1
2
3
4
5
6
7
8
9
10
11 package spellcast.client;
12
13 import java.beans.PropertyChangeEvent;
14
15 import org.apache.log4j.Logger;
16
17 import spellcast.beings.IWizard;
18 import spellcast.event.ConnectionEvent;
19 import spellcast.event.DisconnectionEvent;
20 import spellcast.event.GameEvent;
21 import spellcast.event.GameSyncEvent;
22 import spellcast.event.GameUpdateEvent;
23 import spellcast.event.MessageEvent;
24 import spellcast.event.OkEvent;
25 import spellcast.game.Game;
26 import spellcast.model.Id;
27 import spellcast.ui.SpellcastView;
28
29 public class cengine extends cenginei implements Runnable {
30 private Game theGame;
31 private SpellcastView view;
32 private ClientConnectionHandler clientConnectionHandler;
33 private GameEvent currentGameEvent;
34 private Id myID;
35
36 private final static Logger logger = Logger.getLogger("client.engine");
37
38
39
40 public cengine(
41 SpellcastView view,
42 ClientConnectionHandler clientConnectionHandler) {
43 this.view = view;
44 this.clientConnectionHandler = clientConnectionHandler;
45 }
46
47 /***
48 * When clientConnectionHandler has successfully connected to the Server
49 * it will create the cengine thread. This will read the events sent from the Server
50 * and process them. The thread will finish when the state machine terminates.
51 */
52 public void run() {
53 execute();
54 }
55
56
57
58 public int cengine_execute(String args[]) {
59 int feedback;
60
61 feedback = execute();
62 return (feedback);
63 }
64
65
66
67 public void initialise_the_program() {
68 the_next_event = ok_event;
69 }
70
71
72
73 public void get_external_event() {
74 currentGameEvent = clientConnectionHandler.receive();
75 the_next_event = mapGameEventToStateMachineEvent();
76 }
77
78 public int mapGameEventToStateMachineEvent() {
79 int result = unknown_event;
80
81 if (currentGameEvent == null) {
82 raise_exception(io_error_event);
83 }
84 else
85 if (currentGameEvent instanceof ConnectionEvent) {
86 result = connect_event;
87 }
88 else
89 if (currentGameEvent instanceof DisconnectionEvent) {
90 result = disconnect_event;
91 }
92 else
93 if (currentGameEvent instanceof MessageEvent) {
94 result = message_event;
95 }
96 else
97 if (currentGameEvent instanceof OkEvent) {
98 result = ok_event;
99 }
100 else
101 if (currentGameEvent instanceof GameUpdateEvent) {
102 result = game_update_event;
103 }
104 else
105 if (currentGameEvent instanceof GameSyncEvent) {
106 result = game_sync_event;
107 }
108
109 return result;
110 }
111
112
113
114
115
116 /***
117 * Add a wizard to the game. This also notifies the view that a wizard was added
118 * and sends a messages indicating the connection.
119 */
120 public void add_connection() {
121 ConnectionEvent event = (ConnectionEvent) currentGameEvent;
122 theGame.addWizard(event.getWizard());
123 view.addWizard(event.getWizard());
124 }
125
126
127
128 /***
129 * This is the first message received by the client.
130 * From this message the server tells us what our WizardID is.
131 */
132 public void connect_this_client() {
133 ConnectionEvent event = (ConnectionEvent) currentGameEvent;
134 myID = event.getWizard().getId();
135 view.setID(myID);
136 }
137
138
139
140 /***
141 * If the target of this event is the client's wizardID then we gracefully
142 * shutdown. Otherwise just display a message.
143 */
144 public void remove_connection() {
145 DisconnectionEvent event = (DisconnectionEvent) currentGameEvent;
146 if (theGame != null) {
147 IWizard w = theGame.getWizard(event.getWizardID());
148 if (w != null) {
149 theGame.removeWizard(w);
150 view.removeWizard(w);
151 }
152 if (myID.equals(event.getWizardID())) {
153 clientConnectionHandler.disconnect();
154 clientConnectionHandler.join();
155 }
156 }
157 the_next_event = stop_event;
158 }
159
160
161
162 /***
163 * Display a message to the client.
164 */
165 public void display_message() {
166 MessageEvent event = (MessageEvent) currentGameEvent;
167 view.addMessage(event.getMessage());
168 }
169
170
171
172 /***
173 * A property has changed in the game. Update the local copy to reflect this change.
174 * PropertyChangeEvent's source is transient so we create a new local PropertyChangeEvent
175 * with the source field taken from the GameUpdateEvent.
176 */
177 public void update_game() {
178 GameUpdateEvent event = (GameUpdateEvent) currentGameEvent;
179 PropertyChangeEvent remoteEvent = event.getEvent();
180 PropertyChangeEvent localEvent =
181 new PropertyChangeEvent(
182 event.getSource(),
183 remoteEvent.getPropertyName(),
184 remoteEvent.getOldValue(),
185 remoteEvent.getNewValue());
186 theGame.update(localEvent);
187 }
188
189
190
191 public void handle_unknown_event() {
192 logger.error(
193 "Unknown Game Event received: " + currentGameEvent.getClass().getName());
194 }
195
196
197
198 /***
199 * If there is no game info, just use the one given.
200 * Otherwise check to see what is different and include the new objects.
201 */
202 public void sync_game() {
203 GameSyncEvent event = (GameSyncEvent) currentGameEvent;
204 if (theGame == null) {
205 theGame = event.getGame();
206 view.setGame(theGame);
207 }
208 else {
209 logger.error(
210 "Does not yet handle game sync events when a game is already established.");
211 }
212 }
213
214
215
216 public void handle_io_error() {
217
218
219 }
220
221
222 }