A long-standing issue: We have many listener interfaces, and if you want to listen to a specific event, you gotta find the right interface and still implement a bunch of extra no-op methods.
The worst issue however is the unwrapping of Protocol Messages: For many messages, there is a corresponding listener/notify method with the same signature as the Message, essentially duplicating it. With generic listening, these messages could instead simply be passed through - DRY!
A good example is the LobbyClient:
protected final void onObject(ProtocolMessage o) {
[...]
if (o instanceof RoomPacket) {
RoomPacket packet = (RoomPacket) o;
String roomId = packet.getRoomId();
ProtocolMessage data = packet.getData();
if (data instanceof MementoEvent) {
onNewState(roomId, ((MementoEvent) data).getState());
} else if (data instanceof GameResult) {
logger.info("Received game result");
onGameOver(roomId, (GameResult) data);
} else if (data instanceof GamePausedEvent) {
onGamePaused(roomId, ((GamePausedEvent) data).getNextPlayer());
} else if (data instanceof ProtocolErrorMessage) {
logger.debug("Received error packet");
onError(roomId, ((ProtocolErrorMessage) data));
} else {
onRoomMessage(roomId, data);
}
} else if (o instanceof GamePreparedResponse) {
onGamePrepared((GamePreparedResponse) o);
} else if (o instanceof JoinedRoomResponse) {
onGameJoined(((JoinedRoomResponse) o).getRoomId());
} else if (o instanceof RoomWasJoinedEvent) {
onGameJoined(((RoomWasJoinedEvent) o).getRoomId());
} else if (o instanceof LeftGameEvent) {
onGameLeft(((LeftGameEvent) o).getRoomId());
} else if (o instanceof ObservationResponse) {
onGameObserved(((ObservationResponse) o).getRoomId());
} else if (o instanceof TestModeResponse) {
boolean testMode = (((TestModeResponse) o).getTestMode());
logger.info("TestMode was set to {} ", testMode);
} else if (o instanceof ProtocolErrorMessage) {
ProtocolErrorMessage response = (ProtocolErrorMessage) o;
onError(response.getMessage(), response);
} else {
onCustomObject(o);
}
}
private void onGamePaused(String roomId, Player nextPlayer) {
for (IAdministrativeListener listener : this.administrativeListeners) {
listener.onGamePaused(roomId, nextPlayer);
}
for (ILobbyClientListener listener : this.listeners) {
listener.onGamePaused(roomId, nextPlayer);
}
}
private void onGameOver(String roomId, GameResult data) {
for (IHistoryListener listener : this.historyListeners) {
listener.onGameOver(roomId, data);
}
for (ILobbyClientListener listener : this.listeners) {
listener.onGameOver(roomId, data);
}
}
private void onGameLeft(String roomId) {
for (ILobbyClientListener listener : this.listeners) {
listener.onGameLeft(roomId);
}
}
[...]
A long-standing issue: We have many listener interfaces, and if you want to listen to a specific event, you gotta find the right interface and still implement a bunch of extra no-op methods.
The worst issue however is the unwrapping of Protocol Messages: For many messages, there is a corresponding listener/notify method with the same signature as the Message, essentially duplicating it. With generic listening, these messages could instead simply be passed through - DRY!
A good example is the LobbyClient: