有没有办法让接口代码在运行时运行?
Is there a way to make interface code run at runtime?
我正致力于在我在 Java 中创建的简单游戏引擎中实现事件处理。我现在正在努力弄清楚我应该如何注册一个对象的事件处理程序。我在想我也许可以制作一个在创建对象时运行一行代码(public void registerListener(Object listener)
)的界面。我知道接口无法定义构造函数,因此我正在寻求有关如何处理此问题的指导。现在,我必须在所有具有事件处理程序的对象的构造函数中调用前面提到的代码行,我认为使用接口或类似的东西来减少重复将是一个理想的解决方案。
下面是事件系统代码的其余部分,以备您查看。谢谢!
事件管理器class:
负责维护将响应事件的方法列表。注册EventHandler时,传入一个class作为参数,它会查找所有带有@EventHandler()注解的方法,并将注解值作为事件类型。
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
public class EventManager
{
private HashMap<Class<? extends Event>, ArrayList<Method>> eventCallbackMap;
public EventManager()
{
this.eventCallbackMap = new HashMap<>();
}
public void dispatchEvent(Event event)
{
ArrayList<Method> callbacks = eventCallbackMap.get(event.getClass());
if(callbacks == null)
{
return;
}
for(Method callback : callbacks)
{
//TODO: Invoke Method
}
}
public void registerListener(Object listener)
{
for(Method method : listener.getClass().getMethods())
{
if(method.isAnnotationPresent(EventHandler.class))
{
Class<? extends Event> value = method.getAnnotation(EventHandler.class).value();
if(eventCallbackMap.containsKey(value))
{
eventCallbackMap.get(value).add(method);
}
else
{
ArrayList<Method> callbacks = new ArrayList<>();
callbacks.add(method);
eventCallbackMap.put(value, callbacks);
}
}
}
}
}
事件class:
所有自定义事件都将从中扩展的准系统抽象 class。如果您能告诉我如何改进此功能,我将不胜感激 class,我将不胜感激。
package events;
public abstract class Event
{
public Event()
{
}
}
事件处理程序class:
将方法定义为事件响应方法的注解。
package events;
import java.lang.annotation.*;
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventHandler
{
Class<? extends Event> value();
}
是的。您应该使用接口,而不是注释。一个非常快速的示例可能看起来像这样。这只是一个代码草图,不确定它是否会编译。有改进的余地,但这是基本思想:
interface EventHandler
{
Set<Event> eventTypes();
void onEvent(Event event);
}
interface Event
{
// used as a marker interface, but probably add some methods
}
enum MouseEvent implements Event
{
ON_CLICK
//... and whatever else
}
class OnClickEventHandler implements EventHandler
{
public Set<Event> eventTypes()
{
Set<Event> events = new HashSet<>();
events.add(MouseEvent.ON_CLICK);
return events;
}
public void onEvent(Event event)
{
if (event == MouseEvent.ON_CLICK)
{
System.out.println("Mouse clicked");
}
}
}
class EventManager
{
private final Map<Event, List<EventHandler>> handlers = new HashMap<>();
public void registerListener(EventHandler handler)
{
for (Event eventType : handler.eventTypes())
{
handlers.putIfAbsent(eventType, new ArrayList<>());
handlers.get(eventType).add(handler);
}
}
public void dispatchEvent(Event event)
{
handlers.getOrDefault(event, Collections.emptyList())
.forEach(handler -> handler.onEvent(event));
}
}
我正致力于在我在 Java 中创建的简单游戏引擎中实现事件处理。我现在正在努力弄清楚我应该如何注册一个对象的事件处理程序。我在想我也许可以制作一个在创建对象时运行一行代码(public void registerListener(Object listener)
)的界面。我知道接口无法定义构造函数,因此我正在寻求有关如何处理此问题的指导。现在,我必须在所有具有事件处理程序的对象的构造函数中调用前面提到的代码行,我认为使用接口或类似的东西来减少重复将是一个理想的解决方案。
下面是事件系统代码的其余部分,以备您查看。谢谢!
事件管理器class:
负责维护将响应事件的方法列表。注册EventHandler时,传入一个class作为参数,它会查找所有带有@EventHandler()注解的方法,并将注解值作为事件类型。
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
public class EventManager
{
private HashMap<Class<? extends Event>, ArrayList<Method>> eventCallbackMap;
public EventManager()
{
this.eventCallbackMap = new HashMap<>();
}
public void dispatchEvent(Event event)
{
ArrayList<Method> callbacks = eventCallbackMap.get(event.getClass());
if(callbacks == null)
{
return;
}
for(Method callback : callbacks)
{
//TODO: Invoke Method
}
}
public void registerListener(Object listener)
{
for(Method method : listener.getClass().getMethods())
{
if(method.isAnnotationPresent(EventHandler.class))
{
Class<? extends Event> value = method.getAnnotation(EventHandler.class).value();
if(eventCallbackMap.containsKey(value))
{
eventCallbackMap.get(value).add(method);
}
else
{
ArrayList<Method> callbacks = new ArrayList<>();
callbacks.add(method);
eventCallbackMap.put(value, callbacks);
}
}
}
}
}
事件class:
所有自定义事件都将从中扩展的准系统抽象 class。如果您能告诉我如何改进此功能,我将不胜感激 class,我将不胜感激。
package events;
public abstract class Event
{
public Event()
{
}
}
事件处理程序class:
将方法定义为事件响应方法的注解。
package events;
import java.lang.annotation.*;
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventHandler
{
Class<? extends Event> value();
}
是的。您应该使用接口,而不是注释。一个非常快速的示例可能看起来像这样。这只是一个代码草图,不确定它是否会编译。有改进的余地,但这是基本思想:
interface EventHandler
{
Set<Event> eventTypes();
void onEvent(Event event);
}
interface Event
{
// used as a marker interface, but probably add some methods
}
enum MouseEvent implements Event
{
ON_CLICK
//... and whatever else
}
class OnClickEventHandler implements EventHandler
{
public Set<Event> eventTypes()
{
Set<Event> events = new HashSet<>();
events.add(MouseEvent.ON_CLICK);
return events;
}
public void onEvent(Event event)
{
if (event == MouseEvent.ON_CLICK)
{
System.out.println("Mouse clicked");
}
}
}
class EventManager
{
private final Map<Event, List<EventHandler>> handlers = new HashMap<>();
public void registerListener(EventHandler handler)
{
for (Event eventType : handler.eventTypes())
{
handlers.putIfAbsent(eventType, new ArrayList<>());
handlers.get(eventType).add(handler);
}
}
public void dispatchEvent(Event event)
{
handlers.getOrDefault(event, Collections.emptyList())
.forEach(handler -> handler.onEvent(event));
}
}