Generic interface with generic Enums extension

I am trying to write a common event system. For this, I would like to create an interface for EventHandlerlike this * (which does not work) *:

public interface GameEventHandler<I extends GameEvent<TYPE extends Enum<?>, ATT extends Enum<?>>> {
    public void handleEvent(final GameEvent<TYPE, ATT>... e);
    public void registerListener(final GameEventListener<I> listener,
            final TYPE... type);
    public void unregisterListener(final GameEventListener<I>... listener);
    public void unregisterAllListener();
    public void unregisterAllListener(final I... type);
    public void processEvents();
    public void processEvents(final int maxTimeInMS);
}

but it doesn’t work as I "think".

The event itself is a common element that will simply:

public class GameEvent<T extends Enum<?>, S extends Enum<?>> {
    private HashMap<S, String> values;
    private T type;

    public void init(T type) {
        this.type = type;
    }

    public T getType() {
        return this.type;
    }

    public void addMessage(S t, String value) {
        this.values.put(t, value);
    }

    public void getMessage(S t) {
        this.values.get(t);
    }
}

if I implement id HandlerInterfaceso that it is still shared, so there is something like to initialize it DefaultHandler<GameEvent<TypeEnum, AttributEnum>>(). This way you can use the interface to create your own handler, or use the DefaultHandlerone I provide, but still can use your own Enums.

At the moment, I managed to create such an interface:

public interface GameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends Enum<?>, ATT extends Enum<?>> 

But I do not get the implementation of DefaultHandler Generic

public class DefaultGameEventHandler implements GameEventHandler<GameEvent<EventTypes, AttributeTypes>, EventTypes, AttributeTypes>  // not generic those are testing Enums

So what am I doing wrong? Is it possible as if I would like to have it?

+3
2

, , . DefaultGameEventHandler , :

, GameEventHandler, Enums EventTypes AttributeTypes, GameEventHandler EventType AttributeType:

public interface GameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends EventType, ATT extends  AttributeType> {

    public void handleEvent(final GameEvent<TYPE, ATT>... e);
    public void registerListener(final GameEventListener<I> listener, final TYPE... type);

    public void unregisterListener(final GameEventListener<I>... listener);

    public void unregisterAllListener();
    public void unregisterAllListener(final I... type);

    public void processEvents();
    public void processEvents(final int maxTimeInMS);

}

GameEvent:

public interface EventType {
    // common functionality of EventTypes, if any
}

public interface AttributeType {
    // common functionality of AttributeTypes , if any
}

public class GameEvent<T extends EventType, S extends AttributeType> {
    private HashMap<S, String> values;
    private T type;

    public void init(T type) {
        this.type = type;
    }

    public T getType() {
        return this.type;
    }

    public void addMessage(S t, String value) {
        this.values.put(t, value);
    }

    public void getMessage(S t) {
        this.values.get(t);
    }
}

Enums, :

enum MyEventTypes implements EventType{TYPE_1,TYPE_2,TYPE_3}

enum MyAttributeTypes implements AttributeType{ATT_1,ATT_2,ATT_3}

Enum, :

public interface EventType {
    Enum<?> asEnum();
}

enum MyEventTypes implements EventType{
    TYPE_1,TYPE_2,TYPE_3;
    @Override
    public Enum<?> asEnum() {return this;}
}

DefaultGameEventHandler, GameEventHandler:

public class DefaultGameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends EventType, ATT extends  AttributeType> implements GameEventHandler<I, TYPE, ATT>{ 

    @Override
    public void handleEvent(GameEvent<TYPE, ATT>... e) {
        //...
    }
    @Override
    public void registerListener(GameEventListener<I> listener, TYPE... type) {
        //...
    }
    @Override
    public void unregisterListener(GameEventListener<I>... listener) {
        //...
    }
    @Override
    public void unregisterAllListener() {
        //...
    }
    @Override
    public void unregisterAllListener(I... type) {
        //...
    }
    @Override
    public void processEvents() {
        //...
    }
    @Override
    public void processEvents(int maxTimeInMS) {
        //...
    }
}

DefaultGameEventHandler

//MyEventTypes and MyAttributeTypes are enums implementing EventType respectively AttributeType
DefaultGameEventHandler<GameEvent<MyEventTypes, MyAttributeTypes>, MyEventTypes, MyAttributeTypes> handler = new DefaultGameEventHandler<>();
GameEvent<MyEventTypes, MyAttributeTypes> event = new GameEvent<>();
event.addMessage(MyAttributeTypes.ATT_1, "some Message");
event.init(MyEventTypes.TYPE_1);
handler.handleEvent(event);
switch (event.getType()) {
    case TYPE_1:
        System.out.println("TYPE_1");
        break;
    case TYPE_2:
        System.out.println("TYPE_2");
        break;
    case TYPE_3:
        System.out.println("TYPE_3");
        break;
    default:
        break;
}

, :

DefaultGameEventHandler<GameEvent<EventType, AttributeType>, EventType, AttributeType> handler = new DefaultGameEventHandler<>();
GameEvent<EventType, AttributeType> event = new GameEvent<>();
event.addMessage(MyAttributeTypes.ATT_1, "some Message");
event.init(MyEventTypes.TYPE_1);
handler.handleEvent(event);
EventType type = event.getType();
// To switch on the type you could use the asEnum() method
// and cast the type to the corresponding enum if possible:
if (type.asEnum().getClass() == MyEventTypes.class) {
    MyEventTypes t = (MyEventTypes)type.asEnum();
    switch (t) {
        case TYPE_1:
            System.out.println("TYPE_1");
            break;
        case TYPE_2:
            System.out.println("TYPE_2");
            break;
        case TYPE_3:
            System.out.println("TYPE_3");
            break;
        default:
            break;
    }
}
// Or you could also directly switch on the name of the enum (not recommended!):
switch (type.asEnum().name()) {
    case "TYPE_1":
        System.out.println("TYPE_1");
        break;
    case "TYPE_2":
        System.out.println("TYPE_2");
        break;
    case "TYPE_3":
        System.out.println("TYPE_3");
        break;
    default:
        break;
}

EDIT. BennX:

, Eventhandlers GameEvents 2 Enums. , , .

, Enums . Enums, :

public class GameEvent<T extends Enum<?>, S extends Enum<?>>

public interface GameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends Enum<?>, ATT extends  Enum<?>>

public class DefaultGameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE extends Enum<?>, ATT extends  Enum<?>> implements GameEventHandler<I, TYPE, ATT>

Enums GameEventHandler? - EventType AttributeType, - GameEventHandler :

public interface GameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE, ATT>

public class GameEvent<T, S>

public class DefaultGameEventHandler<I extends GameEvent<TYPE, ATT>, TYPE, ATT> implements GameEventHandler<I, TYPE, ATT>

, , DefaultGameEventHandler Enums, GameEventHandler. Enums , .

+1

, DefaultGameEventHandler :

class DefaultGameEventHandler<TYPE extends Enum<?>,ATT extends Enum<?>>  implements GameEventHandler<GameEvent<TYPE, ATT>,TYPE,ATT>
-1

All Articles