diff --git a/framework/src/main/java/org/toop/framework/networking/server/Server.java b/framework/src/main/java/org/toop/framework/networking/server/Server.java index 12cd052..129bc17 100644 --- a/framework/src/main/java/org/toop/framework/networking/server/Server.java +++ b/framework/src/main/java/org/toop/framework/networking/server/Server.java @@ -6,6 +6,7 @@ import org.toop.framework.networking.server.challenges.gamechallenge.GameChallen import org.toop.framework.networking.server.challenges.gamechallenge.GameChallengeTimer; import org.toop.framework.networking.server.client.NettyClient; import org.toop.framework.networking.server.stores.ClientStore; +import org.toop.framework.networking.server.stores.SubscriptionStore; import org.toop.framework.networking.server.stores.TurnBasedGameStore; import org.toop.framework.networking.server.stores.TurnBasedGameTypeStore; import org.toop.framework.utils.ImmutablePair; @@ -21,7 +22,7 @@ public class Server implements GameServer { final private List gameChallenges = new CopyOnWriteArrayList<>(); final private TurnBasedGameStore gameStore; - final private ConcurrentHashMap> subscriptions; // TODO move to own store / manager + final private SubscriptionStore subscriptionStore; final private Duration challengeDuration; final private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); @@ -30,14 +31,15 @@ public class Server implements GameServer { Duration challengeDuration, TurnBasedGameTypeStore turnBasedGameTypeStore, ClientStore clientStore, - TurnBasedGameStore gameStore + TurnBasedGameStore gameStore, + SubscriptionStore subStore ) { this.gameTypesStore = turnBasedGameTypeStore; this.challengeDuration = challengeDuration; this.clientStore = clientStore; this.gameStore = gameStore; - this.subscriptions = new ConcurrentHashMap<>(); + this.subscriptionStore = subStore; scheduler.schedule(this::serverTask, 0, TimeUnit.MILLISECONDS); } @@ -114,16 +116,12 @@ public class Server implements GameServer { return; } - subscriptions.forEach((_, clientNames) -> clientNames.remove(clientName)); - subscriptions.computeIfAbsent( - gameTypeKey, - _ -> new ArrayList<>()) - .add(clientName); + subscriptionStore.add(new ImmutablePair<>(gameTypeKey, clientName)); } @Override public void unsubscribeClient(String clientName) { - subscriptions.forEach((_, clientNames) -> clientNames.remove(clientName)); + subscriptionStore.remove(clientName); } @Override @@ -191,13 +189,12 @@ public class Server implements GameServer { } private void checkSubscriptions() { - if (subscriptions.isEmpty()) return; + if (subscriptionStore.allKeys().isEmpty()) return; - List keys = List.copyOf(subscriptions.keySet()); Random ran = new Random(); - for (String key : keys) { - List userNames = subscriptions.get(key); + for (String key : subscriptionStore.allKeys()) { + List userNames = (List) subscriptionStore.allValues(key); if (userNames.size() < 2) continue; while (userNames.size() > 1) { diff --git a/framework/src/main/java/org/toop/framework/networking/server/gateway/NettyGatewayServer.java b/framework/src/main/java/org/toop/framework/networking/server/gateway/NettyGatewayServer.java index 8123255..8b0dd2a 100644 --- a/framework/src/main/java/org/toop/framework/networking/server/gateway/NettyGatewayServer.java +++ b/framework/src/main/java/org/toop/framework/networking/server/gateway/NettyGatewayServer.java @@ -17,6 +17,7 @@ import org.toop.framework.networking.server.client.NettyClient; import org.toop.framework.networking.server.connectionHandler.NettyClientSession; import org.toop.framework.networking.server.Server; import org.toop.framework.networking.server.handlers.MessageHandler; +import org.toop.framework.networking.server.stores.MapSubscriptionStore; import org.toop.framework.networking.server.stores.NettyClientStore; import org.toop.framework.networking.server.stores.TurnBasedGameStore; import org.toop.framework.networking.server.stores.TurnBasedGameTypeStore; @@ -43,7 +44,8 @@ public class NettyGatewayServer implements GatewayServer { challengeDuration, turnBasedGameTypeStore, new NettyClientStore(new ConcurrentHashMap<>()), - new TurnBasedGameStore(new CopyOnWriteArrayList<>()) + new TurnBasedGameStore(new CopyOnWriteArrayList<>()), + new MapSubscriptionStore(new ConcurrentHashMap<>()) ); } diff --git a/framework/src/main/java/org/toop/framework/networking/server/stores/MapSubscriptionStore.java b/framework/src/main/java/org/toop/framework/networking/server/stores/MapSubscriptionStore.java new file mode 100644 index 0000000..64b092b --- /dev/null +++ b/framework/src/main/java/org/toop/framework/networking/server/stores/MapSubscriptionStore.java @@ -0,0 +1,71 @@ +package org.toop.framework.networking.server.stores; + +import org.toop.framework.utils.ImmutablePair; + +import java.util.*; + +public class MapSubscriptionStore implements SubscriptionStore { + + final private Map> subscriptions; + + public MapSubscriptionStore(Map> initMap) { + this.subscriptions = initMap; + } + + @Override + public void add(ImmutablePair adding) { + subscriptions.forEach((_, clientNames) -> clientNames.remove(adding.getRight())); + subscriptions.computeIfAbsent( + adding.getLeft(), + _ -> new ArrayList<>()) + .add(adding.getRight()); + } + + @Override + public void remove(String remover) { + subscriptions.forEach((_, clientNames) -> clientNames.remove(remover)); + } + + // TODO move server internal code to here + @Override + public ImmutablePair get(String getter) { + String foundKey = null; + String foundName = null; + + for (var key : subscriptions.keySet()) { + var a = subscriptions.get(key).stream().filter(e -> e.equals(getter)).toList(); + if (!a.isEmpty()) { + foundKey = key; + foundName = a.getFirst(); + break; + } + } + + return new ImmutablePair<>(foundKey, foundName); + + } + + @Override + public Collection> all() { + List> a = new ArrayList<>(); + + for (var key : subscriptions.keySet()) { + for (var sub : subscriptions.get(key)) { + a.addLast(new ImmutablePair<>(key, sub)); + } + } + + return a; + + } + + @Override + public Collection allKeys() { + return subscriptions.keySet(); + } + + @Override + public Collection allValues(String key) { + return subscriptions.get(key); + } +} diff --git a/framework/src/main/java/org/toop/framework/networking/server/stores/SubscriptionStore.java b/framework/src/main/java/org/toop/framework/networking/server/stores/SubscriptionStore.java new file mode 100644 index 0000000..5ef6f35 --- /dev/null +++ b/framework/src/main/java/org/toop/framework/networking/server/stores/SubscriptionStore.java @@ -0,0 +1,10 @@ +package org.toop.framework.networking.server.stores; + +import org.toop.framework.utils.ImmutablePair; + +import java.util.Collection; + +public interface SubscriptionStore extends Store> { + Collection allKeys(); + Collection allValues(String key); +}