diff --git a/src/dev/kske/chess/event/EventBus.java b/src/dev/kske/chess/event/EventBus.java new file mode 100644 index 0000000..f9351aa --- /dev/null +++ b/src/dev/kske/chess/event/EventBus.java @@ -0,0 +1,58 @@ +package dev.kske.chess.event; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * Project: Chess
+ * File: EventBus.java
+ * Created: 02.08.2019
+ * Author: Kai S. K. Engelbart + */ +public final class EventBus { + + private Map, List> invocations; + + public EventBus() { + invocations = new ConcurrentHashMap<>(); + } + + public void post(Object object) { + Class type = object.getClass(); + if (invocations.containsKey(type)) invocations.get(type).forEach(invocation -> invocation.invoke(object)); + } + + public void register(Object object) { + Class currentClass = object.getClass(); + while (currentClass != null) { + for (Method method : findSubscriptionMethods(currentClass)) { + Class type = method.getParameterTypes()[0]; + if (invocations.containsKey(type)) invocations.get(type).add(new Invocation(method, object)); + else { + List temp = new Vector<>(); + temp.add(new Invocation(method, object)); + invocations.put(type, temp); + } + } + currentClass = currentClass.getSuperclass(); + } + } + + private List findSubscriptionMethods(Class type) { + List subscriberMethods = Arrays.stream(type.getDeclaredMethods()) + .filter(method -> method.isAnnotationPresent(Subscribe.class)) + .collect(Collectors.toList()); + checkSubscriberMethods(subscriberMethods); + return subscriberMethods; + } + + private void checkSubscriberMethods(List subscriberMethods) { + if (subscriberMethods.stream().anyMatch(method -> method.getParameterCount() != 1)) + throw new IllegalArgumentException("Method annotated with @Subscribe must have exactly one parameter"); + } +} diff --git a/src/dev/kske/chess/event/Invocation.java b/src/dev/kske/chess/event/Invocation.java new file mode 100644 index 0000000..d0ce29f --- /dev/null +++ b/src/dev/kske/chess/event/Invocation.java @@ -0,0 +1,29 @@ +package dev.kske.chess.event; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Project: Chess
+ * File: Invocation.java
+ * Created: 02.08.2019
+ * Author: Kai S. K. Engelbart + */ +public final class Invocation { + + private final Method method; + private final Object object; + + public Invocation(Method method, Object object) { + this.method = method; + this.object = object; + } + + public void invoke(Object arg) { + try { + method.invoke(object, arg); + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { + ex.printStackTrace(); + } + } +} diff --git a/src/dev/kske/chess/event/Subscribe.java b/src/dev/kske/chess/event/Subscribe.java new file mode 100644 index 0000000..6cae9a4 --- /dev/null +++ b/src/dev/kske/chess/event/Subscribe.java @@ -0,0 +1,19 @@ +package dev.kske.chess.event; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(METHOD) +/** + * Project: Chess
+ * File: Subscribe.java
+ * Created: 02.08.2019
+ * Author: Kai S. K. Engelbart + */ +public @interface Subscribe { + +} diff --git a/src/dev/kske/chess/ui/MainWindow.java b/src/dev/kske/chess/ui/MainWindow.java index c6aaae6..fef681f 100644 --- a/src/dev/kske/chess/ui/MainWindow.java +++ b/src/dev/kske/chess/ui/MainWindow.java @@ -32,15 +32,12 @@ public class MainWindow { * Launch the application. */ public static void main(String[] args) { - EventQueue.invokeLater(new Runnable() { - - public void run() { - try { - MainWindow window = new MainWindow(); - window.mframe.setVisible(true); - } catch (Exception e) { - e.printStackTrace(); - } + EventQueue.invokeLater(() -> { + try { + MainWindow window = new MainWindow(); + window.mframe.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); } }); }