Added event package with EventBus class

This commit is contained in:
Kai S. K. Engelbart 2019-08-02 18:46:00 +02:00
parent 5bfc57a5af
commit cd44db37ae
4 changed files with 112 additions and 9 deletions

View File

@ -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: <strong>Chess</strong><br>
* File: <strong>EventBus.java</strong><br>
* Created: <strong>02.08.2019</strong><br>
* Author: <strong>Kai S. K. Engelbart</strong>
*/
public final class EventBus {
private Map<Class<?>, List<Invocation>> 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<Invocation> temp = new Vector<>();
temp.add(new Invocation(method, object));
invocations.put(type, temp);
}
}
currentClass = currentClass.getSuperclass();
}
}
private List<Method> findSubscriptionMethods(Class<?> type) {
List<Method> subscriberMethods = Arrays.stream(type.getDeclaredMethods())
.filter(method -> method.isAnnotationPresent(Subscribe.class))
.collect(Collectors.toList());
checkSubscriberMethods(subscriberMethods);
return subscriberMethods;
}
private void checkSubscriberMethods(List<Method> subscriberMethods) {
if (subscriberMethods.stream().anyMatch(method -> method.getParameterCount() != 1))
throw new IllegalArgumentException("Method annotated with @Subscribe must have exactly one parameter");
}
}

View File

@ -0,0 +1,29 @@
package dev.kske.chess.event;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Project: <strong>Chess</strong><br>
* File: <strong>Invocation.java</strong><br>
* Created: <strong>02.08.2019</strong><br>
* Author: <strong>Kai S. K. Engelbart</strong>
*/
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();
}
}
}

View File

@ -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: <strong>Chess</strong><br>
* File: <strong>Subscribe.java</strong><br>
* Created: <strong>02.08.2019</strong><br>
* Author: <strong>Kai S. K. Engelbart</strong>
*/
public @interface Subscribe {
}

View File

@ -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();
}
});
}