# HG changeset patch # User Jaroslav Tulach # Date 1380059552 -7200 # Node ID 6bb4070d2c20ffbdb33c1797143ec5cbca635680 # Parent 3f1866fdb2a1b19450bd5450d27bf3f7616b152e Removing the server communication stuff diff -r 3f1866fdb2a1 -r 6bb4070d2c20 chess/src/main/java/org/apidesign/html/demo/chess/BoardModel.java --- a/chess/src/main/java/org/apidesign/html/demo/chess/BoardModel.java Tue Sep 24 22:37:17 2013 +0200 +++ b/chess/src/main/java/org/apidesign/html/demo/chess/BoardModel.java Tue Sep 24 23:52:32 2013 +0200 @@ -35,14 +35,12 @@ import net.java.html.json.OnPropertyChange; import net.java.html.json.Property; import net.java.html.sound.AudioClip; -import org.apidesign.html.demo.chess.Communication.AlertType; @Model(className="Board", properties={ @Property(name = "player", type = String.class), @Property(name = "gameId", type = String.class), @Property(name = "whitePlayer", type = String.class), @Property(name = "blackPlayer", type = String.class), - @Property(name = "alert", type = Alert.class), @Property(name = "alertMessage", type = String.class), @Property(name = "status", type = String.class), @Property(name = "rows", type = Row.class, array = true), @@ -85,17 +83,6 @@ private static final AudioClip CHECK = AudioClip.create("sounds/check.mp3"); private static final AudioClip CHECKMATE = AudioClip.create("sounds/checkmate.mp3"); - @OnPropertyChange("alert") static void warnCheckAndMate(Board b) { - if (b.getAlert() == null) { - return; - } - if (b.getAlert().getType() == AlertType.CHECK) { - CHECK.play(); - } - if (b.getAlert().getType() == AlertType.CHECKMATE) { - CHECKMATE.play(); - } - } @Function static void selected(Board b, Square data) { if (!b.isMyTurn()) { @@ -141,17 +128,6 @@ previoslySelected.setPiece(null); previoslySelected.setPieceColor(null); Rules.computeAccessible(b, null); - - Request sm = new Request(); - sm.setMsg(MsgType.SendMove); - sm.setGameId(b.getGameId()); - sm.setFrom(newMove.getFrom().getLocation()); - sm.setTo(newMove.getTo().getLocation()); - sm.setColor(newMove.getTurn()); - final UI ui = UIModel.findUI(b); - if (ui != null) { - ui.sendMsg(sm); - } } } } @@ -259,8 +235,10 @@ return null; } - static void moveResponse(final Board b, final String errMsg, final List whites, final List blacks, final Color turn, - Alert alert + static void moveResponse( + final Board b, final String errMsg, + final List whites, final List blacks, + final Color turn, Object alert ) { if (errMsg != null) { b.getMoves().remove(b.getPendingMove()); @@ -270,11 +248,14 @@ b.setTurn(turn); b.setAlertMessage(null); } - b.setAlert(alert); Rules.initBoard(b, whites, blacks, turn); } - static void moveUpdate(final Board b, final Move move, final List whites, final List blacks, final Color turn, Alert alert) { + static void moveUpdate( + final Board b, final Move move, + final List whites, final List blacks, + final Color turn, Object alert + ) { final Square from = BoardModel.findSquare(b, move.getFrom()); final Square to = BoardModel.findSquare(b, move.getTo()); move.setPiece(from.getPiece()); @@ -282,8 +263,6 @@ if (to.getPiece() != null) { move.setTakes(true); } - b.setAlert(alert); - b.setAlertMessage(alert == null ? null : alert.getMessage()); move.setRound(b.getMoves().size() / 2 + 1); b.getMoves().add(move); Rules.initBoard(b, whites, blacks, turn); diff -r 3f1866fdb2a1 -r 6bb4070d2c20 chess/src/main/java/org/apidesign/html/demo/chess/Communication.java --- a/chess/src/main/java/org/apidesign/html/demo/chess/Communication.java Tue Sep 24 22:37:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (C) 2013 Jaroslav Tulach - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.apidesign.html.demo.chess; - -import net.java.html.json.ComputedProperty; -import net.java.html.json.Model; -import net.java.html.json.Property; - - -/** Communication protocols to talk to the server. - * - * @author Jaroslav Tulach - */ -final class Communication { - @Model(className = "Request", properties = { - @Property(name = "msg", type = MsgType.class), - @Property(name = "username", type = String.class), - @Property(name = "password", type = String.class), - @Property(name = "gameId", type = String.class), - @Property(name = "color", type = Color.class), - @Property(name = "from", type = String.class), - @Property(name = "to", type = String.class), - @Property(name = "observer", type = boolean.class), - }) - static class RequestModel { - } - - @Model(className = "BoardRep", properties = { - @Property(name = "whites", type = String.class, array = true), - @Property(name = "blacks", type = String.class, array = true), - }) - static class BoardRepModel { - } - - @Model(className = "Response", properties = { - @Property(name = "msg", type = String.class), - @Property(name = "games", array = true, type = Game.class), - @Property(name = "board", type = BoardRep.class), - @Property(name = "turn", type = Color.class), - @Property(name = "color", type = Color.class), - @Property(name = "gameId", type = String.class), - @Property(name = "error", type = Err.class), - @Property(name = "alert", type = Alert.class), - @Property(name = "status", type = String.class), - @Property(name = "summary", type = String.class), - @Property(name = "moves", type = String.class, array = true), - @Property(name = "from", type = String.class), - @Property(name = "to", type = String.class), - @Property(name = "check", type = CheckResult.class), - @Property(name = "whitePlayer", type = String.class), - @Property(name = "blackPlayer", type = String.class), - }) - static class ResponseModel { - @ComputedProperty static Color nextTurn(Color turn, Alert alert) { - if (alert == null || !alert.getType().isTerminal()) { - return turn; - } else { - return null; - } - } - } - - static enum CheckResult { - VALID, INVALID, NOT_REGISTERED - }; - - @Model(className = "Err", properties = { - @Property(name = "code", type = int.class), - @Property(name = "message", type = String.class), - }) - static class ErrorModel { - } - - @Model(className = "Alert", properties = { - @Property(name = "type", type = AlertType.class), - @Property(name = "message", type = String.class), - }) - static class AlertModel { - } - - static enum AlertType { - CHECKMATE, CHECK, DRAW; - - public boolean isTerminal() { - return this == CHECKMATE || this == DRAW; - } - }; - -} diff -r 3f1866fdb2a1 -r 6bb4070d2c20 chess/src/main/java/org/apidesign/html/demo/chess/GamesModel.java --- a/chess/src/main/java/org/apidesign/html/demo/chess/GamesModel.java Tue Sep 24 22:37:17 2013 +0200 +++ b/chess/src/main/java/org/apidesign/html/demo/chess/GamesModel.java Tue Sep 24 23:52:32 2013 +0200 @@ -23,10 +23,8 @@ */ package org.apidesign.html.demo.chess; -import java.util.List; import net.java.html.json.ComputedProperty; import net.java.html.json.Model; -import net.java.html.json.ModelOperation; import net.java.html.json.Property; /** @@ -34,53 +32,15 @@ * @author Jaroslav Tulach */ @Model(className = "Games", properties = { - @Property(name = "own", array = true, type = Game.class), - @Property(name = "other", array = true, type = Game.class), + @Property(name = "whitePlayer", type = String.class), + @Property(name = "blackPlayer", type = String.class), @Property(name = "selectedColor", type = String.class), }) class GamesModel { - @Model(className = "Game", properties = { - @Property(name = "gameId", type=String.class), - @Property(name = "summary", type=String.class), - @Property(name = "open", type=boolean.class), - @Property(name = "whitePlayer", type=String.class), - @Property(name = "blackPlayer", type=String.class) - }) - static class GameImpl { - @ComputedProperty static String description(String gameId, String summary) { - return summary != null ? summary : gameId; - } - - @ComputedProperty static boolean pendingPlayer(String whitePlayer, String blackPlayer) { - return whitePlayer == null || blackPlayer == null; - } - } - - - @ComputedProperty static boolean anyOwnGame(List own) { - return !own.isEmpty(); - } - - @ComputedProperty static boolean anyOtherGame(List other) { - return !other.isEmpty(); - } - - @ModelOperation static void listGames(Games g, List games, String username) { - g.getOwn().clear(); - g.getOther().clear(); - int cnt = 0; - final int maxGames = 30; - for (Game game : games) { - if ( - username.equals(game.getWhitePlayer()) || - username.equals(game.getBlackPlayer()) - ) { - g.getOwn().add(game); - } else { - if (cnt++ < maxGames) { - g.getOther().add(game); - } - } - } + @ComputedProperty static boolean correctNames( + String whitePlayer, String blackPlayer + ) { + return whitePlayer != null && blackPlayer != null && !whitePlayer.isEmpty() && + !blackPlayer.isEmpty(); } } diff -r 3f1866fdb2a1 -r 6bb4070d2c20 chess/src/main/java/org/apidesign/html/demo/chess/SettingsModel.java --- a/chess/src/main/java/org/apidesign/html/demo/chess/SettingsModel.java Tue Sep 24 22:37:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (C) 2013 Jaroslav Tulach - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.apidesign.html.demo.chess; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Properties; -import net.java.html.json.ComputedProperty; -import net.java.html.json.Model; -import net.java.html.json.ModelOperation; -import net.java.html.json.Property; - -/** - * - * @author Jaroslav Tulach - */ -@Model(className = "Settings", properties = { - @Property(name = "username", type = String.class), - @Property(name = "password", type = String.class), - @Property(name = "url", type = String.class), -}) -class SettingsModel { - private static final String SETTINGS = ".j1chess/html.properties"; - private static final String DEFAULT_URL = "ws://localhost:8080/chess/chessserver"; - - @ComputedProperty static boolean validCredentials(String username, String password) { - return username != null && password != null && !username.isEmpty() && !password.isEmpty(); - } - - @ModelOperation static void read(Settings s) { - File prefs = new File(System.getProperty("user.home"), SETTINGS); - try (FileInputStream is = new FileInputStream(prefs)) { - Properties p = new Properties(); - p.load(is); - - s.setUsername(p.getProperty("username", "")); - s.setPassword(p.getProperty("password", "")); - s.setUrl(p.getProperty("url", DEFAULT_URL)); - } catch (Throwable ex) { - s.setUsername(""); - s.setPassword(""); - s.setUrl(DEFAULT_URL); - } - } - - @ModelOperation static void write(Settings s, UI ui) { - File prefs = new File(System.getProperty("user.home"), SETTINGS); - prefs.getParentFile().mkdirs(); - try (FileOutputStream os = new FileOutputStream(prefs)) { - Properties p = new Properties(); - p.setProperty("username", s.getUsername()); - p.setProperty("password", s.getPassword()); - p.setProperty("url", s.getUrl()); - p.store(os, "Java One Chess Preferences for HTML/Java Client"); - } catch (Throwable ex) { - ui.setStatus("Cannot save preferences: " + ex.getMessage()); - } - } -} diff -r 3f1866fdb2a1 -r 6bb4070d2c20 chess/src/main/java/org/apidesign/html/demo/chess/UIModel.java --- a/chess/src/main/java/org/apidesign/html/demo/chess/UIModel.java Tue Sep 24 22:37:17 2013 +0200 +++ b/chess/src/main/java/org/apidesign/html/demo/chess/UIModel.java Tue Sep 24 23:52:32 2013 +0200 @@ -25,17 +25,11 @@ import java.io.IOException; import java.net.URISyntaxException; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.logging.Level; import java.util.logging.Logger; import net.java.html.json.ComputedProperty; import net.java.html.json.Function; import net.java.html.json.Model; -import net.java.html.json.ModelOperation; -import net.java.html.json.OnPropertyChange; -import net.java.html.json.OnReceive; import net.java.html.json.Property; /** @@ -47,21 +41,14 @@ @Property(name = "selectedGameId", type = String.class), @Property(name = "boards", type = Board.class, array = true), @Property(name = "viewGames", type = Games.class), - @Property(name = "settings", type = Settings.class), - @Property(name = "connected", type = boolean.class), - @Property(name = "disconnected", type = boolean.class), }) public class UIModel { private static final Logger LOG = Logger.getLogger(UIModel.class.getName()); - @ComputedProperty static boolean settingsActive(String selectedGameId) { + @ComputedProperty static boolean viewGamesActive(String selectedGameId) { return selectedGameId == null; } - @ComputedProperty static boolean viewGamesActive(String selectedGameId, boolean connected) { - return selectedGameId == null && connected; - } - @ComputedProperty static Board selectedBoard(String selectedGameId, List boards) { Board active = null; for (Board b : boards) { @@ -80,149 +67,26 @@ @Function static void activateSettings(UI m) { m.setSelectedGameId(null); - refreshGames(m); } + private static int boardCnt; + @Function static void createGame(UI u) { - u.setStatus("Creating new game..."); - Request r = new Request(); - r.setMsg(MsgType.CreateGame); - r.setColor(Color.valueOf(u.getViewGames().getSelectedColor())); - u.sendMsg(r); + Board b = Rules.createBoard(); + b.setGameId("id" + ++boardCnt); + final String wp = u.getViewGames().getWhitePlayer(); + b.setWhitePlayer(wp); + final String bp = u.getViewGames().getBlackPlayer(); + b.setBlackPlayer(bp); + b.setStatus(wp + " vs. " + bp); + u.getBoards().add(b); + u.setSelectedGameId(b.getGameId()); + + u.getViewGames().setWhitePlayer(null); + u.getViewGames().setBlackPlayer(null); } - @ModelOperation @Function static void refreshGames(UI u) { - u.setStatus("Refreshing games..."); - Request r = new Request(); - r.setMsg(MsgType.QueryGames); - u.sendMsg(r); - } - @ModelOperation static void sendMsg(UI ui, Request r) { - final Settings sttngs = ui.getSettings(); - - String url = sttngs.getUrl(); - r.setUsername(sttngs.getUsername()); - r.setPassword(sttngs.getPassword()); - - LOG.log(Level.INFO, "Sending {0} to {1}", new Object[]{r, url}); - ui.queryServer(url, r); - } - - - @OnReceive(data = Request.class, url = "{url}", method = "WebSocket", onError = "wasAnError") - static void queryServer(UI ui, Response r) { - LOG.log(Level.INFO, "Received {0}", r); - if (r == null) { - ui.setDisconnected(false); - verifyLogin(ui); - return; - } - SWITCH: switch (MsgType.forResponse(r.getMsg())) { - case CheckCredentials: { - switch (r.getCheck()) { - case NOT_REGISTERED: - case VALID: - ui.setConnected(true); - ui.refreshGames(); - ui.setStatus("Connected."); - return; - case INVALID: - ui.setStatus("Password is invalid"); - break; - } - disconnect(ui); - } - - case QueryGames: - ui.getViewGames().listGames(r.getGames(), ui.getSettings().getUsername()); - ui.setStatus(""); - break; - case CreateGame: { - ui.setStatus("Game " + r + " created"); - final Board b = Rules.createBoard(); - Rules.initBoard( - b, r.getBoard().getWhites(), - r.getBoard().getBlacks(), - r.getTurn() - ); - b.setGameId(r.getGameId()); - b.setWhitePlayer(r.getWhitePlayer()); - b.setBlackPlayer(r.getBlackPlayer()); - b.setPlayer(ui.getSettings().getUsername()); - b.updateSummary(r.getSummary()); - ui.getBoards().add(b); - ui.setSelectedGameId(r.getGameId()); - UIModel.refreshGames(ui); - break; - } - case SendMove: { - if (r.getBoard() == null) { - throw new NullPointerException("No board in " + r); - } - final Board b = findBoard(ui, r.getGameId()); - if (b == null) { - break; - } - b.updateSummary(r.getSummary()); - final String errMsg = r.getError() == null ? null : r.getError().getMessage(); - final List whites = r.getBoard().getWhites(); - final List blacks = r.getBoard().getBlacks(); - final Color turn = r.getNextTurn(); - BoardModel.moveResponse(b, errMsg, whites, blacks, turn, r.getAlert()); - break; - } - case JoinGame: { - Board b; - if ((b = findBoard(ui, r.getGameId())) != null) { - b.setWhitePlayer(r.getWhitePlayer()); - b.setBlackPlayer(r.getBlackPlayer()); - b.setPlayer(ui.getSettings().getUsername()); - b.updateSummary(r.getSummary()); - ui.setSelectedGameId(r.getGameId()); - break SWITCH; - } - ui.setStatus("Joining " + r.getGameId() + " as " + r.getColor()); - b = Rules.createBoard(); - Rules.initBoard( - b, r.getBoard().getWhites(), - r.getBoard().getBlacks(), - r.getTurn() - ); - b.setGameId(r.getGameId()); - b.setWhitePlayer(r.getWhitePlayer()); - b.setBlackPlayer(r.getBlackPlayer()); - b.setPlayer(ui.getSettings().getUsername()); - b.updateSummary(r.getSummary()); - if (r.getColor() == Color.B) { - BoardModel.rotateBoard(b); - } - if (r.getMoves() != null) { - for (String move : r.getMoves()) { - Move m = BoardModel.MoveImpl.valueOf(move); - b.getMoves().add(m); - } - } else { - b.getMoves().clear(); - } - ui.setSelectedGameId(b.getGameId()); - ui.getBoards().add(b); - break; - } - case UpdateGame: { - final Board b = findBoard(ui, r.getGameId()); - if (b == null) { - break; - } - b.updateSummary(r.getSummary()); - final Move move = BoardModel.MoveImpl.valueOf(r.getFrom() + r.getTo()); - final List whites = r.getBoard().getWhites(); - final List blacks = r.getBoard().getBlacks(); - final Color turn = r.getNextTurn(); - BoardModel.moveUpdate(b, move, whites, blacks, turn, null); - } - } - } private static Board findBoard(UI ui, String gameId) { @@ -235,80 +99,17 @@ } - static void wasAnError(UI ui, Exception t) { - if (t == null) { - ui.setConnected(false); - ui.setDisconnected(true); - ui.setStatus("Disconnected."); - } else { - ui.setStatus("Error: " + t.getLocalizedMessage()); - } - } - - @Function static void joinGame(UI u, Game data) { - Request r = new Request(); - r.setMsg(MsgType.JoinGame); - r.setObserver(false); - r.setGameId(data.getGameId()); - u.sendMsg(r); + @Function static void joinGame(UI u) { } - @Function static void observeGame(UI u, Game data) { - Request r = new Request(); - r.setMsg(MsgType.JoinGame); - r.setObserver(true); - r.setGameId(data.getGameId()); - u.sendMsg(r); - } - - private static final Set ACTIVE = new HashSet<>(); - @OnPropertyChange("connected") static void clearGames(UI m) { - if (m.isDisconnected()) { - m.getBoards().clear(); - ACTIVE.remove(m); - } else { - ACTIVE.add(m); - } - } - - static UI findUI(Board b) { - for (UI ui : ACTIVE) { - if (ui.getBoards().contains(b)) { - return ui; - } - } - return null; - } - @Function static void leave(UI ui, Board data) { ui.getBoards().remove(data); ui.setSelectedGameId(null); } - @Function static void disconnect(UI ui) { - ui.queryServer(ui.getSettings().getUrl(), null); - ui.setStatus("Disconnecting..."); - } - - private static void verifyLogin(UI ui) { - ui.setStatus("Verifying user credentials..."); - Request r = new Request(); - r.setMsg(MsgType.CheckCredentials); - ui.sendMsg(r); - } - - @Function static void reconnect(UI ui) { - final Settings s = ui.getSettings(); - ui.setStatus("Connecting to the server..."); - ui.queryServer(s.getUrl(), null); - s.write(ui); - } - public static void initialize(String... args) throws URISyntaxException, IOException { UI ui = new UI(); - ui.getSettings().read(); ui.setStatus("Ready."); - ui.setDisconnected(true); ui.applyBindings(); } diff -r 3f1866fdb2a1 -r 6bb4070d2c20 chess/src/main/webapp/pages/index.html --- a/chess/src/main/webapp/pages/index.html Tue Sep 24 22:37:17 2013 +0200 +++ b/chess/src/main/webapp/pages/index.html Tue Sep 24 23:52:32 2013 +0200 @@ -47,7 +47,7 @@ -
-
+
- - -
Loading...

Initializing the virtual machine...

@@ -204,7 +165,7 @@