diff --git a/src/dev/kske/chess/event/Event.java b/src/dev/kske/chess/event/Event.java
new file mode 100644
index 0000000..88df215
--- /dev/null
+++ b/src/dev/kske/chess/event/Event.java
@@ -0,0 +1,15 @@
+package dev.kske.chess.event;
+
+/**
+ * Project: Chess
+ * File: Event.java
+ * Created: 7 Aug 2019
+ * Author: Kai S. K. Engelbart
+ */
+public interface Event {
+
+ /**
+ * @return The data associated with the event
+ */
+ T getData();
+}
diff --git a/src/dev/kske/chess/event/EventBus.java b/src/dev/kske/chess/event/EventBus.java
index 15a7d15..d652df9 100644
--- a/src/dev/kske/chess/event/EventBus.java
+++ b/src/dev/kske/chess/event/EventBus.java
@@ -1,22 +1,17 @@
package dev.kske.chess.event;
-import java.lang.reflect.Method;
-import java.util.Arrays;
+import java.util.ArrayList;
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
+ * Created: 7 Aug 2019
* Author: Kai S. K. Engelbart
*/
-public final class EventBus {
+public class EventBus {
- private Map, List> invocations;
+ private List subscribers;
private static EventBus instance;
@@ -26,40 +21,16 @@ public final class EventBus {
}
private EventBus() {
- invocations = new ConcurrentHashMap<>();
+ subscribers = new ArrayList<>();
}
- public void post(Object object) {
- Class> type = object.getClass();
- if (invocations.containsKey(type)) invocations.get(type).forEach(invocation -> invocation.invoke(object));
+ public void register(Subscribable subscribable) {
+ subscribers.add(subscribable);
}
- 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();
- }
+ public void dispatch(Event> event) {
+ subscribers.stream().filter(e -> e.supports().contains(event.getClass())).forEach(e -> e.handle(event));
}
- 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");
- }
+ public List getSubscribers() { return subscribers; }
}
diff --git a/src/dev/kske/chess/event/Invocation.java b/src/dev/kske/chess/event/Invocation.java
deleted file mode 100644
index d0ce29f..0000000
--- a/src/dev/kske/chess/event/Invocation.java
+++ /dev/null
@@ -1,29 +0,0 @@
-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/MoveEvent.java b/src/dev/kske/chess/event/MoveEvent.java
new file mode 100644
index 0000000..fad5ff3
--- /dev/null
+++ b/src/dev/kske/chess/event/MoveEvent.java
@@ -0,0 +1,21 @@
+package dev.kske.chess.event;
+
+import dev.kske.chess.board.Move;
+
+/**
+ * Project: Chess
+ * File: MoveEvent.java
+ * Created: 7 Aug 2019
+ * Author: Kai S. K. Engelbart
+ */
+public class MoveEvent implements Event {
+
+ private final Move move;
+
+ public MoveEvent(Move move) {
+ this.move = move;
+ }
+
+ @Override
+ public Move getData() { return move; }
+}
diff --git a/src/dev/kske/chess/event/Subscribable.java b/src/dev/kske/chess/event/Subscribable.java
new file mode 100644
index 0000000..ff08cc4
--- /dev/null
+++ b/src/dev/kske/chess/event/Subscribable.java
@@ -0,0 +1,24 @@
+package dev.kske.chess.event;
+
+import java.util.Set;
+
+/**
+ * Project: Chess
+ * File: Subscribable.java
+ * Created: 7 Aug 2019
+ * Author: Kai S. K. Engelbart
+ */
+public interface Subscribable {
+
+ /**
+ * Consumes an event dispatched by an event bus.
+ *
+ * @param event The event dispatched by the event bus, only of supported type
+ */
+ void handle(Event> event);
+
+ /**
+ * @return A set of classes this class is supposed to handle in events
+ */
+ Set> supports();
+}
diff --git a/src/dev/kske/chess/event/Subscribe.java b/src/dev/kske/chess/event/Subscribe.java
deleted file mode 100644
index 6cae9a4..0000000
--- a/src/dev/kske/chess/event/Subscribe.java
+++ /dev/null
@@ -1,19 +0,0 @@
-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/game/Game.java b/src/dev/kske/chess/game/Game.java
index 31443ae..47cfca7 100644
--- a/src/dev/kske/chess/game/Game.java
+++ b/src/dev/kske/chess/game/Game.java
@@ -10,6 +10,7 @@ import dev.kske.chess.board.GameState;
import dev.kske.chess.board.Move;
import dev.kske.chess.board.Piece.Color;
import dev.kske.chess.event.EventBus;
+import dev.kske.chess.event.MoveEvent;
import dev.kske.chess.game.ai.AIPlayer;
import dev.kske.chess.ui.BoardComponent;
import dev.kske.chess.ui.BoardPane;
@@ -66,7 +67,7 @@ public class Game {
System.out.printf("%s: %s%n", player.color, move);
System.out.println("FEN: " + board.toFEN());
- EventBus.getInstance().post(move);
+ EventBus.getInstance().dispatch(new MoveEvent(move));
GameState eventType = board.getGameEventType(board.getDest(move).getColor().opposite());
switch (eventType) {
case CHECKMATE:
diff --git a/src/dev/kske/chess/ui/LogFrame.java b/src/dev/kske/chess/ui/LogFrame.java
index 6d32bb0..14e2b88 100644
--- a/src/dev/kske/chess/ui/LogFrame.java
+++ b/src/dev/kske/chess/ui/LogFrame.java
@@ -1,7 +1,10 @@
package dev.kske.chess.ui;
import java.awt.BorderLayout;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JPanel;
@@ -12,9 +15,10 @@ import javax.swing.table.DefaultTableModel;
import dev.kske.chess.board.Log;
import dev.kske.chess.board.Log.LoggedMove;
-import dev.kske.chess.board.Move;
+import dev.kske.chess.event.Event;
import dev.kske.chess.event.EventBus;
-import dev.kske.chess.event.Subscribe;
+import dev.kske.chess.event.MoveEvent;
+import dev.kske.chess.event.Subscribable;
/**
* Project: Chess
@@ -22,7 +26,7 @@ import dev.kske.chess.event.Subscribe;
* Created: 17.07.2019
* Author: Kai S. K. Engelbart
*/
-public class LogFrame extends JFrame {
+public class LogFrame extends JFrame implements Subscribable {
private static final long serialVersionUID = 1932671698254197119L;
@@ -50,11 +54,16 @@ public class LogFrame extends JFrame {
mcontentPane.add(new JScrollPane(mtable), BorderLayout.CENTER);
EventBus.getInstance().register(this);
- EventBus.getInstance().post(new Move(0, 0, 0, 0));
+ handle(null);
}
- @Subscribe
- public void updateData(Move move) {
+ @Override
+ public Set> supports() {
+ return new HashSet<>(Arrays.asList(MoveEvent.class));
+ }
+
+ @Override
+ public void handle(Event> event) {
final List moves = log.getLoggedMoves();
String[][] data = new String[moves.size() / 2 + moves.size() % 2][2];
for (int i = 0; i < data.length; i++) {