package games.strategy.engine.framework; import java.util.HashMap; import java.util.Map; import java.util.Set; import games.strategy.engine.data.GameData; import games.strategy.engine.data.PlayerID; import games.strategy.engine.data.PlayerList; import games.strategy.engine.data.PlayerManager; import games.strategy.engine.data.events.GameStepListener; import games.strategy.engine.display.DefaultDisplayBridge; import games.strategy.engine.display.IDisplay; import games.strategy.engine.gamePlayer.DefaultPlayerBridge; import games.strategy.engine.gamePlayer.IGamePlayer; import games.strategy.engine.gamePlayer.IPlayerBridge; import games.strategy.engine.message.IChannelMessenger; import games.strategy.engine.message.IRemoteMessenger; import games.strategy.engine.message.RemoteName; import games.strategy.engine.vault.Vault; import games.strategy.net.IMessenger; import games.strategy.net.INode; import games.strategy.net.Messengers; import games.strategy.sound.ISound; import games.strategy.util.ListenerList; /** * This abstract class keeps common variables and methods from a game (ClientGame or ServerGame). */ public abstract class AbstractGame implements IGame { protected static final String DISPLAY_CHANNEL = "games.strategy.engine.framework.AbstractGame.DISPLAY_CHANNEL"; protected static final String SOUND_CHANNEL = "games.strategy.engine.framework.AbstractGame.SOUND_CHANNEL"; protected final GameData m_data; protected final IMessenger m_messenger; protected final IRemoteMessenger m_remoteMessenger; protected final IChannelMessenger m_channelMessenger; protected final Map<PlayerID, IGamePlayer> m_gamePlayers = new HashMap<>(); protected volatile boolean m_isGameOver = false; protected final Vault m_vault; protected IGameModifiedChannel m_gameModifiedChannel; protected final PlayerManager m_playerManager; protected boolean m_firstRun = true; protected final ListenerList<GameStepListener> m_gameStepListeners = new ListenerList<>(); public AbstractGame(final GameData data, final Set<IGamePlayer> gamePlayers, final Map<String, INode> remotePlayerMapping, final Messengers messengers) { m_data = data; m_messenger = messengers.getMessenger(); m_remoteMessenger = messengers.getRemoteMessenger(); m_channelMessenger = messengers.getChannelMessenger(); m_vault = new Vault(m_channelMessenger); final Map<String, INode> allPlayers = new HashMap<>(remotePlayerMapping); for (final IGamePlayer player : gamePlayers) { // this is necessary for Server games, but not needed for client games. allPlayers.put(player.getName(), m_messenger.getLocalNode()); } m_playerManager = new PlayerManager(allPlayers); if (m_playerManager == null) { throw new IllegalArgumentException("Player manager cant be null"); } setupLocalPlayers(gamePlayers); } private void setupLocalPlayers(final Set<IGamePlayer> localPlayers) { final PlayerList playerList = m_data.getPlayerList(); for (final IGamePlayer gp : localPlayers) { final PlayerID player = playerList.getPlayerID(gp.getName()); m_gamePlayers.put(player, gp); final IPlayerBridge bridge = new DefaultPlayerBridge(this); gp.initialize(bridge, player); final RemoteName descriptor = ServerGame.getRemoteName(gp.getPlayerID(), m_data); m_remoteMessenger.registerRemote(gp, descriptor); } } /** * @param stepName * step name. * @param delegateName * delegate name * @param player * playerID * @param round * round number * @param displayName * display name */ protected void notifyGameStepListeners(final String stepName, final String delegateName, final PlayerID player, final int round, final String displayName) { for (final GameStepListener listener : m_gameStepListeners) { listener.gameStepChanged(stepName, delegateName, player, round, displayName); } } @Override public GameData getData() { return m_data; } @Override public Vault getVault() { return m_vault; } @Override public boolean isGameOver() { return m_isGameOver; } @Override public IRemoteMessenger getRemoteMessenger() { return m_remoteMessenger; } @Override public IChannelMessenger getChannelMessenger() { return m_channelMessenger; } @Override public IMessenger getMessenger() { return m_messenger; } @Override public PlayerManager getPlayerManager() { return m_playerManager; } @Override public void addGameStepListener(final GameStepListener listener) { m_gameStepListeners.add(listener); } @Override public void removeGameStepListener(final GameStepListener listener) { m_gameStepListeners.remove(listener); } public static RemoteName getDisplayChannel(final GameData data) { return new RemoteName(DISPLAY_CHANNEL, data.getGameLoader().getDisplayType()); } @Override public void addDisplay(final IDisplay display) { display.initialize(new DefaultDisplayBridge(m_data)); m_channelMessenger.registerChannelSubscriber(display, getDisplayChannel(getData())); } @Override public void removeDisplay(final IDisplay display) { m_channelMessenger.unregisterChannelSubscriber(display, getDisplayChannel(getData())); } public static RemoteName getSoundChannel(final GameData data) { return new RemoteName(SOUND_CHANNEL, data.getGameLoader().getSoundType()); } @Override public void addSoundChannel(final ISound soundChannel) { m_channelMessenger.registerChannelSubscriber(soundChannel, getSoundChannel(getData())); } @Override public void removeSoundChannel(final ISound soundChannel) { m_channelMessenger.unregisterChannelSubscriber(soundChannel, getSoundChannel(getData())); } }