diff --git a/core/src/main/java/mc/core/eventbus/EventBus.java b/core/src/main/java/mc/core/eventbus/EventBus.java new file mode 100644 index 0000000..c28a328 --- /dev/null +++ b/core/src/main/java/mc/core/eventbus/EventBus.java @@ -0,0 +1,39 @@ +package mc.core.eventbus; + +import javafx.util.Pair; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.lang.reflect.Method; +import java.util.*; +import java.util.stream.Stream; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class EventBus { + @Getter + private static final EventBus insnance = new EventBus(); + + private Queue eventQueue; + private Map, List>> subscribes = new HashMap<>(); + + @SuppressWarnings("unchecked") + public void registerSubscribes(Object subscriberObject) { + Stream.of(subscriberObject.getClass().getDeclaredMethods()) + .filter(method -> method.isAnnotationPresent(Subscriber.class)) + .filter(method -> method.getReturnType().equals(Void.TYPE)) + .filter(method -> method.getParameterCount() == 1) + .filter(method -> Event.class.isAssignableFrom(method.getParameterTypes()[0])) + .forEach(method -> { + Class type = (Class) method.getParameterTypes()[0]; + List> pairs; + if (subscribes.containsKey(type)) { + pairs = subscribes.get(type); + } else { + pairs = new ArrayList<>(); + subscribes.put(type, pairs); + } + pairs.add(new Pair<>(subscriberObject, method)); + }); + } +} diff --git a/core/src/main/java/mc/core/eventbus/Subscriber.java b/core/src/main/java/mc/core/eventbus/Subscriber.java new file mode 100644 index 0000000..9a8aaee --- /dev/null +++ b/core/src/main/java/mc/core/eventbus/Subscriber.java @@ -0,0 +1,11 @@ +package mc.core.eventbus; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value= ElementType.METHOD) +@Retention(value= RetentionPolicy.RUNTIME) +public @interface Subscriber { +} diff --git a/core/src/test/java/mc/core/TestEventBus.java b/core/src/test/java/mc/core/TestEventBus.java new file mode 100644 index 0000000..88a882a --- /dev/null +++ b/core/src/test/java/mc/core/TestEventBus.java @@ -0,0 +1,62 @@ +package mc.core; + +import javafx.util.Pair; +import mc.core.eventbus.Event; +import mc.core.eventbus.EventBus; +import mc.core.eventbus.Subscriber; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.internal.util.reflection.Whitebox; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +class TestEventBus { + + @SuppressWarnings("unchecked") + @Test + void testRegisterSubscribes() { + DumbEventHandler handler = new DumbEventHandler(); + EventBus.getInsnance().registerSubscribes(handler); + + Map>> subscribes = + (Map>>) + Whitebox.getInternalState(EventBus.getInsnance(), "subscribes"); + assertEquals(1, subscribes.size()); + + List> pairs = subscribes.values().iterator().next(); + assertEquals(1, pairs.size()); + + Pair pair = pairs.get(0); + assertSame(handler, pair.getKey()); + assertEquals("corectSubscribe", pair.getValue().getName()); + } + + private class DumbEvent implements Event { + } + + private class DumbEventHandler { + @Subscriber + public void corectSubscribe(DumbEvent event) { + } + + @Subscriber + public Object incorectSubscribeReturnType(DumbEvent event) { + return null; + } + + @Subscriber + public void incorrectSubscriberTypeParameter(Object object) { + } + + @Subscriber + public void incorrectSubscriberManyParameters(DumbEvent event, Object object) { + } + + public void someMethod() { + } + } +}