mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 02:44:50 +00:00
231 connecting to server feedback (#275)
* 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 * Imports * fixed loadingwidget * Workable LoadingWidget and trying to connect to server * Removed output * Small bug temp fix --------- Co-authored-by: ramollia <>
This commit is contained in:
committed by
GitHub
parent
4dbc4997a0
commit
3c9b010dd3
@@ -1,24 +1,24 @@
|
||||
package org.toop.app;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Pos;
|
||||
import org.toop.app.game.Connect4Game;
|
||||
import org.toop.app.game.gameControllers.AbstractGameController;
|
||||
import org.toop.app.game.gameControllers.ReversiController;
|
||||
import org.toop.app.game.gameControllers.TicTacToeController;
|
||||
import org.toop.app.game.ReversiGame;
|
||||
import org.toop.app.game.TicTacToeGame;
|
||||
import org.toop.app.widget.Primitive;
|
||||
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.ErrorPopup;
|
||||
import org.toop.app.widget.popup.SendChallengePopup;
|
||||
import org.toop.app.widget.view.ServerView;
|
||||
import org.toop.framework.eventbus.EventFlow;
|
||||
import org.toop.framework.eventbus.ListenerHandler;
|
||||
import org.toop.framework.networking.clients.TournamentNetworkingClient;
|
||||
import org.toop.framework.networking.events.NetworkEvents;
|
||||
import org.toop.framework.networking.types.NetworkingConnector;
|
||||
import org.toop.game.players.ArtificialPlayer;
|
||||
import org.toop.game.players.OnlinePlayer;
|
||||
import org.toop.game.players.AbstractPlayer;
|
||||
import org.toop.game.reversi.ReversiAIR;
|
||||
import org.toop.game.tictactoe.TicTacToeAIR;
|
||||
import org.toop.local.AppContext;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@@ -28,7 +28,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public final class Server {
|
||||
// TODO: Keep track of listeners. Remove them on Server connection close so reference is deleted.
|
||||
private String user = "";
|
||||
private long clientId = -1;
|
||||
|
||||
@@ -38,14 +37,10 @@ public final class Server {
|
||||
private ServerView primary;
|
||||
private boolean isPolling = true;
|
||||
|
||||
private AbstractGameController<?> gameController;
|
||||
|
||||
private final AtomicBoolean isSingleGame = new AtomicBoolean(false);
|
||||
|
||||
private ScheduledExecutorService scheduler;
|
||||
|
||||
private EventFlow eventFlow = new EventFlow();
|
||||
|
||||
public static GameInformation.Type gameToType(String game) {
|
||||
if (game.equalsIgnoreCase("tic-tac-toe")) {
|
||||
return GameInformation.Type.TICTACTOE;
|
||||
@@ -60,9 +55,6 @@ public final class Server {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Server has to deal with ALL network related listen events. This "server" can then interact with the manager to make stuff happen.
|
||||
// This prevents data races where events get sent to the game manager but the manager isn't ready yet.
|
||||
public Server(String ip, String port, String user) {
|
||||
if (ip.split("\\.").length < 4) {
|
||||
new ErrorPopup("\"" + ip + "\" " + AppContext.getString("is-not-a-valid-ip-address"));
|
||||
@@ -83,7 +75,17 @@ public final class Server {
|
||||
return;
|
||||
}
|
||||
|
||||
final int reconnectAttempts = 10;
|
||||
final int reconnectAttempts = 5;
|
||||
|
||||
LoadingWidget loading = new LoadingWidget(Primitive.text("connecting"), 0, reconnectAttempts);
|
||||
loading.setOnFailure(() -> {
|
||||
WidgetContainer.getCurrentView().transitionPrevious();
|
||||
WidgetContainer.add(Pos.CENTER, new ErrorPopup(AppContext.getString(
|
||||
"connecting-failed") + " " + ip + ":" + port)
|
||||
);
|
||||
});
|
||||
|
||||
WidgetContainer.getCurrentView().transitionNext(loading);
|
||||
|
||||
var a = new EventFlow()
|
||||
.addPostEvent(NetworkEvents.StartClient.class,
|
||||
@@ -93,6 +95,20 @@ public final class Server {
|
||||
|
||||
a.onResponse(NetworkEvents.StartClientResponse.class, e -> {
|
||||
|
||||
if (!e.successful()) {
|
||||
// loading.triggerFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(500); // TODO temp fix for index bug
|
||||
} catch (InterruptedException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
WidgetContainer.getCurrentView().transitionPrevious();
|
||||
|
||||
a.unsubscribe("connecting");
|
||||
a.unsubscribe("startclient");
|
||||
|
||||
this.user = user;
|
||||
@@ -103,18 +119,17 @@ public final class Server {
|
||||
primary = new ServerView(user, this::sendChallenge, this::disconnect);
|
||||
WidgetContainer.getCurrentView().transitionNext(primary);
|
||||
|
||||
startPopulateScheduler();
|
||||
populateGameList();
|
||||
startPopulateScheduler();
|
||||
populateGameList();
|
||||
}, false, "startclient")
|
||||
.listen(NetworkEvents.ConnectTry.class,
|
||||
e -> Platform.runLater(() ->
|
||||
loading.setAmount(e.amount())), false, "connecting")
|
||||
.postEvent();
|
||||
|
||||
}).postEvent();
|
||||
|
||||
eventFlow.listen(NetworkEvents.ChallengeResponse.class, this::handleReceivedChallenge, false)
|
||||
.listen(NetworkEvents.GameMatchResponse.class, this::handleMatchResponse, false)
|
||||
.listen(NetworkEvents.GameResultResponse.class, this::handleGameResult, false)
|
||||
.listen(NetworkEvents.GameMoveResponse.class, this::handleReceivedMove, false)
|
||||
.listen(NetworkEvents.YourTurnResponse.class, this::handleYourTurn, false);
|
||||
startPopulateScheduler();
|
||||
populateGameList();
|
||||
new EventFlow()
|
||||
.listen(NetworkEvents.ChallengeResponse.class, this::handleReceivedChallenge, false)
|
||||
.listen(NetworkEvents.GameMatchResponse.class, this::handleMatchResponse, false);
|
||||
}
|
||||
|
||||
private void sendChallenge(String opponent) {
|
||||
@@ -127,16 +142,10 @@ public final class Server {
|
||||
}
|
||||
|
||||
private void handleMatchResponse(NetworkEvents.GameMatchResponse response) {
|
||||
// TODO: Redo all of this mess
|
||||
if (gameController != null) {
|
||||
gameController.stop();
|
||||
}
|
||||
|
||||
gameController = null;
|
||||
|
||||
//if (!isPolling) return;
|
||||
if (!isPolling) return;
|
||||
|
||||
String gameType = extractQuotedValue(response.gameType());
|
||||
|
||||
if (response.clientId() == clientId) {
|
||||
isPolling = false;
|
||||
onlinePlayers.clear();
|
||||
@@ -157,58 +166,21 @@ public final class Server {
|
||||
information.players[0].computerThinkTime = 1;
|
||||
information.players[1].name = response.opponent();
|
||||
|
||||
AbstractPlayer[] players = new AbstractPlayer[2];
|
||||
|
||||
players[(myTurn + 1) % 2] = new OnlinePlayer(response.opponent());
|
||||
|
||||
switch (type){
|
||||
case TICTACTOE ->{
|
||||
players[myTurn] = new ArtificialPlayer<>(new TicTacToeAIR(), user);
|
||||
}
|
||||
case REVERSI ->{
|
||||
players[myTurn] = new ArtificialPlayer<>(new ReversiAIR(), user);
|
||||
}
|
||||
}
|
||||
|
||||
Runnable onGameOverRunnable = isSingleGame.get()? null: this::gameOver;
|
||||
|
||||
|
||||
switch (type) {
|
||||
case TICTACTOE ->{
|
||||
gameController = new TicTacToeController(players, false);
|
||||
}
|
||||
case TICTACTOE ->
|
||||
new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||
case REVERSI ->
|
||||
gameController = new ReversiController(players, false);
|
||||
new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||
case CONNECT4 ->
|
||||
new Connect4Game(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||
default -> new ErrorPopup("Unsupported game type.");
|
||||
}
|
||||
|
||||
if (gameController != null){
|
||||
gameController.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleYourTurn(NetworkEvents.YourTurnResponse response) {
|
||||
if (gameController == null) {
|
||||
return;
|
||||
}
|
||||
gameController.yourTurn(response);
|
||||
}
|
||||
|
||||
private void handleGameResult(NetworkEvents.GameResultResponse response) {
|
||||
if (gameController == null) {
|
||||
return;
|
||||
}
|
||||
gameController.gameFinished(response);
|
||||
}
|
||||
|
||||
private void handleReceivedMove(NetworkEvents.GameMoveResponse response) {
|
||||
if (gameController == null) {
|
||||
return;
|
||||
}
|
||||
gameController.moveReceived(response);
|
||||
}
|
||||
|
||||
private void handleReceivedChallenge(NetworkEvents.ChallengeResponse response) {
|
||||
if (!isPolling) return;
|
||||
|
||||
|
||||
@@ -3,25 +3,32 @@ package org.toop.app.widget.complex;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import org.toop.app.widget.Primitive;
|
||||
|
||||
public class LoadingWidget extends ViewWidget implements Update { // TODO make of widget type
|
||||
private final ProgressBar progressBar;
|
||||
private final Text loadingText;
|
||||
|
||||
private Runnable success = () -> {};
|
||||
private Runnable failure = () -> {};
|
||||
private boolean successTriggered = false;
|
||||
private boolean failureTriggered = false;
|
||||
private int maxAmount;
|
||||
private int amount;
|
||||
private float percentage = 0.0f;
|
||||
|
||||
|
||||
public LoadingWidget(int startAmount, int maxAmount) {
|
||||
public LoadingWidget(Text loadingText, int startAmount, int maxAmount) {
|
||||
|
||||
amount = startAmount;
|
||||
this.maxAmount = maxAmount;
|
||||
|
||||
progressBar = new ProgressBar();
|
||||
this.loadingText = loadingText;
|
||||
|
||||
HBox box = new HBox(10, progressBar);
|
||||
VBox box = Primitive.vbox(this.loadingText, progressBar);
|
||||
add(Pos.CENTER, box);
|
||||
}
|
||||
|
||||
@@ -47,24 +54,28 @@ public class LoadingWidget extends ViewWidget implements Update { // TODO make o
|
||||
}
|
||||
|
||||
public void triggerSuccess() {
|
||||
successTriggered = true; // TODO, else it will double call... why?
|
||||
success.run();
|
||||
}
|
||||
|
||||
public void triggerFailure() {
|
||||
failureTriggered = true; // TODO, else it will double call... why?
|
||||
failure.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (successTriggered || failureTriggered) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount >= maxAmount) {
|
||||
triggerSuccess();
|
||||
System.out.println("triggered");
|
||||
this.hide();
|
||||
this.remove(this);
|
||||
return;
|
||||
} else if (amount < 0) {
|
||||
triggerFailure();
|
||||
System.out.println("triggerFailure");
|
||||
this.hide();
|
||||
this.remove(this);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.toop.app.widget.view;
|
||||
import org.toop.app.Server;
|
||||
import org.toop.app.widget.Primitive;
|
||||
import org.toop.app.widget.complex.LabeledInputWidget;
|
||||
import org.toop.app.widget.complex.LoadingWidget;
|
||||
import org.toop.app.widget.complex.ViewWidget;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
|
||||
@@ -9,6 +9,8 @@ computer-difficulty=Computer difficulty
|
||||
computer-think-time=Computer think time
|
||||
computer=Computer
|
||||
connect=Connect
|
||||
connecting=Connecting to server...
|
||||
connecting-failed=Could not connect to server:
|
||||
credits=Credits
|
||||
dark=Dark
|
||||
deny=Deny
|
||||
|
||||
Reference in New Issue
Block a user