diff --git a/Server/src/test/java/uulm/teamname/marvelous/server/lobbymanager/LobbyRunner.java b/Server/src/test/java/uulm/teamname/marvelous/server/lobbymanager/LobbyRunner.java new file mode 100644 index 0000000..a73bf1d --- /dev/null +++ b/Server/src/test/java/uulm/teamname/marvelous/server/lobbymanager/LobbyRunner.java @@ -0,0 +1,79 @@ +package uulm.teamname.marvelous.server.lobbymanager; + +import org.tinylog.Logger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +/** + * Class meant for running lobbies. It manages said lobbys, creates threads for it, and moves it into an executor + */ +public class LobbyRunner { + + private static LobbyRunner instance; + + static LobbyRunner getInstance() { + if (instance == null) { + instance = new LobbyRunner(); + } + return instance; + } + + + private final HashMap activeLobbies; + + private LobbyRunner() { + this.activeLobbies = new HashMap<>(); + } + + /** Starts a new thread for the current LobbyConnection, and adds it to the currently active lobbies */ + void startLobby(LobbyConnection connection) { + Logger.trace("Starting lobby connection thread '{}'", connection.gameID); + synchronized (activeLobbies) { + if (activeLobbies.containsKey(connection)) { + Logger.warn("Already active lobby was started again. This is probably a bug."); + } else { + Logger.trace("Creating lobby thread 'Lobby-{}'...", connection.gameID); + var lobbyThread = new Thread(connection, "Lobby-" + connection.gameID); + Logger.trace("Creating mapping from LobbyConnection to newly created thread"); + activeLobbies.put(connection, lobbyThread); + Logger.debug("Starting new lobby thread '{}'", lobbyThread.getName()); + lobbyThread.start(); + } + } + } + + /** Calls {@link Thread#notify()} on the given lobbyConnection's thread */ + void notifyLobby(LobbyConnection toNotify) { + var lobbyThread = activeLobbies.get(toNotify); + if (lobbyThread == null) { + Logger.warn("Tried to notify non-existent lobby thread. This is probably a bug."); + } else { + lobbyThread.notify(); + } + } + + void removeLobby(LobbyConnection lobby) { + synchronized (activeLobbies) { + var lobbyThread = activeLobbies.get(lobby); + if (lobbyThread == null) { + Logger.warn("Tried to remove non-existent lobby thread. This is probably a bug."); + } else { + Logger.debug("Stopping and removing lobby '{}'", lobby.gameID); + lobby.terminateConnection(); + lobbyThread.notify(); + activeLobbies.remove(lobby); + } + } + } + + /** Shutdown all threads, destroy the lobbies, and close everything up */ + void shutdownAll() { + Logger.info("Stopping and removing all LobbyThreads"); + activeLobbies.keySet().forEach(this::removeLobby); + } +}