使用Enums封装事件处理

Ale*_*ein 5 java enums

我的应用层/视图有一个事件调度系统,即黑板.在其中,侦听器由散列映射存储,其中键是作为枚举EventType实现的事件类型,而值是侦听此事件类型的侦听器引用.例如,模型对象正在侦听事件类型"LOCAL_PLAYER_INPUT",黑板进程并通知玩家,因为玩家实现了EventHandler接口.

我想通过为模型实现一个独立的黑板来进一步解耦我的模型.然后它将被添加为应用程序层黑板的监听器,因为应用程序层从键盘或触摸获得I/O. 模型黑板本身会进一步委托事件.为此我想创建一个枚举层次结构,其中事件以这种方式分类:

MODEL.LOCAL.PLAYER_INPUT
Run Code Online (Sandbox Code Playgroud)

只有通过这样传递MODEL,模型才会在视图黑板中注册为监听器:

addListener(model.blackboard, MODEL); //Types: (EventHandler, EventType)
Run Code Online (Sandbox Code Playgroud)

通过将接口与我实现的枚举相结合,我可以编写类似MODEL.XY的事件类型,但是尽管MODEL正在实现EventType接口,但addListener不会接受它.

我该怎么办?

编辑:更多代码

addListener方法:

    public void addListener(EventHandler handler, EventType eventType) {
    getListener(eventType).add(handler);}


private Array<EventHandler> getListener(EventType eventType) {
    if(map.containsKey(eventType))
        return map.get(eventType);
    else {
        Array<EventHandler> tmp = new Array<EventHandler>(false, 1, EventHandler.class);
        map.put(eventType, tmp);
        return tmp;
    }

}
Run Code Online (Sandbox Code Playgroud)

枚举:

public interface WL extends EventType {

public static enum LOCAL {
    PLAYER_INPUT,
    NPC_INPUT
}
Run Code Online (Sandbox Code Playgroud)

}

GameEvent:

    public GameEvent(EventType eventType, Object message) {
    this.eventType = eventType;
    this.message = message;
    timeStamp = System.currentTimeMillis();

}
Run Code Online (Sandbox Code Playgroud)

And*_*nek 0

MODEL.LOCAL.PLAYER_INPUTEventType尽管是,但不是类型MODEL。由于枚举是 的内部类MODEL,因此它的类型实际上是LOCAL

public interface WL extends EventType { // Your interface WL is EventType

    public static enum LOCAL { // Your enum is type LOCAL because there are no extensions
        PLAYER_INPUT,
        NPC_INPUT // Your enum constants represents something of type LOCAL
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以将其更改为:

public enum WL implements EventType { // Your interface WL is EventType

    public static enum LOCAL implements EventType { // LOCAL is now EventType
        PLAYER_INPUT,
        NPC_INPUT // So are the enum constants
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,如果您现在引用WL.LOCAL,它的类型将是Class(不能 100% 确定该类型,但它肯定不是EventType。甚至可能无法准确编译)。您必须声明LOCAL为枚举常量才能以这种方式访问​​它。遗憾的是,如果两者具有相同的名称,则无法做到这一点。

如果我没有遗漏什么,你就必须找到一个完全不同的解决方案。可能不是您正在寻找的答案,但太长,无法发表评论。