Add Event/Listener framework to common/ecs
This commit is contained in:
parent
83113f3afd
commit
22fc504619
@ -1,6 +1,8 @@
|
||||
package com.me.common.ecs;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.me.common.ecs.event.Event;
|
||||
import com.me.common.ecs.event.Listener;
|
||||
|
||||
public class Engine {
|
||||
|
||||
@ -8,9 +10,12 @@ public class Engine {
|
||||
private ComponentBag[] components;
|
||||
private Array<EntitySystem> systems;
|
||||
|
||||
private ListenerRegistry listenerRegistry;
|
||||
|
||||
public Engine() {
|
||||
this.entities = new Array<>();
|
||||
this.systems = new Array<>();
|
||||
this.listenerRegistry = new ListenerRegistry();
|
||||
}
|
||||
|
||||
public void registerComponentClass(Class<? extends Component> clazz) {
|
||||
@ -47,6 +52,14 @@ public class Engine {
|
||||
entities.removeValue(entity, true);
|
||||
}
|
||||
|
||||
public void registerListener(Listener listener) {
|
||||
listenerRegistry.registerListener(listener);
|
||||
}
|
||||
|
||||
public void callEvent(Event event) {
|
||||
listenerRegistry.callEvent(event);
|
||||
}
|
||||
|
||||
private void removeAllEntityComponents(int entityId) {
|
||||
for (int i = 0; i < components.length; i++) {
|
||||
components[i].insert(entityId, null);
|
||||
|
@ -33,6 +33,10 @@ public final class Entity {
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
public Engine getEngine() {
|
||||
return this.engine;
|
||||
}
|
||||
|
||||
public <T extends Component> T getComponent(Class<T> clazz) {
|
||||
return engine.getEntityComponent(this, clazz);
|
||||
}
|
||||
|
66
core/src/com/me/common/ecs/ListenerRegistry.java
Normal file
66
core/src/com/me/common/ecs/ListenerRegistry.java
Normal file
@ -0,0 +1,66 @@
|
||||
package com.me.common.ecs;
|
||||
|
||||
import com.me.common.ecs.event.Event;
|
||||
import com.me.common.ecs.event.RegisteredListener;
|
||||
import com.me.common.ecs.event.EventHandler;
|
||||
import com.me.common.ecs.event.Listener;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ListenerRegistry {
|
||||
|
||||
private final Map<Class<? extends Event>, List<RegisteredListener>> registeredListeners;
|
||||
|
||||
protected ListenerRegistry() {
|
||||
this.registeredListeners = new HashMap<>();
|
||||
}
|
||||
|
||||
protected void registerListener(Listener listener) {
|
||||
Method[] methods = listener.getClass().getMethods();
|
||||
|
||||
for (Method method : methods) {
|
||||
EventHandler eh = method.getAnnotation(EventHandler.class);
|
||||
if (eh == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?>[] parameters = method.getParameterTypes();
|
||||
if (parameters.length != 1 || !Event.class.isAssignableFrom(parameters[0])) {
|
||||
System.err.println("Attempting to register an EventHandler with an invalid method signature: " + method.toGenericString() + " in " + listener.getClass());
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<? extends Event> eventClass = parameters[0].asSubclass(Event.class);
|
||||
method.setAccessible(true);
|
||||
|
||||
List<RegisteredListener> executors = registeredListeners.get(eventClass);
|
||||
if (executors == null) {
|
||||
executors = new ArrayList<>();
|
||||
registeredListeners.put(eventClass, executors);
|
||||
}
|
||||
|
||||
executors.add(new RegisteredListener(listener, method, eventClass, eh));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void callEvent(Event event) {
|
||||
List<RegisteredListener> listeners = registeredListeners.get(event.getClass());
|
||||
if (listeners == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (RegisteredListener listener : listeners) {
|
||||
if (listener.isIgnoringCancelled() && event.isCancelled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener.execute(event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
19
core/src/com/me/common/ecs/event/Event.java
Normal file
19
core/src/com/me/common/ecs/event/Event.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.me.common.ecs.event;
|
||||
|
||||
public abstract class Event {
|
||||
|
||||
boolean cancelled;
|
||||
|
||||
public Event() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
}
|
14
core/src/com/me/common/ecs/event/EventHandler.java
Normal file
14
core/src/com/me/common/ecs/event/EventHandler.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.me.common.ecs.event;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EventHandler {
|
||||
|
||||
boolean ignoreCancelled() default false;
|
||||
|
||||
}
|
5
core/src/com/me/common/ecs/event/Listener.java
Normal file
5
core/src/com/me/common/ecs/event/Listener.java
Normal file
@ -0,0 +1,5 @@
|
||||
package com.me.common.ecs.event;
|
||||
|
||||
public interface Listener {
|
||||
|
||||
}
|
36
core/src/com/me/common/ecs/event/RegisteredListener.java
Normal file
36
core/src/com/me/common/ecs/event/RegisteredListener.java
Normal file
@ -0,0 +1,36 @@
|
||||
package com.me.common.ecs.event;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class RegisteredListener {
|
||||
|
||||
private Listener listener;
|
||||
private Method method;
|
||||
private Class<? extends Event> eventType;
|
||||
|
||||
public EventHandler eh;
|
||||
|
||||
public RegisteredListener(Listener listener, Method method, Class<? extends Event> eventType, EventHandler eh) {
|
||||
this.listener = listener;
|
||||
this.method = method;
|
||||
this.eventType = eventType;
|
||||
this.eh = eh;
|
||||
}
|
||||
|
||||
public boolean isIgnoringCancelled() {
|
||||
return eh.ignoreCancelled();
|
||||
}
|
||||
|
||||
public void execute(Event event) {
|
||||
if (!eventType.isAssignableFrom(event.getClass())) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
method.invoke(listener, event);
|
||||
} catch (Throwable e) {
|
||||
System.err.println("Could not call event " + event.toString() + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user