Archived
0

обработка очереди событий

This commit is contained in:
2019-01-12 21:02:30 +03:00
parent 71c1699206
commit d042169952
2 changed files with 79 additions and 5 deletions

View File

@@ -4,17 +4,22 @@ import javafx.util.Pair;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.helpers.MessageFormatter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.stream.Stream; import java.util.stream.Stream;
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class EventBus { public class EventBus {
@Getter @Getter
private static final EventBus insnance = new EventBus(); private static final EventBus insnance = new EventBus();
private Queue<Event> eventQueue; private Queue<Event> eventQueue = new ConcurrentLinkedQueue<>();
private Map<Class<? extends Event>, List<Pair<Object, Method>>> subscribes = new HashMap<>(); private Map<Class<? extends Event>, List<Pair<Object, Method>>> subscribes = new HashMap<>();
private Stream<Method> getMethods(Object subscriberObject) { private Stream<Method> getMethods(Object subscriberObject) {
@@ -56,4 +61,29 @@ public class EventBus {
} }
}); });
} }
public void post(Event event) {
eventQueue.add(event);
}
public void process() {
Event event;
while ((event = eventQueue.poll()) != null) {
final Class<? extends Event> type = event.getClass();
if (subscribes.containsKey(type)) {
final List<Pair<Object, Method>> pairs = subscribes.get(type);
for (Pair<Object, Method> pair : pairs) {
try {
pair.getValue().invoke(pair.getKey(), event);
} catch (IllegalAccessException | InvocationTargetException e) {
log.error(MessageFormatter.format("Invoke method '{}#{}'",
pair.getKey().getClass().getSimpleName(),
pair.getValue().getName()).getMessage(),
e
);
}
}
}
}
}
} }

View File

@@ -1,6 +1,8 @@
package mc.core; package mc.core;
import javafx.util.Pair; import javafx.util.Pair;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import mc.core.eventbus.Event; import mc.core.eventbus.Event;
import mc.core.eventbus.EventBus; import mc.core.eventbus.EventBus;
import mc.core.eventbus.Subscriber; import mc.core.eventbus.Subscriber;
@@ -9,21 +11,29 @@ import org.junit.jupiter.api.Test;
import org.mockito.internal.util.reflection.Whitebox; import org.mockito.internal.util.reflection.Whitebox;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
class TestEventBus { class TestEventBus {
private List<String> resultList = new ArrayList<>();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Map<Class<? extends Event>, List<Pair<Object, Method>>> getEventBusFieldSubscribes() { private Map<Class<? extends Event>, List<Pair<Object, Method>>> getEventBusFieldSubscribes() {
return (Map<Class<? extends Event>, List<Pair<Object, Method>>>) Whitebox.getInternalState(EventBus.getInsnance(), "subscribes"); return (Map<Class<? extends Event>, List<Pair<Object, Method>>>)
Whitebox.getInternalState(EventBus.getInsnance(), "subscribes");
} }
@BeforeEach @BeforeEach
@SuppressWarnings("unchecked")
void before() { void before() {
getEventBusFieldSubscribes().clear(); getEventBusFieldSubscribes().clear();
((Queue<Event>) Whitebox.getInternalState(EventBus.getInsnance(), "eventQueue")).clear();
} }
@@ -54,12 +64,46 @@ class TestEventBus {
assertEquals(0, subscribes.size()); assertEquals(0, subscribes.size());
} }
private class DumbEvent implements Event { @Test
@SuppressWarnings("unchecked")
void testPost() {
EventBus.getInsnance().post(new DumbEvent());
Queue<Event> eventQueue = (Queue<Event>) Whitebox.getInternalState(EventBus.getInsnance(), "eventQueue");
assertEquals(1, eventQueue.size());
} }
private class DumbEventHandler { @Test
void testProcess() {
Stream.of(new DumbEventHandler("D1 "), new DumbEventHandler("D2 "))
.forEach(handler -> EventBus.getInsnance().registerSubscribes(handler));
Stream.of(new DumbEvent("message 1"), new DumbEvent("message 2"))
.forEach(event -> EventBus.getInsnance().post(event));
EventBus.getInsnance().process();
assertEquals(4, resultList.size());
assertEquals("D1 message 1", resultList.get(0));
assertEquals("D2 message 1", resultList.get(1));
assertEquals("D1 message 2", resultList.get(2));
assertEquals("D2 message 2", resultList.get(3));
}
@AllArgsConstructor
@NoArgsConstructor
private class DumbEvent implements Event {
String message;
}
@AllArgsConstructor
@NoArgsConstructor
public class DumbEventHandler {
private String prefix = "";
@Subscriber @Subscriber
public void corectSubscribe(DumbEvent event) { public void corectSubscribe(DumbEvent event) {
resultList.add(prefix + event.message);
} }
@Subscriber @Subscriber