software-challenge / backend

Server, Client und Spiel-Plugins der Software-Challenge Germany
https://www.software-challenge.de
11 stars 10 forks source link

Unify listeners and add filters instead of multiple interfaces #365

Open xeruf opened 3 years ago

xeruf commented 3 years ago

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);
    }
  }
[...]