diff --git a/event-loop/build.gradle b/event-loop/build.gradle new file mode 100644 index 0000000..0a1c7d0 --- /dev/null +++ b/event-loop/build.gradle @@ -0,0 +1,15 @@ +group 'mc' +version '1.0-SNAPSHOT' + +dependencies { + /* Core */ + compile_excludeCopy project(':core') + + testCompile group: 'org.slf4j', name: 'slf4j-simple', version: '1.6.1' + testCompile group: 'com.carrotsearch', name: 'junit-benchmarks', version: '0.7.0' +} + + +test { + exclude "ru/core/events/*Benchmark.class" +} \ No newline at end of file diff --git a/event-loop/src/main/java/mc/core/events/BaseEventLoop.java b/event-loop/src/main/java/mc/core/events/BaseEventLoop.java index 9aff373..7945d61 100644 --- a/event-loop/src/main/java/mc/core/events/BaseEventLoop.java +++ b/event-loop/src/main/java/mc/core/events/BaseEventLoop.java @@ -13,7 +13,7 @@ public abstract class BaseEventLoop implements EventLoop { return true; if (!Modifier.isPublic(method.getModifiers())) { - log.error("Unable to register {} as an EventHandler. Method must have a 'private' access modifier.", method.toString()); + log.error("Unable to register {} as an EventHandler. Method must have a 'public' access modifier.", method.toString()); return true; } diff --git a/event-loop/src/main/java/mc/core/events/EventHandler.java b/event-loop/src/main/java/mc/core/events/EventHandler.java index 096b52e..0def90c 100644 --- a/event-loop/src/main/java/mc/core/events/EventHandler.java +++ b/event-loop/src/main/java/mc/core/events/EventHandler.java @@ -10,4 +10,8 @@ public @interface EventHandler { EventPriority priority() default EventPriority.NORMAL; boolean ignoreCancelled() default false; + + boolean pluginSynchronize() default true; + + LockableResource[] lock() default {}; } diff --git a/event-loop/src/main/java/mc/core/events/LockableResource.java b/event-loop/src/main/java/mc/core/events/LockableResource.java new file mode 100644 index 0000000..3d8c459 --- /dev/null +++ b/event-loop/src/main/java/mc/core/events/LockableResource.java @@ -0,0 +1,6 @@ +package mc.core.events; + +public enum LockableResource { + PLAYER, + WORLD; +} diff --git a/event-loop/src/main/java/mc/core/events/cachelike/EventHandlerBase.java b/event-loop/src/main/java/mc/core/events/cachelike/EventHandlerBase.java deleted file mode 100644 index b4eecc5..0000000 --- a/event-loop/src/main/java/mc/core/events/cachelike/EventHandlerBase.java +++ /dev/null @@ -1,11 +0,0 @@ -package mc.core.events.cachelike; - -import java.util.List; - -public class EventHandlerBase { - private List contextList; - - protected void push(PreprocessorContext context){ - contextList.add(context); - } -} diff --git a/event-loop/src/main/java/mc/core/events/cachelike/Preprocessor.java b/event-loop/src/main/java/mc/core/events/cachelike/Preprocessor.java deleted file mode 100644 index 28c7c49..0000000 --- a/event-loop/src/main/java/mc/core/events/cachelike/Preprocessor.java +++ /dev/null @@ -1,5 +0,0 @@ -package mc.core.events.cachelike; - -public @interface Preprocessor { - int index(); -} diff --git a/event-loop/src/main/java/mc/core/events/cachelike/PreprocessorContext.java b/event-loop/src/main/java/mc/core/events/cachelike/PreprocessorContext.java deleted file mode 100644 index 99292fc..0000000 --- a/event-loop/src/main/java/mc/core/events/cachelike/PreprocessorContext.java +++ /dev/null @@ -1,17 +0,0 @@ -package mc.core.events.cachelike; - -import com.google.common.base.Function; - -import java.util.ArrayList; -import java.util.List; - -public abstract class PreprocessorContext { - private List> fetchers = new ArrayList<>(); - - protected void push(Function fetcher) { - fetchers.add(fetcher); - } - - protected abstract void init() ; - -} diff --git a/event-loop/src/main/java/mc/core/events/cachelike/SampleHandler.java b/event-loop/src/main/java/mc/core/events/cachelike/SampleHandler.java deleted file mode 100644 index 61241b1..0000000 --- a/event-loop/src/main/java/mc/core/events/cachelike/SampleHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package mc.core.events.cachelike; - -import mc.core.events.LoginEvent; - -public class SampleHandler extends EventHandlerBase { - - public SampleHandler() { - push(new PreprocessorContext() { - @Override - protected void init() { - System.out.println("I am context #0!"); - } - }); - - } - - @Preprocessor(index = 0) // Map constructor #0 to this event handler - public void onLogin(LoginEvent event){ - - } -} diff --git a/event-loop/src/main/java/mc/core/events/v3/FullAsyncEventLoop.java b/event-loop/src/main/java/mc/core/events/v3/FullAsyncEventLoop.java new file mode 100644 index 0000000..4b01936 --- /dev/null +++ b/event-loop/src/main/java/mc/core/events/v3/FullAsyncEventLoop.java @@ -0,0 +1,58 @@ +package mc.core.events.v3; + +import lombok.extern.slf4j.Slf4j; +import mc.core.events.Event; +import mc.core.events.EventHandler; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.*; + +@Slf4j +public class FullAsyncEventLoop { + Map, List> handlers = new HashMap<>(); + + public void addEventHandler(Plugin plugin, Object object) { + Map candidates = getEventHandlerCandidates(object); + + for (Map.Entry pair : candidates.entrySet()) { + @SuppressWarnings("unchecked") Class eventType = (Class) pair.getKey().getParameterTypes()[0]; + List handlers = this.handlers.computeIfAbsent(eventType, e -> new ArrayList<>()); + handlers.add(new RegisteredEventHandler(plugin, object, pair.getKey(), pair.getValue().lock(), pair.getValue().pluginSynchronize(), pair.getValue().priority().getValue(), pair.getValue().ignoreCancelled())); + handlers.sort(Comparator.comparingInt(RegisteredEventHandler::getPriority)); + } + } + + + + private Map getEventHandlerCandidates(Object object) { + Map candidates; + candidates = new HashMap<>(); + for (Method method : object.getClass().getDeclaredMethods()) { + EventHandler annotation = method.getAnnotation(EventHandler.class); + if (annotation == null) + continue; + + if (!Modifier.isPublic(method.getModifiers())) { + log.error("Unable to register {} as an EventHandler. Method must have a 'public' access modifier.", method.toString()); + continue; + + } + + if (method.getParameterCount() != 1) { + log.error("Unable to register {} as an EventHandler. Method must have exactly one argument.", method.toString()); + continue; + } + + Class firstParamType = method.getParameterTypes()[0]; + if (!Event.class.isAssignableFrom(firstParamType)) { + log.error("Unable to register {} as an EventHandler. First parameter type must implement 'Event' interface.", method.toString()); + continue; + } + + candidates.put(method, annotation); + } + return candidates; + } + +} diff --git a/event-loop/src/main/java/mc/core/events/v3/Plugin.java b/event-loop/src/main/java/mc/core/events/v3/Plugin.java new file mode 100644 index 0000000..670bd82 --- /dev/null +++ b/event-loop/src/main/java/mc/core/events/v3/Plugin.java @@ -0,0 +1,4 @@ +package mc.core.events.v3; + +public interface Plugin { +} diff --git a/event-loop/src/main/java/mc/core/events/v3/QueueManager.java b/event-loop/src/main/java/mc/core/events/v3/QueueManager.java new file mode 100644 index 0000000..b395844 --- /dev/null +++ b/event-loop/src/main/java/mc/core/events/v3/QueueManager.java @@ -0,0 +1,4 @@ +package mc.core.events.v3; + +public class QueueManager { +} diff --git a/event-loop/src/main/java/mc/core/events/v3/RegisteredEventHandler.java b/event-loop/src/main/java/mc/core/events/v3/RegisteredEventHandler.java new file mode 100644 index 0000000..ae708e2 --- /dev/null +++ b/event-loop/src/main/java/mc/core/events/v3/RegisteredEventHandler.java @@ -0,0 +1,20 @@ +package mc.core.events.v3; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import mc.core.events.LockableResource; + +import java.lang.reflect.Method; + +@RequiredArgsConstructor +@Getter +public class RegisteredEventHandler { + private final Plugin plugin; + private final Object object; + private final Method method; + private final LockableResource[] lock; + private final boolean pluginSynchronize; + private final int priority; + private final boolean ignoreCancelled; + +}