jaroslav@49
|
1 |
/**
|
jaroslav@49
|
2 |
* The MIT License (MIT)
|
jaroslav@49
|
3 |
*
|
jaroslav@49
|
4 |
* Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
|
jaroslav@49
|
5 |
*
|
jaroslav@49
|
6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
jaroslav@49
|
7 |
* of this software and associated documentation files (the "Software"), to deal
|
jaroslav@49
|
8 |
* in the Software without restriction, including without limitation the rights
|
jaroslav@49
|
9 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
jaroslav@49
|
10 |
* copies of the Software, and to permit persons to whom the Software is
|
jaroslav@49
|
11 |
* furnished to do so, subject to the following conditions:
|
jaroslav@49
|
12 |
*
|
jaroslav@49
|
13 |
* The above copyright notice and this permission notice shall be included in
|
jaroslav@49
|
14 |
* all copies or substantial portions of the Software.
|
jaroslav@49
|
15 |
*
|
jaroslav@49
|
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
jaroslav@49
|
17 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
jaroslav@49
|
18 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
jaroslav@49
|
19 |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
jaroslav@49
|
20 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
jaroslav@49
|
21 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
jaroslav@49
|
22 |
* THE SOFTWARE.
|
jaroslav@49
|
23 |
*/
|
jaroslav@49
|
24 |
package com.oracle.chess.client.htmljava;
|
jaroslav@49
|
25 |
|
jaroslav@49
|
26 |
import java.io.IOException;
|
jaroslav@49
|
27 |
import java.net.URISyntaxException;
|
jaroslav@49
|
28 |
import java.util.HashSet;
|
jaroslav@49
|
29 |
import java.util.List;
|
jaroslav@49
|
30 |
import java.util.Set;
|
jaroslav@49
|
31 |
import java.util.logging.Level;
|
jaroslav@49
|
32 |
import java.util.logging.Logger;
|
jaroslav@49
|
33 |
import net.java.html.json.ComputedProperty;
|
jaroslav@49
|
34 |
import net.java.html.json.Function;
|
jaroslav@49
|
35 |
import net.java.html.json.Model;
|
jaroslav@49
|
36 |
import net.java.html.json.ModelOperation;
|
jaroslav@49
|
37 |
import net.java.html.json.OnPropertyChange;
|
jaroslav@49
|
38 |
import net.java.html.json.OnReceive;
|
jaroslav@49
|
39 |
import net.java.html.json.Property;
|
jaroslav@49
|
40 |
|
jaroslav@49
|
41 |
/**
|
jaroslav@49
|
42 |
*
|
jaroslav@49
|
43 |
* @author Jaroslav Tulach <jtulach@netbeans.org>
|
jaroslav@49
|
44 |
*/
|
jaroslav@49
|
45 |
@Model(className = "UI", properties = {
|
jaroslav@49
|
46 |
@Property(name = "status", type = String.class),
|
jaroslav@49
|
47 |
@Property(name = "selectedGameId", type = String.class),
|
jaroslav@49
|
48 |
@Property(name = "boards", type = Board.class, array = true),
|
jaroslav@49
|
49 |
@Property(name = "viewGames", type = Games.class),
|
jaroslav@49
|
50 |
@Property(name = "settings", type = Settings.class),
|
jaroslav@49
|
51 |
@Property(name = "connected", type = boolean.class),
|
jaroslav@49
|
52 |
@Property(name = "disconnected", type = boolean.class),
|
jaroslav@49
|
53 |
})
|
jaroslav@49
|
54 |
public class UIModel {
|
jaroslav@49
|
55 |
private static final Logger LOG = Logger.getLogger(UIModel.class.getName());
|
jaroslav@49
|
56 |
|
jaroslav@49
|
57 |
@ComputedProperty static boolean settingsActive(String selectedGameId) {
|
jaroslav@49
|
58 |
return selectedGameId == null;
|
jaroslav@49
|
59 |
}
|
jaroslav@49
|
60 |
|
jaroslav@49
|
61 |
@ComputedProperty static boolean viewGamesActive(String selectedGameId, boolean connected) {
|
jaroslav@49
|
62 |
return selectedGameId == null && connected;
|
jaroslav@49
|
63 |
}
|
jaroslav@49
|
64 |
|
jaroslav@49
|
65 |
@ComputedProperty static Board selectedBoard(String selectedGameId, List<Board> boards) {
|
jaroslav@49
|
66 |
Board active = null;
|
jaroslav@49
|
67 |
for (Board b : boards) {
|
jaroslav@49
|
68 |
b.setActive(false);
|
jaroslav@49
|
69 |
if (selectedGameId != null && selectedGameId.equals(b.getGameId())) {
|
jaroslav@49
|
70 |
b.setActive(true);
|
jaroslav@49
|
71 |
active = b;
|
jaroslav@49
|
72 |
}
|
jaroslav@49
|
73 |
}
|
jaroslav@49
|
74 |
return active;
|
jaroslav@49
|
75 |
}
|
jaroslav@49
|
76 |
|
jaroslav@49
|
77 |
@Function static void activateGame(UI m, Board data) {
|
jaroslav@49
|
78 |
m.setSelectedGameId(data.getGameId());
|
jaroslav@49
|
79 |
}
|
jaroslav@49
|
80 |
|
jaroslav@49
|
81 |
@Function static void activateSettings(UI m) {
|
jaroslav@49
|
82 |
m.setSelectedGameId(null);
|
jaroslav@49
|
83 |
refreshGames(m);
|
jaroslav@49
|
84 |
}
|
jaroslav@49
|
85 |
|
jaroslav@49
|
86 |
@Function static void createGame(UI u) {
|
jaroslav@49
|
87 |
u.setStatus("Creating new game...");
|
jaroslav@49
|
88 |
Request r = new Request();
|
jaroslav@49
|
89 |
r.setMsg(MsgType.CreateGame);
|
jaroslav@49
|
90 |
r.setColor(Color.valueOf(u.getViewGames().getSelectedColor()));
|
jaroslav@49
|
91 |
u.sendMsg(r);
|
jaroslav@49
|
92 |
}
|
jaroslav@49
|
93 |
|
jaroslav@49
|
94 |
@ModelOperation @Function static void refreshGames(UI u) {
|
jaroslav@49
|
95 |
u.setStatus("Refreshing games...");
|
jaroslav@49
|
96 |
Request r = new Request();
|
jaroslav@49
|
97 |
r.setMsg(MsgType.QueryGames);
|
jaroslav@49
|
98 |
u.sendMsg(r);
|
jaroslav@49
|
99 |
}
|
jaroslav@49
|
100 |
|
jaroslav@49
|
101 |
@ModelOperation static void sendMsg(UI ui, Request r) {
|
jaroslav@49
|
102 |
final Settings sttngs = ui.getSettings();
|
jaroslav@49
|
103 |
|
jaroslav@49
|
104 |
String url = sttngs.getUrl();
|
jaroslav@49
|
105 |
r.setUsername(sttngs.getUsername());
|
jaroslav@49
|
106 |
r.setPassword(sttngs.getPassword());
|
jaroslav@49
|
107 |
|
jaroslav@49
|
108 |
LOG.log(Level.INFO, "Sending {0} to {1}", new Object[]{r, url});
|
jaroslav@49
|
109 |
ui.queryServer(url, r);
|
jaroslav@49
|
110 |
}
|
jaroslav@49
|
111 |
|
jaroslav@49
|
112 |
|
jaroslav@49
|
113 |
@OnReceive(data = Request.class, url = "{url}", method = "WebSocket", onError = "wasAnError")
|
jaroslav@49
|
114 |
static void queryServer(UI ui, Response r) {
|
jaroslav@49
|
115 |
LOG.log(Level.INFO, "Received {0}", r);
|
jaroslav@49
|
116 |
if (r == null) {
|
jaroslav@49
|
117 |
ui.setDisconnected(false);
|
jaroslav@49
|
118 |
verifyLogin(ui);
|
jaroslav@49
|
119 |
return;
|
jaroslav@49
|
120 |
}
|
jaroslav@49
|
121 |
SWITCH: switch (MsgType.forResponse(r.getMsg())) {
|
jaroslav@49
|
122 |
case CheckCredentials: {
|
jaroslav@49
|
123 |
switch (r.getCheck()) {
|
jaroslav@49
|
124 |
case NOT_REGISTERED:
|
jaroslav@49
|
125 |
case VALID:
|
jaroslav@49
|
126 |
ui.setConnected(true);
|
jaroslav@49
|
127 |
ui.refreshGames();
|
jaroslav@49
|
128 |
ui.setStatus("Connected.");
|
jaroslav@49
|
129 |
return;
|
jaroslav@49
|
130 |
case INVALID:
|
jaroslav@49
|
131 |
ui.setStatus("Password is invalid");
|
jaroslav@49
|
132 |
break;
|
jaroslav@49
|
133 |
}
|
jaroslav@49
|
134 |
disconnect(ui);
|
jaroslav@49
|
135 |
}
|
jaroslav@49
|
136 |
|
jaroslav@49
|
137 |
case QueryGames:
|
jaroslav@49
|
138 |
ui.getViewGames().listGames(r.getGames(), ui.getSettings().getUsername());
|
jaroslav@49
|
139 |
ui.setStatus("");
|
jaroslav@49
|
140 |
break;
|
jaroslav@49
|
141 |
case CreateGame: {
|
jaroslav@49
|
142 |
ui.setStatus("Game " + r + " created");
|
jaroslav@49
|
143 |
final Board b = Rules.createBoard();
|
jaroslav@49
|
144 |
Rules.initBoard(
|
jaroslav@49
|
145 |
b, r.getBoard().getWhites(),
|
jaroslav@49
|
146 |
r.getBoard().getBlacks(),
|
jaroslav@49
|
147 |
r.getTurn()
|
jaroslav@49
|
148 |
);
|
jaroslav@49
|
149 |
b.setGameId(r.getGameId());
|
jaroslav@49
|
150 |
b.setWhitePlayer(r.getWhitePlayer());
|
jaroslav@49
|
151 |
b.setBlackPlayer(r.getBlackPlayer());
|
jaroslav@49
|
152 |
b.setPlayer(ui.getSettings().getUsername());
|
jaroslav@49
|
153 |
b.updateSummary(r.getSummary());
|
jaroslav@49
|
154 |
ui.getBoards().add(b);
|
jaroslav@49
|
155 |
ui.setSelectedGameId(r.getGameId());
|
jaroslav@49
|
156 |
UIModel.refreshGames(ui);
|
jaroslav@49
|
157 |
break;
|
jaroslav@49
|
158 |
}
|
jaroslav@49
|
159 |
case SendMove: {
|
jaroslav@49
|
160 |
if (r.getBoard() == null) {
|
jaroslav@49
|
161 |
throw new NullPointerException("No board in " + r);
|
jaroslav@49
|
162 |
}
|
jaroslav@49
|
163 |
final Board b = findBoard(ui, r.getGameId());
|
jaroslav@49
|
164 |
if (b == null) {
|
jaroslav@49
|
165 |
break;
|
jaroslav@49
|
166 |
}
|
jaroslav@49
|
167 |
b.updateSummary(r.getSummary());
|
jaroslav@49
|
168 |
final String errMsg = r.getError() == null ? null : r.getError().getMessage();
|
jaroslav@49
|
169 |
final List<String> whites = r.getBoard().getWhites();
|
jaroslav@49
|
170 |
final List<String> blacks = r.getBoard().getBlacks();
|
jaroslav@49
|
171 |
final Color turn = r.getNextTurn();
|
jaroslav@49
|
172 |
BoardModel.moveResponse(b, errMsg, whites, blacks, turn, r.getAlert());
|
jaroslav@49
|
173 |
break;
|
jaroslav@49
|
174 |
}
|
jaroslav@49
|
175 |
case JoinGame: {
|
jaroslav@49
|
176 |
Board b;
|
jaroslav@49
|
177 |
if ((b = findBoard(ui, r.getGameId())) != null) {
|
jaroslav@49
|
178 |
b.setWhitePlayer(r.getWhitePlayer());
|
jaroslav@49
|
179 |
b.setBlackPlayer(r.getBlackPlayer());
|
jaroslav@49
|
180 |
b.setPlayer(ui.getSettings().getUsername());
|
jaroslav@49
|
181 |
b.updateSummary(r.getSummary());
|
jaroslav@49
|
182 |
ui.setSelectedGameId(r.getGameId());
|
jaroslav@49
|
183 |
break SWITCH;
|
jaroslav@49
|
184 |
}
|
jaroslav@49
|
185 |
ui.setStatus("Joining " + r.getGameId() + " as " + r.getColor());
|
jaroslav@49
|
186 |
b = Rules.createBoard();
|
jaroslav@49
|
187 |
Rules.initBoard(
|
jaroslav@49
|
188 |
b, r.getBoard().getWhites(),
|
jaroslav@49
|
189 |
r.getBoard().getBlacks(),
|
jaroslav@49
|
190 |
r.getTurn()
|
jaroslav@49
|
191 |
);
|
jaroslav@49
|
192 |
b.setGameId(r.getGameId());
|
jaroslav@49
|
193 |
b.setWhitePlayer(r.getWhitePlayer());
|
jaroslav@49
|
194 |
b.setBlackPlayer(r.getBlackPlayer());
|
jaroslav@49
|
195 |
b.setPlayer(ui.getSettings().getUsername());
|
jaroslav@49
|
196 |
b.updateSummary(r.getSummary());
|
jaroslav@49
|
197 |
if (r.getColor() == Color.B) {
|
jaroslav@49
|
198 |
BoardModel.rotateBoard(b);
|
jaroslav@49
|
199 |
}
|
jaroslav@49
|
200 |
if (r.getMoves() != null) {
|
jaroslav@49
|
201 |
for (String move : r.getMoves()) {
|
jaroslav@49
|
202 |
Move m = BoardModel.MoveImpl.valueOf(move);
|
jaroslav@49
|
203 |
b.getMoves().add(m);
|
jaroslav@49
|
204 |
}
|
jaroslav@49
|
205 |
} else {
|
jaroslav@49
|
206 |
b.getMoves().clear();
|
jaroslav@49
|
207 |
}
|
jaroslav@49
|
208 |
ui.setSelectedGameId(b.getGameId());
|
jaroslav@49
|
209 |
ui.getBoards().add(b);
|
jaroslav@49
|
210 |
break;
|
jaroslav@49
|
211 |
}
|
jaroslav@49
|
212 |
case UpdateGame: {
|
jaroslav@49
|
213 |
final Board b = findBoard(ui, r.getGameId());
|
jaroslav@49
|
214 |
if (b == null) {
|
jaroslav@49
|
215 |
break;
|
jaroslav@49
|
216 |
}
|
jaroslav@49
|
217 |
b.updateSummary(r.getSummary());
|
jaroslav@49
|
218 |
final Move move = BoardModel.MoveImpl.valueOf(r.getFrom() + r.getTo());
|
jaroslav@49
|
219 |
final List<String> whites = r.getBoard().getWhites();
|
jaroslav@49
|
220 |
final List<String> blacks = r.getBoard().getBlacks();
|
jaroslav@49
|
221 |
final Color turn = r.getNextTurn();
|
jaroslav@49
|
222 |
BoardModel.moveUpdate(b, move, whites, blacks, turn, null);
|
jaroslav@49
|
223 |
}
|
jaroslav@49
|
224 |
}
|
jaroslav@49
|
225 |
}
|
jaroslav@49
|
226 |
|
jaroslav@49
|
227 |
|
jaroslav@49
|
228 |
private static Board findBoard(UI ui, String gameId) {
|
jaroslav@49
|
229 |
for (Board tmp : ui.getBoards()) {
|
jaroslav@49
|
230 |
if (tmp.getGameId().equals(gameId)) {
|
jaroslav@49
|
231 |
return tmp;
|
jaroslav@49
|
232 |
}
|
jaroslav@49
|
233 |
}
|
jaroslav@49
|
234 |
return null;
|
jaroslav@49
|
235 |
}
|
jaroslav@49
|
236 |
|
jaroslav@49
|
237 |
|
jaroslav@49
|
238 |
static void wasAnError(UI ui, Exception t) {
|
jaroslav@49
|
239 |
if (t == null) {
|
jaroslav@49
|
240 |
ui.setConnected(false);
|
jaroslav@49
|
241 |
ui.setDisconnected(true);
|
jaroslav@49
|
242 |
ui.setStatus("Disconnected.");
|
jaroslav@49
|
243 |
} else {
|
jaroslav@49
|
244 |
ui.setStatus("Error: " + t.getLocalizedMessage());
|
jaroslav@49
|
245 |
}
|
jaroslav@49
|
246 |
}
|
jaroslav@49
|
247 |
|
jaroslav@49
|
248 |
@Function static void joinGame(UI u, Game data) {
|
jaroslav@49
|
249 |
Request r = new Request();
|
jaroslav@49
|
250 |
r.setMsg(MsgType.JoinGame);
|
jaroslav@49
|
251 |
r.setObserver(false);
|
jaroslav@49
|
252 |
r.setGameId(data.getGameId());
|
jaroslav@49
|
253 |
u.sendMsg(r);
|
jaroslav@49
|
254 |
}
|
jaroslav@49
|
255 |
|
jaroslav@49
|
256 |
@Function static void observeGame(UI u, Game data) {
|
jaroslav@49
|
257 |
Request r = new Request();
|
jaroslav@49
|
258 |
r.setMsg(MsgType.JoinGame);
|
jaroslav@49
|
259 |
r.setObserver(true);
|
jaroslav@49
|
260 |
r.setGameId(data.getGameId());
|
jaroslav@49
|
261 |
u.sendMsg(r);
|
jaroslav@49
|
262 |
}
|
jaroslav@49
|
263 |
|
jaroslav@49
|
264 |
private static final Set<UI> ACTIVE = new HashSet<>();
|
jaroslav@49
|
265 |
@OnPropertyChange("connected") static void clearGames(UI m) {
|
jaroslav@49
|
266 |
if (m.isDisconnected()) {
|
jaroslav@49
|
267 |
m.getBoards().clear();
|
jaroslav@49
|
268 |
ACTIVE.remove(m);
|
jaroslav@49
|
269 |
} else {
|
jaroslav@49
|
270 |
ACTIVE.add(m);
|
jaroslav@49
|
271 |
}
|
jaroslav@49
|
272 |
}
|
jaroslav@49
|
273 |
|
jaroslav@49
|
274 |
static UI findUI(Board b) {
|
jaroslav@49
|
275 |
for (UI ui : ACTIVE) {
|
jaroslav@49
|
276 |
if (ui.getBoards().contains(b)) {
|
jaroslav@49
|
277 |
return ui;
|
jaroslav@49
|
278 |
}
|
jaroslav@49
|
279 |
}
|
jaroslav@49
|
280 |
return null;
|
jaroslav@49
|
281 |
}
|
jaroslav@49
|
282 |
|
jaroslav@49
|
283 |
@Function static void leave(UI ui, Board data) {
|
jaroslav@49
|
284 |
ui.getBoards().remove(data);
|
jaroslav@49
|
285 |
ui.setSelectedGameId(null);
|
jaroslav@49
|
286 |
}
|
jaroslav@49
|
287 |
|
jaroslav@49
|
288 |
@Function static void disconnect(UI ui) {
|
jaroslav@49
|
289 |
ui.queryServer(ui.getSettings().getUrl(), null);
|
jaroslav@49
|
290 |
ui.setStatus("Disconnecting...");
|
jaroslav@49
|
291 |
}
|
jaroslav@49
|
292 |
|
jaroslav@49
|
293 |
private static void verifyLogin(UI ui) {
|
jaroslav@49
|
294 |
ui.setStatus("Verifying user credentials...");
|
jaroslav@49
|
295 |
Request r = new Request();
|
jaroslav@49
|
296 |
r.setMsg(MsgType.CheckCredentials);
|
jaroslav@49
|
297 |
ui.sendMsg(r);
|
jaroslav@49
|
298 |
}
|
jaroslav@49
|
299 |
|
jaroslav@49
|
300 |
@Function static void reconnect(UI ui) {
|
jaroslav@49
|
301 |
final Settings s = ui.getSettings();
|
jaroslav@49
|
302 |
ui.setStatus("Connecting to the server...");
|
jaroslav@49
|
303 |
ui.queryServer(s.getUrl(), null);
|
jaroslav@49
|
304 |
s.write(ui);
|
jaroslav@49
|
305 |
}
|
jaroslav@49
|
306 |
|
jaroslav@49
|
307 |
public static void initialize(String... args) throws URISyntaxException, IOException {
|
jaroslav@49
|
308 |
UI ui = new UI();
|
jaroslav@49
|
309 |
ui.getSettings().read();
|
jaroslav@49
|
310 |
ui.setStatus("Ready.");
|
jaroslav@49
|
311 |
ui.setDisconnected(true);
|
jaroslav@49
|
312 |
ui.applyBindings();
|
jaroslav@49
|
313 |
}
|
jaroslav@49
|
314 |
|
jaroslav@49
|
315 |
}
|