2013-06-17 5 views
5

В моем приложении Layer/View есть система диспетчеризации событий, а также доска. В нем слушатели хранятся с помощью хэш-карты с ключами, которые являются типами событий, реализованными как перечисляемый EventType, а значения - это ссылки слушателя, которые прослушивают этот тип события. Например. объект модели прослушивает тип события «LOCAL_PLAYER_INPUT», доски обрабатывают и уведомляют игрока, так как игрок реализует интерфейс EventHandler.Инкапсулированная обработка событий с помощью Enums

Я хотел бы отделить мою модель дальше, выполнив отдельную доску для модели. Затем он будет добавлен в качестве слушателя к доске уровня приложения, поскольку прикладной уровень получает ввод/вывод с клавиатуры или прикосновения. Модельная доску сама делегировала бы события дальше. Для этого я хотел создать перечислимую иерархию, где событие классифицируется таким образом:

MODEL.LOCAL.PLAYER_INPUT 

Модель будет зарегистрирована в качестве слушателя в виде доске только пройдя MODEL так:

addListener(model.blackboard, MODEL); //Types: (EventHandler, EventType) 

По сочетая интерфейсы с перечислениями, которые я достиг, чтобы я мог писать типы событий, такие как MODEL.XY, но он не будет принят addListener, хотя MODEL реализует интерфейс EventType.

Что мне делать?

EDIT: Еще немного кода

Метод добавления слушателя:

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; 
    } 

} 

Перечисления:

public interface WL extends EventType { 

public static enum LOCAL { 
    PLAYER_INPUT, 
    NPC_INPUT 
} 

}

GameEvent:

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

} 
+0

Поскольку ваши ключи перечислены, вам следует использовать «EnumMap». Хотя я считаю, что на самом деле это не критическая производительность здесь – fge

+0

Это хороший совет, я его реализую, спасибо! –

+0

Некоторый код был бы полезен. Как выглядят ваши перечисления (ы), о чем жалуется компилятор? – lost

ответ

0

MODEL.LOCAL.PLAYER_INPUT не имеет значения EventType хотя MODEL есть. Поскольку enum является внутренним классом MODEL, это тип acctually 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 
    } 
} 

Вы можете изменить его:

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 
    } 
} 

Проблема в том, если вы сейчас смотрите WL.LOCAL, это тип будет Class (не 100% уверен, что один, но это deffinetly не EventType. Не может даже скомпилироваться). Вам нужно объявить LOCAL в качестве константы перечисления, чтобы получить к нему доступ таким образом. К сожалению, нет никакого способа сделать это, если у обоих должно быть одно имя.

Если я не пропущу что-то, вам нужно будет найти совершенно другое решение. Не может быть ответа, который вы искали, но слишком долго, чтобы вставить комментарий.

+0

Спасибо за ваш ответ. Я собираюсь сделать это сейчас: Поскольку enum WL (это сокращение от WorldLogic, это имя для моей модели) относится к типу WL, я могу сделать проверку getClass() и все в порядке. Добавьте на мою доску перегруженный метод addListener, который добавляет слушателей, которые ищут специальный класс, и все. –

Смежные вопросы