我正在开发一个游戏引擎,关于这一点,我的最后一个问题是,我可以使用什么好方法来制作"观察者"或听众。一个用户建议我应该使用Java的EventObject类来继承并创建一个Listener接口。然而,这并没有给我提供很好的灵活性。
下面是Handler注释,说明方法是侦听器中的事件处理程序:
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface Handler {}
下面是Event的基类,它基本上与EventObject相同(但我迟早会添加抽象方法):
public abstract class Event {
private Object source;
public Event(Object source) {
this.source = source;
}
public Object getSource() {
return source;
}
}
下面是Listener类,它为空:
public interface Listener {}
这是ListenerHandler类,用于处理所有侦听器。你在这里注册和注销它们。为了更好地使用,我将稍后编辑register/unregister方法:
public class ListenerHandler {
private ArrayList<Listener> listeners;
public ListenerHandler() {
this.listeners = new ArrayList<Listener>();
}
public void registerListener(Listener l) {
listeners.add(l);
}
public void unregisterListener(Listener l) {
listeners.remove(l);
}
public void onEvent(Event event) {
for(Listener l : listeners) {
Class<?> c = l.getClass();
Method[] methods = c.getDeclaredMethods();
for(Method m : methods) {
if(m.isAccessible()) {
if(m.isAnnotationPresent(Handler.class)) {
Class<?>[] params = m.getParameterTypes();
if(params.length > 1) {
continue;
}
Class<?> par = params[0];
if(par.getSuperclass().equals(Event.class)) {
try {
m.invoke(this, event);
}catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
}
据我所知,为了获得一个类的所有方法,它使用了大量内存。我不打算假设这是事实,但我确信有一个更好的方法,因为这将是一个包含许多组件的游戏引擎。
我想知道实现这个的最好方法,或者我做得对不对。我还想知道是否有人可以帮助我以任何方式改进这一点,而不会占用游戏的内存使用(到目前为止,这不是什么大问题——"游戏引擎"甚至还没有接近渲染任何东西)
我尽量保持它是一个非常简单的例子,并将用不同的想法来评论它:第一次见到成就类:
import java.util.Observable;
public class Achievement extends Observable {
public static class AchievementDetails {}
public Achievement() {
addObserver(EventsListener.getInstance());
}
public void achievementReached() {
AchievementDetails achievemetDetails = null;
setChanged();
notifyObservers(achievemetDetails);
}
}
然后是事件监听器类:
import com.test.Achievement.AchievementDetails;
public class EventsListener implements Observer {
private static EventsListener instance = new EventsListener();
public static EventsListener getInstance() {
return instance;
}
@Override
public void update(Observable o, Object arg) {
if(o instanceof Achievement) {
AchievementDetails achievemetDetails = (AchievementDetails) arg;
//do some logic here
}
}
}
唯一缺少的是创建一个成就实例(它将EventsListener注册到自己)并处理它的生命周期。