mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
Merge remote-tracking branch 'origin/Development' into Development
This commit is contained in:
@@ -1,10 +1,13 @@
|
|||||||
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.gameControllers.AbstractGameController;
|
import org.toop.app.game.ReversiGame;
|
||||||
import org.toop.app.game.gameControllers.ReversiController;
|
import org.toop.app.game.TicTacToeGame;
|
||||||
import org.toop.app.game.gameControllers.TicTacToeController;
|
import org.toop.app.widget.Primitive;
|
||||||
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;
|
||||||
@@ -13,11 +16,6 @@ import org.toop.framework.eventbus.EventFlow;
|
|||||||
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.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 org.toop.local.AppContext;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -28,7 +26,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public final class Server {
|
public final class Server {
|
||||||
// TODO: Keep track of listeners. Remove them on Server connection close so reference is deleted.
|
|
||||||
private String user = "";
|
private String user = "";
|
||||||
private long clientId = -1;
|
private long clientId = -1;
|
||||||
|
|
||||||
@@ -38,14 +35,10 @@ public final class Server {
|
|||||||
private ServerView primary;
|
private ServerView primary;
|
||||||
private boolean isPolling = true;
|
private boolean isPolling = true;
|
||||||
|
|
||||||
private AbstractGameController<?> gameController;
|
|
||||||
|
|
||||||
private final AtomicBoolean isSingleGame = new AtomicBoolean(false);
|
private final AtomicBoolean isSingleGame = new AtomicBoolean(false);
|
||||||
|
|
||||||
private ScheduledExecutorService scheduler;
|
private ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
private EventFlow eventFlow = new EventFlow();
|
|
||||||
|
|
||||||
public static GameInformation.Type gameToType(String game) {
|
public static GameInformation.Type gameToType(String game) {
|
||||||
if (game.equalsIgnoreCase("tic-tac-toe")) {
|
if (game.equalsIgnoreCase("tic-tac-toe")) {
|
||||||
return GameInformation.Type.TICTACTOE;
|
return GameInformation.Type.TICTACTOE;
|
||||||
@@ -60,9 +53,6 @@ public final class Server {
|
|||||||
return null;
|
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) {
|
public Server(String ip, String port, String user) {
|
||||||
if (ip.split("\\.").length < 4) {
|
if (ip.split("\\.").length < 4) {
|
||||||
new ErrorPopup("\"" + ip + "\" " + AppContext.getString("is-not-a-valid-ip-address"));
|
new ErrorPopup("\"" + ip + "\" " + AppContext.getString("is-not-a-valid-ip-address"));
|
||||||
@@ -83,7 +73,13 @@ public final class Server {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int reconnectAttempts = 10;
|
final int reconnectAttempts = 5;
|
||||||
|
|
||||||
|
LoadingWidget loading = new LoadingWidget(
|
||||||
|
Primitive.text("connecting"), 0, 0, reconnectAttempts
|
||||||
|
);
|
||||||
|
|
||||||
|
WidgetContainer.getCurrentView().transitionNext(loading);
|
||||||
|
|
||||||
var a = new EventFlow()
|
var a = new EventFlow()
|
||||||
.addPostEvent(NetworkEvents.StartClient.class,
|
.addPostEvent(NetworkEvents.StartClient.class,
|
||||||
@@ -91,8 +87,31 @@ public final class Server {
|
|||||||
new NetworkingConnector(ip, parsedPort, reconnectAttempts, 1, TimeUnit.SECONDS)
|
new NetworkingConnector(ip, parsedPort, reconnectAttempts, 1, TimeUnit.SECONDS)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
loading.setOnFailure(() -> {
|
||||||
|
WidgetContainer.getCurrentView().transitionPrevious();
|
||||||
|
a.unsubscribe("connecting");
|
||||||
|
WidgetContainer.add(
|
||||||
|
Pos.CENTER,
|
||||||
|
new ErrorPopup(AppContext.getString("connecting-failed") + " " + ip + ":" + port)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
a.onResponse(NetworkEvents.StartClientResponse.class, e -> {
|
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");
|
a.unsubscribe("startclient");
|
||||||
|
|
||||||
this.user = user;
|
this.user = user;
|
||||||
@@ -105,16 +124,25 @@ public final class Server {
|
|||||||
|
|
||||||
startPopulateScheduler();
|
startPopulateScheduler();
|
||||||
populateGameList();
|
populateGameList();
|
||||||
|
}, false, "startclient")
|
||||||
|
.listen(
|
||||||
|
NetworkEvents.ConnectTry.class,
|
||||||
|
e -> Platform.runLater(
|
||||||
|
() -> {
|
||||||
|
try {
|
||||||
|
loading.setAmount(e.amount());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
false, "connecting"
|
||||||
|
)
|
||||||
|
.postEvent();
|
||||||
|
|
||||||
}).postEvent();
|
new EventFlow()
|
||||||
|
.listen(NetworkEvents.ChallengeResponse.class, this::handleReceivedChallenge, false)
|
||||||
eventFlow.listen(NetworkEvents.ChallengeResponse.class, this::handleReceivedChallenge, false)
|
.listen(NetworkEvents.GameMatchResponse.class, this::handleMatchResponse, 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendChallenge(String opponent) {
|
private void sendChallenge(String opponent) {
|
||||||
@@ -127,16 +155,10 @@ public final class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleMatchResponse(NetworkEvents.GameMatchResponse response) {
|
private void handleMatchResponse(NetworkEvents.GameMatchResponse response) {
|
||||||
// TODO: Redo all of this mess
|
if (!isPolling) return;
|
||||||
if (gameController != null) {
|
|
||||||
gameController.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
gameController = null;
|
|
||||||
|
|
||||||
//if (!isPolling) return;
|
|
||||||
|
|
||||||
String gameType = extractQuotedValue(response.gameType());
|
String gameType = extractQuotedValue(response.gameType());
|
||||||
|
|
||||||
if (response.clientId() == clientId) {
|
if (response.clientId() == clientId) {
|
||||||
isPolling = false;
|
isPolling = false;
|
||||||
onlinePlayers.clear();
|
onlinePlayers.clear();
|
||||||
@@ -157,57 +179,20 @@ public final class Server {
|
|||||||
information.players[0].computerThinkTime = 1;
|
information.players[0].computerThinkTime = 1;
|
||||||
information.players[1].name = response.opponent();
|
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;
|
Runnable onGameOverRunnable = isSingleGame.get()? null: this::gameOver;
|
||||||
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TICTACTOE ->{
|
case TICTACTOE ->
|
||||||
gameController = new TicTacToeController(players, false);
|
new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||||
}
|
|
||||||
case REVERSI ->
|
case REVERSI ->
|
||||||
gameController = new ReversiController(players, false);
|
new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||||
case CONNECT4 ->
|
case CONNECT4 ->
|
||||||
new Connect4Game(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
new Connect4Game(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage, onGameOverRunnable);
|
||||||
default -> new ErrorPopup("Unsupported game type.");
|
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) {
|
private void handleReceivedChallenge(NetworkEvents.ChallengeResponse response) {
|
||||||
if (!isPolling) return;
|
if (!isPolling) return;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.toop.app.widget;
|
package org.toop.app.widget;
|
||||||
|
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
|
import org.toop.framework.audio.events.AudioEvents;
|
||||||
|
import org.toop.framework.eventbus.EventFlow;
|
||||||
import org.toop.framework.resource.resources.ImageAsset;
|
import org.toop.framework.resource.resources.ImageAsset;
|
||||||
import org.toop.local.AppContext;
|
import org.toop.local.AppContext;
|
||||||
|
|
||||||
@@ -73,8 +75,11 @@ public final class Primitive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (onAction != null) {
|
if (onAction != null) {
|
||||||
button.setOnAction(_ ->
|
button.setOnAction(_ -> {
|
||||||
onAction.run());
|
onAction.run();
|
||||||
|
playButtonSound();
|
||||||
|
System.out.println("HI I got called button");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
@@ -116,10 +121,16 @@ public final class Primitive {
|
|||||||
slider.setValue(value);
|
slider.setValue(value);
|
||||||
|
|
||||||
if (onValueChanged != null) {
|
if (onValueChanged != null) {
|
||||||
slider.valueProperty().addListener((_, _, newValue) ->
|
slider.valueProperty().addListener((_, _, newValue) -> {
|
||||||
onValueChanged.accept(newValue.intValue()));
|
onValueChanged.accept(newValue.intValue());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slider.setOnMouseReleased(event -> {
|
||||||
|
playButtonSound();
|
||||||
|
System.out.println("I got called!");
|
||||||
|
});
|
||||||
|
|
||||||
return slider;
|
return slider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,8 +148,11 @@ public final class Primitive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (onValueChanged != null) {
|
if (onValueChanged != null) {
|
||||||
choice.valueProperty().addListener((_, _, newValue) ->
|
choice.valueProperty().addListener((_, _, newValue) -> {
|
||||||
onValueChanged.accept(newValue));
|
onValueChanged.accept(newValue);
|
||||||
|
playButtonSound();
|
||||||
|
System.out.println("hi i got called choice");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
choice.setItems(FXCollections.observableArrayList(items));
|
choice.setItems(FXCollections.observableArrayList(items));
|
||||||
@@ -191,4 +205,8 @@ public final class Primitive {
|
|||||||
|
|
||||||
return vbox;
|
return vbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void playButtonSound() {
|
||||||
|
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).postEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,26 +2,45 @@ package org.toop.app.widget.complex;
|
|||||||
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.ProgressBar;
|
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;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
public class LoadingWidget extends ViewWidget implements Update { // TODO make of widget type
|
public class LoadingWidget extends ViewWidget implements Update { // TODO make of widget type
|
||||||
private final ProgressBar progressBar;
|
private final ProgressBar progressBar;
|
||||||
|
private final Text loadingText;
|
||||||
|
|
||||||
private Runnable success = () -> {};
|
private Runnable success = () -> {};
|
||||||
private Runnable failure = () -> {};
|
private Runnable failure = () -> {};
|
||||||
|
private boolean successTriggered = false;
|
||||||
|
private boolean failureTriggered = false;
|
||||||
private int maxAmount;
|
private int maxAmount;
|
||||||
|
private int minAmount;
|
||||||
private int amount;
|
private int amount;
|
||||||
|
private Callable<Boolean> successTrigger = () -> (amount >= maxAmount);
|
||||||
|
private Callable<Boolean> failureTrigger = () -> (amount < minAmount);
|
||||||
private float percentage = 0.0f;
|
private float percentage = 0.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
public LoadingWidget(int startAmount, int maxAmount) {
|
*
|
||||||
|
* Widget that shows a loading bar.
|
||||||
amount = startAmount;
|
*
|
||||||
|
* @param loadingText Text above the loading bar.
|
||||||
|
* @param minAmount The minimum amount.
|
||||||
|
* @param startAmount The starting amount.
|
||||||
|
* @param maxAmount The max amount.
|
||||||
|
*/
|
||||||
|
public LoadingWidget(Text loadingText, int minAmount, int startAmount, int maxAmount) {
|
||||||
this.maxAmount = maxAmount;
|
this.maxAmount = maxAmount;
|
||||||
|
this.minAmount = minAmount;
|
||||||
|
amount = startAmount;
|
||||||
|
|
||||||
progressBar = new ProgressBar();
|
progressBar = new ProgressBar();
|
||||||
|
this.loadingText = loadingText;
|
||||||
|
|
||||||
HBox box = new HBox(10, progressBar);
|
VBox box = Primitive.vbox(this.loadingText, progressBar);
|
||||||
add(Pos.CENTER, box);
|
add(Pos.CENTER, box);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,42 +48,88 @@ public class LoadingWidget extends ViewWidget implements Update { // TODO make o
|
|||||||
this.maxAmount = maxAmount;
|
this.maxAmount = maxAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmount(int amount) {
|
public void setAmount(int amount) throws Exception {
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmount() {
|
public int getMaxAmount() {
|
||||||
setAmount(this.amount+1);
|
return maxAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPercentage() {
|
||||||
|
return percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTriggered() {
|
||||||
|
return (failureTriggered || successTriggered);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What to do when success is triggered.
|
||||||
|
* @param onSuccess The lambda that gets run on success.
|
||||||
|
*/
|
||||||
public void setOnSuccess(Runnable onSuccess) {
|
public void setOnSuccess(Runnable onSuccess) {
|
||||||
success = onSuccess;
|
success = onSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What to do when failure is triggered.
|
||||||
|
* @param onFailure The lambda that gets run on failure.
|
||||||
|
*/
|
||||||
public void setOnFailure(Runnable onFailure) {
|
public void setOnFailure(Runnable onFailure) {
|
||||||
failure = onFailure;
|
failure = onFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The trigger to activate onSuccess.
|
||||||
|
* @param trigger The lambda that triggers onSuccess.
|
||||||
|
*/
|
||||||
|
public void setSuccessTrigger(Callable<Boolean> trigger) {
|
||||||
|
successTrigger = trigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The trigger to activate onFailure.
|
||||||
|
* @param trigger The lambda that triggers onFailure.
|
||||||
|
*/
|
||||||
|
public void setFailureTrigger(Callable<Boolean> trigger) {
|
||||||
|
failureTrigger = trigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forcefully trigger success.
|
||||||
|
*/
|
||||||
public void triggerSuccess() {
|
public void triggerSuccess() {
|
||||||
|
successTriggered = true; // TODO, else it will double call... why?
|
||||||
success.run();
|
success.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forcefully trigger failure.
|
||||||
|
*/
|
||||||
public void triggerFailure() {
|
public void triggerFailure() {
|
||||||
|
failureTriggered = true; // TODO, else it will double call... why?
|
||||||
failure.run();
|
failure.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() throws Exception { // TODO Better exception
|
||||||
if (amount >= maxAmount) {
|
if (successTriggered || failureTriggered) { // If already triggered, throw exception.
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (successTrigger.call()) {
|
||||||
triggerSuccess();
|
triggerSuccess();
|
||||||
System.out.println("triggered");
|
this.remove(this);
|
||||||
this.hide();
|
|
||||||
return;
|
return;
|
||||||
} else if (amount < 0) {
|
} else if (failureTrigger.call()) {
|
||||||
triggerFailure();
|
triggerFailure();
|
||||||
System.out.println("triggerFailure");
|
this.remove(this);
|
||||||
this.hide();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package org.toop.app.widget.complex;
|
|||||||
|
|
||||||
import org.toop.app.widget.Primitive;
|
import org.toop.app.widget.Primitive;
|
||||||
import org.toop.app.widget.Widget;
|
import org.toop.app.widget.Widget;
|
||||||
|
import org.toop.framework.audio.events.AudioEvents;
|
||||||
|
import org.toop.framework.eventbus.EventFlow;
|
||||||
import org.toop.local.AppContext;
|
import org.toop.local.AppContext;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -30,6 +32,7 @@ public class ToggleWidget implements Widget {
|
|||||||
updateText();
|
updateText();
|
||||||
if (onToggle != null) {
|
if (onToggle != null) {
|
||||||
onToggle.accept(state);
|
onToggle.accept(state);
|
||||||
|
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).postEvent(); // TODO FIX PRIMITIVES
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package org.toop.app.widget.complex;
|
package org.toop.app.widget.complex;
|
||||||
|
|
||||||
public interface Update {
|
public interface Update {
|
||||||
void update();
|
void update() throws Exception;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.toop.app.widget.view;
|
|||||||
import org.toop.app.Server;
|
import org.toop.app.Server;
|
||||||
import org.toop.app.widget.Primitive;
|
import org.toop.app.widget.Primitive;
|
||||||
import org.toop.app.widget.complex.LabeledInputWidget;
|
import org.toop.app.widget.complex.LabeledInputWidget;
|
||||||
|
import org.toop.app.widget.complex.LoadingWidget;
|
||||||
import org.toop.app.widget.complex.ViewWidget;
|
import org.toop.app.widget.complex.ViewWidget;
|
||||||
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ computer-difficulty=Computer difficulty
|
|||||||
computer-think-time=Computer think time
|
computer-think-time=Computer think time
|
||||||
computer=Computer
|
computer=Computer
|
||||||
connect=Connect
|
connect=Connect
|
||||||
|
connecting=Connecting to server...
|
||||||
|
connecting-failed=Could not connect to server:
|
||||||
credits=Credits
|
credits=Credits
|
||||||
dark=Dark
|
dark=Dark
|
||||||
deny=Deny
|
deny=Deny
|
||||||
|
|||||||
Reference in New Issue
Block a user