Abstraktion für Listener API erstellt

EventGenerator soll als einheitlicher Unterbau zur Umstzung von Listener Patterns dienen. Damit sollen Listener wie AudioListener oder AnimationListener umgesetzt werden.
This commit is contained in:
ngb
2022-07-07 21:45:08 +02:00
parent 3030445dcf
commit e4818d4f3e
3 changed files with 122 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
package schule.ngb.zm.events;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.BiConsumer;
public class EventGenerator<E, L extends Listener<E>> {
private CopyOnWriteArraySet<L> listeners;
private ConcurrentMap<String, BiConsumer<E, L>> eventRegistry;
public EventGenerator() {
listeners = new CopyOnWriteArraySet<>();
eventRegistry = new ConcurrentHashMap<>();
}
public void registerEventType( String eventKey, BiConsumer<E, L> dispatcher ) {
if( !eventRegistered(eventKey) ) {
eventRegistry.put(eventKey, dispatcher);
}
}
public void addListener( L listener ) {
listeners.add(listener);
}
public void removeListener( L listener ) {
listeners.remove(listener);
}
public boolean hasListeners() {
return !listeners.isEmpty();
}
public boolean eventRegistered( String eventKey ) {
return eventRegistry.containsKey(eventKey);
}
public void dispatchEvent( String eventKey, final E event ) {
if( eventRegistered(eventKey) ) {
final BiConsumer<E, L> dispatcher = eventRegistry.get(eventKey);
listeners.stream().forEach(( listener ) -> {
dispatcher.accept(event, listener);
});
}
}
}

View File

@@ -0,0 +1,7 @@
package schule.ngb.zm.events;
public interface Listener<E> {
}

View File

@@ -0,0 +1,65 @@
package schule.ngb.zm.events;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class EventGeneratorTest {
class TestEvent {
private String data;
private String type;
public TestEvent( String data, boolean isStart ) {
this.data = data;
this.type = isStart ? "start" : "stop";
}
public String getData() {
return data;
}
public String getType() {
return type;
}
}
interface TestListener extends Listener<TestEvent> {
void startEvent( TestEvent t );
void stopEvent( TestEvent t );
}
@Test
void eventRegistry() {
EventGenerator<TestEvent, TestListener> gen = new EventGenerator<>();
gen.registerEventType("start", ( event, listener ) -> listener.startEvent(event));
gen.registerEventType("stop", ( event, listener ) -> listener.stopEvent(event));
gen.addListener(new TestListener() {
@Override
public void startEvent( TestEvent t ) {
assertEquals("start", t.getType());
assertTrue(t.getData().startsWith("Start Event"));
}
@Override
public void stopEvent( TestEvent t ) {
assertEquals("stop", t.getType());
assertTrue(t.getData().startsWith("Stop Event"));
}
});
gen.dispatchEvent("start", new TestEvent("Start Event 1", true));
gen.dispatchEvent("stop", new TestEvent("Stop Event 1", false));
gen.dispatchEvent("stop", new TestEvent("Stop Event 2", false));
gen.dispatchEvent("start", new TestEvent("Start Event 2", true));
}
}