package games.strategy.engine.chat; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import games.strategy.net.INode; import games.strategy.net.Messengers; public class StatusManager { private final List<IStatusListener> listeners = new CopyOnWriteArrayList<>(); private final Map<INode, String> status = new HashMap<>(); private final Messengers messengers; private final Object mutex = new Object(); private final IStatusChannel statusChannelSubscribor; public StatusManager(final Messengers messengers) { this.messengers = messengers; statusChannelSubscribor = (node, status1) -> { synchronized (mutex) { if (status1 == null) { StatusManager.this.status.remove(node); } else { StatusManager.this.status.put(node, status1); } } notifyStatusChanged(node, status1); }; if (messengers.getMessenger().isServer() && !messengers.getRemoteMessenger().hasLocalImplementor(IStatusController.STATUS_CONTROLLER)) { final StatusController controller = new StatusController(messengers); messengers.getRemoteMessenger().registerRemote(controller, IStatusController.STATUS_CONTROLLER); } this.messengers.getChannelMessenger().registerChannelSubscriber(statusChannelSubscribor, IStatusChannel.STATUS_CHANNEL); final IStatusController controller = (IStatusController) this.messengers.getRemoteMessenger().getRemote(IStatusController.STATUS_CONTROLLER); final Map<INode, String> values = controller.getAllStatus(); synchronized (mutex) { status.putAll(values); // at this point we are just being constructed, so we have no // listeners // and we do not need to notify if anything has changed } } public void shutDown() { messengers.getChannelMessenger().unregisterChannelSubscriber(statusChannelSubscribor, IStatusChannel.STATUS_CHANNEL); } /** * Get the status for the given node. */ public String getStatus(final INode node) { synchronized (mutex) { return status.get(node); } } public void setStatus(final String status) { final IStatusController controller = (IStatusController) messengers.getRemoteMessenger().getRemote(IStatusController.STATUS_CONTROLLER); controller.setStatus(status); } public void addStatusListener(final IStatusListener listener) { listeners.add(listener); } public void removeStatusListener(final IStatusListener listener) { listeners.remove(listener); } private void notifyStatusChanged(final INode node, final String newStatus) { for (final IStatusListener listener : listeners) { listener.statusChanged(node, newStatus); } } }