Я полагаю, вы спрашиваете о том, как хранить и получать доступ к подписчикам.Так как вы не знаете классы событий, которые вам нужно будет привести в какой-то момент, но это может быть обработано внутри генератора.
Простое хранилище может быть Map<Class<? extends Event>, List<EventSubscriber<?>>
.
.Интерфейс подписчика может содержать метод Class<T> getEventClass()
, который используется в качестве ключа в этой карте при регистрации подписчика.
При запуске событий вы будете использовать класс события, чтобы просмотреть список подписчиков и получить List<EventSubscriber<?>>
.Теперь вы перебираете их и вызываете receiveEvent(event)
.Из-за подстановочного знака вам необходимо привести каждый элемент к необработанному типу EventSubscriber
, чтобы компилятор использовал метод моста receiveEvent(Object)
.
Обратите внимание, что, поскольку вы убедитесь, что тот же класс событийиспользуется для регистрации и поиска подписчиков, а подстановочные знаки скрыты внутри генератора, это должно быть безопасно.Мы постоянно используем такие вещи:)
Редактировать:
Вот пример того, как может выглядеть событие:
void fireEvent( Event event ) {
List<EventSubscriber<?>> subscribers = subscriberMap.get( event.getClass() );
//This cast will cause warnings that you'll want to suppress
//via @SuppressWarnings ( { "rawtypes", "unchecked" } ) on the method level
subscribers.forEach(s -> ((EventSubscriber)s).receiveEvent( event ) );
}
Внутренне компилятор сгенерирует метод моста receiveEvent( Object )
, который будет вызываться для необработанного типа, к которому вы привели подписчика.Как говорится в комментарии, это будет генерировать предупреждения, но если вы убедитесь, что поиск будет использовать тот же класс, что и фактический тип параметра, то их можно безопасно игнорировать.