Feat: Adds functionality to periodically refresh lobbies to update lobby GUI screen

This commit is contained in:
Jona Walpert
2026-04-09 10:43:25 +02:00
parent df31c307fe
commit b205b25b48
@@ -12,6 +12,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import ch.unibas.dmi.dbis.cs108.casono.client.network.LobbyClient; import ch.unibas.dmi.dbis.cs108.casono.client.network.LobbyClient;
import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService; import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService;
import javafx.scene.Node; import javafx.scene.Node;
@@ -59,6 +61,8 @@ public class LobbyButtonGridManager {
/** Executor for background status/network tasks. */ /** Executor for background status/network tasks. */
private final ExecutorService executor = Executors.newCachedThreadPool(); private final ExecutorService executor = Executors.newCachedThreadPool();
/** Scheduler for periodic refresh of lobby mappings. */
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
/** /**
* Constructor for the GridManager. * Constructor for the GridManager.
@@ -72,6 +76,8 @@ public class LobbyButtonGridManager {
// Always use the singleton // Always use the singleton
this.translationManager = LobbyButtonTranslationManager.getInstance(); this.translationManager = LobbyButtonTranslationManager.getInstance();
this.lobbyClient = lobbyClient; this.lobbyClient = lobbyClient;
// Start periodic refresh to keep mapping in sync with server
startPeriodicRefresh(5, 5);
} }
/** /**
@@ -84,6 +90,51 @@ public class LobbyButtonGridManager {
this(gridPane, translationManager, new LobbyClient(clientService)); this(gridPane, translationManager, new LobbyClient(clientService));
} }
/**
* Start periodic refresh of lobby mappings.
*
* @param initialDelay initial delay in seconds
* @param period period in seconds
*/
private void startPeriodicRefresh(long initialDelay, long period) {
scheduler.scheduleAtFixedRate(this::refreshMappings, initialDelay, period, TimeUnit.SECONDS);
}
/**
* Refresh mappings by checking each stored lobby id on the server. If a lobby
* no longer exists (or an error occurs), remove it from the translation map
* and update the UI.
*/
private void refreshMappings() {
Map<Integer, Integer> mapping = translationManager.getButtonIdToLobbyId();
if (mapping.isEmpty()) {
return;
}
// Make a copy of entries to avoid concurrent modification
List<Map.Entry<Integer, Integer>> entries = new ArrayList<>(mapping.entrySet());
for (Map.Entry<Integer, Integer> e : entries) {
int buttonId = e.getKey();
int lobbyId = e.getValue();
CompletableFuture.supplyAsync(() -> {
try {
String status = lobbyClient.fetchLobbyStatusString(lobbyId);
return status;
} catch (Exception ex) {
LOGGER.info("Lobby {} appears missing or error: {}", lobbyId, ex.getMessage());
return null;
}
}, executor).thenAccept(status -> {
if (status == null) {
// remove mapping and update UI
translationManager.removeLobbyButton(buttonId);
javafx.application.Platform.runLater(() -> {
updateLobbyButtonImages();
});
}
});
}
}
// Default client creation removed to avoid implicit IP/port configuration. // Default client creation removed to avoid implicit IP/port configuration.
// Applications must construct and provide a LobbyClient or ClientService // Applications must construct and provide a LobbyClient or ClientService
// explicitly. // explicitly.
@@ -309,6 +360,8 @@ public class LobbyButtonGridManager {
ev -> { ev -> {
try { try {
currentStage.show(); currentStage.show();
// refresh mappings immediately when returning from game
refreshMappings();
updateLobbyButtonImages(); updateLobbyButtonImages();
} catch (Exception ex) { } catch (Exception ex) {
LOGGER.error( LOGGER.error(
@@ -346,4 +399,12 @@ public class LobbyButtonGridManager {
return lobbyClient; return lobbyClient;
} }
/**
* Trigger an immediate refresh of mappings (poll server and remove missing
* lobbies). Public so callers can force a refresh when UI focus returns.
*/
public void refreshNow() {
refreshMappings();
}
} }