Fix music display not working (#267)

* Added unsubscribe to EventFlow. ListenerHandler now functional. GlobalEventbus now user listenerHandler

* getAllListeners

* Removed nulls

* Fixed stress tests

* Added docs, no more list creation when adding events to the bus.

* Fixed unsubscribe not working.

* Moved away from deprecated functions

* moved from wildcard to typed

* Moved away from deprecated function

* Added debugging to GlobalEventBus

* Fixed cleaning flow

* Fixed unsubscribe all

* Fixed unsubscribe all

* Removed unused import

* Added LoadingWidget.java for server feedback

* Replace deprecated with correct function
This commit is contained in:
Bas Antonius de Jong
2025-11-30 17:51:52 +01:00
committed by GitHub
parent 81740acd04
commit 12a20a224e
6 changed files with 117 additions and 13 deletions

View File

@@ -1,18 +1,23 @@
package org.toop.app; package org.toop.app;
import javafx.application.Platform;
import javafx.geometry.Pos;
import org.toop.app.game.Connect4Game; import org.toop.app.game.Connect4Game;
import org.toop.app.game.ReversiGame; import org.toop.app.game.ReversiGame;
import org.toop.app.game.TicTacToeGame; import org.toop.app.game.TicTacToeGame;
import org.toop.app.widget.WidgetContainer; import org.toop.app.widget.WidgetContainer;
import org.toop.app.widget.complex.LoadingWidget;
import org.toop.app.widget.popup.ChallengePopup; import org.toop.app.widget.popup.ChallengePopup;
import org.toop.app.widget.popup.ErrorPopup; import org.toop.app.widget.popup.ErrorPopup;
import org.toop.app.widget.popup.SendChallengePopup; import org.toop.app.widget.popup.SendChallengePopup;
import org.toop.app.widget.view.ServerView; import org.toop.app.widget.view.ServerView;
import org.toop.framework.eventbus.EventFlow; import org.toop.framework.eventbus.EventFlow;
import org.toop.framework.eventbus.ListenerHandler;
import org.toop.framework.networking.clients.TournamentNetworkingClient; import org.toop.framework.networking.clients.TournamentNetworkingClient;
import org.toop.framework.networking.events.NetworkEvents; import org.toop.framework.networking.events.NetworkEvents;
import org.toop.framework.networking.types.NetworkingConnector; import org.toop.framework.networking.types.NetworkingConnector;
import org.toop.local.AppContext; import org.toop.local.AppContext;
import java.util.function.Consumer;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@@ -69,24 +74,35 @@ public final class Server {
return; return;
} }
new EventFlow() final int reconnectAttempts = 10;
LoadingWidget loading = new LoadingWidget(0, reconnectAttempts);
loading.show(Pos.CENTER);
var a = new EventFlow()
.addPostEvent(NetworkEvents.StartClient.class, .addPostEvent(NetworkEvents.StartClient.class,
new TournamentNetworkingClient(), new TournamentNetworkingClient(),
new NetworkingConnector(ip, parsedPort, 10, 1, TimeUnit.SECONDS) new NetworkingConnector(ip, parsedPort, reconnectAttempts, 1, TimeUnit.SECONDS)
) );
.onResponse(NetworkEvents.StartClientResponse.class, e -> {
this.user = user;
clientId = e.clientId();
new EventFlow().addPostEvent(new NetworkEvents.SendLogin(clientId, user)).postEvent(); a.onResponse(NetworkEvents.StartClientResponse.class, e -> {
primary = new ServerView(user, this::sendChallenge, this::disconnect); a.unsubscribe("startclient");
WidgetContainer.getCurrentView().transitionNext(primary);
startPopulateScheduler(); loading.hide();
populateGameList(); this.user = user;
clientId = e.clientId();
}).postEvent(); new EventFlow().addPostEvent(new NetworkEvents.SendLogin(clientId, user)).postEvent();
primary = new ServerView(user, this::sendChallenge, this::disconnect);
WidgetContainer.getCurrentView().transitionNext(primary);
startPopulateScheduler();
populateGameList();
}, false, "startclient").listen(NetworkEvents.ConnectTry.class, e -> {
Platform.runLater(() -> loading.setAmount(e.amount()));
}).postEvent();
new EventFlow().listen(this::handleReceivedChallenge) new EventFlow().listen(this::handleReceivedChallenge)
.listen(this::handleMatchResponse); .listen(this::handleMatchResponse);

View File

@@ -0,0 +1,75 @@
package org.toop.app.widget.complex;
import javafx.geometry.Pos;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
public class LoadingWidget extends ViewWidget implements Update { // TODO make of widget type
private final ProgressBar progressBar;
private Runnable success = () -> {};
private Runnable failure = () -> {};
private int maxAmount;
private int amount;
private float percentage = 0.0f;
public LoadingWidget(int startAmount, int maxAmount) {
amount = startAmount;
this.maxAmount = maxAmount;
progressBar = new ProgressBar();
HBox box = new HBox(10, progressBar);
add(Pos.CENTER, box);
}
public void setMaxAmount(int maxAmount) {
this.maxAmount = maxAmount;
}
public void setAmount(int amount) {
this.amount = amount;
update();
}
public void setAmount() {
setAmount(this.amount+1);
}
public void setOnSuccess(Runnable onSuccess) {
success = onSuccess;
}
public void setOnFailure(Runnable onFailure) {
failure = onFailure;
}
public void triggerSuccess() {
success.run();
}
public void triggerFailure() {
failure.run();
}
@Override
public void update() {
if (amount >= maxAmount) {
triggerSuccess();
System.out.println("triggered");
this.hide();
return;
} else if (amount < 0) {
triggerFailure();
System.out.println("triggerFailure");
this.hide();
return;
}
percentage = (float) amount / maxAmount;
progressBar.setProgress(percentage);
}
}

View File

@@ -0,0 +1,5 @@
package org.toop.app.widget.complex;
public interface Update {
void update();
}

View File

@@ -22,7 +22,7 @@ public class SongDisplay extends VBox implements Widget {
public SongDisplay() { public SongDisplay() {
new EventFlow() new EventFlow()
.listen(this::updateTheSong); .listen(AudioEvents.PlayingMusic.class, this::updateTheSong, false);
setAlignment(Pos.CENTER); setAlignment(Pos.CENTER);
setMaxHeight(Region.USE_PREF_SIZE); setMaxHeight(Region.USE_PREF_SIZE);

View File

@@ -8,6 +8,8 @@ import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.toop.framework.eventbus.GlobalEventBus;
import org.toop.framework.networking.events.NetworkEvents;
import org.toop.framework.networking.exceptions.ClientNotFoundException; import org.toop.framework.networking.exceptions.ClientNotFoundException;
import org.toop.framework.networking.exceptions.CouldNotConnectException; import org.toop.framework.networking.exceptions.CouldNotConnectException;
import org.toop.framework.networking.interfaces.NetworkingClient; import org.toop.framework.networking.interfaces.NetworkingClient;
@@ -44,6 +46,7 @@ public class NetworkingClientManager implements org.toop.framework.networking.in
nClient.connect(id, nConnector.host(), nConnector.port()); nClient.connect(id, nConnector.host(), nConnector.port());
networkClients.put(id, nClient); networkClients.put(id, nClient);
logger.info("New client started successfully for {}:{}", nConnector.host(), nConnector.port()); logger.info("New client started successfully for {}:{}", nConnector.host(), nConnector.port());
GlobalEventBus.post(new NetworkEvents.ConnectTry(id, attempts, nConnector.reconnectAttempts(), true));
onSuccess.run(); onSuccess.run();
scheduler.shutdown(); scheduler.shutdown();
} catch (CouldNotConnectException e) { } catch (CouldNotConnectException e) {
@@ -51,14 +54,17 @@ public class NetworkingClientManager implements org.toop.framework.networking.in
if (attempts < nConnector.reconnectAttempts()) { if (attempts < nConnector.reconnectAttempts()) {
logger.warn("Could not connect to {}:{}. Retrying in {} {}", logger.warn("Could not connect to {}:{}. Retrying in {} {}",
nConnector.host(), nConnector.port(), nConnector.timeout(), nConnector.timeUnit()); nConnector.host(), nConnector.port(), nConnector.timeout(), nConnector.timeUnit());
GlobalEventBus.post(new NetworkEvents.ConnectTry(id, attempts, nConnector.reconnectAttempts(), false));
scheduler.schedule(this, nConnector.timeout(), nConnector.timeUnit()); scheduler.schedule(this, nConnector.timeout(), nConnector.timeUnit());
} else { } else {
logger.error("Failed to start client for {}:{} after {} attempts", nConnector.host(), nConnector.port(), attempts); logger.error("Failed to start client for {}:{} after {} attempts", nConnector.host(), nConnector.port(), attempts);
GlobalEventBus.post(new NetworkEvents.ConnectTry(id, -1, nConnector.reconnectAttempts(), false));
onFailure.run(); onFailure.run();
scheduler.shutdown(); scheduler.shutdown();
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Unexpected exception during startClient", e); logger.error("Unexpected exception during startClient", e);
GlobalEventBus.post(new NetworkEvents.ConnectTry(id, -1, nConnector.reconnectAttempts(), false));
onFailure.run(); onFailure.run();
scheduler.shutdown(); scheduler.shutdown();
} }

View File

@@ -181,6 +181,8 @@ public class NetworkEvents extends EventsBase {
public record StartClientResponse(long clientId, boolean successful, long identifier) public record StartClientResponse(long clientId, boolean successful, long identifier)
implements ResponseToUniqueEvent {} implements ResponseToUniqueEvent {}
public record ConnectTry(long clientId, int amount, int maxAmount, boolean success) implements GenericEvent {}
/** /**
* Requests reconnection of an existing client using its previous configuration. * Requests reconnection of an existing client using its previous configuration.
* <p> * <p>