diff options
author | Starla Insigna <hatkirby@fourisland.com> | 2009-02-23 09:20:19 -0500 |
---|---|---|
committer | Starla Insigna <hatkirby@fourisland.com> | 2009-02-23 09:20:19 -0500 |
commit | 284c53489b89a6e39027aeab27c258c8926f77f0 (patch) | |
tree | 51d0cd69236b0a43ce2b36149f62f18281dd86c6 /src/com | |
parent | 8b8e44782659c65b9899f81a1ad5e09477c37354 (diff) | |
download | fourpuzzle-284c53489b89a6e39027aeab27c258c8926f77f0.tar.gz fourpuzzle-284c53489b89a6e39027aeab27c258c8926f77f0.tar.bz2 fourpuzzle-284c53489b89a6e39027aeab27c258c8926f77f0.zip |
Engine: Added Event Thread cancellation
Diffstat (limited to 'src/com')
7 files changed, 145 insertions, 51 deletions
diff --git a/src/com/fourisland/fourpuzzle/Display.java b/src/com/fourisland/fourpuzzle/Display.java index a8c9a37..c8d17d9 100755 --- a/src/com/fourisland/fourpuzzle/Display.java +++ b/src/com/fourisland/fourpuzzle/Display.java | |||
@@ -198,47 +198,54 @@ public class Display { | |||
198 | transitionRunning = true; | 198 | transitionRunning = true; |
199 | 199 | ||
200 | transitionWait = new CountDownLatch(1); | 200 | transitionWait = new CountDownLatch(1); |
201 | transitionWait.await(); | ||
202 | 201 | ||
203 | Display.transition = null; | 202 | try { |
203 | transitionWait.await(); | ||
204 | } catch (InterruptedException ex) { | ||
205 | throw ex; | ||
206 | } finally { | ||
207 | Display.transition = null; | ||
204 | 208 | ||
205 | if (!startedTransition) | 209 | if (!startedTransition) |
206 | { | 210 | { |
207 | transitionRunning = false; | 211 | transitionRunning = false; |
212 | } | ||
208 | } | 213 | } |
209 | } | 214 | } |
210 | 215 | ||
211 | private static Executor transitioner = Executors.newSingleThreadExecutor(); | 216 | private static Executor transitioner = Executors.newSingleThreadExecutor(); |
212 | public static void transition(final OutTransition out, final GameState gameState, final InTransition in, boolean thread) | 217 | public static void transition(final OutTransition out, final GameState gameState, final InTransition in, boolean thread) throws InterruptedException |
213 | { | 218 | { |
214 | Runnable transitionCall = new Runnable() { | ||
215 | public void run() | ||
216 | { | ||
217 | try { | ||
218 | Display.transition(out); | ||
219 | Game.setGameState(gameState); | ||
220 | Display.transition(in); | ||
221 | } catch (InterruptedException ex) { | ||
222 | Thread.currentThread().interrupt(); | ||
223 | } catch (RuntimeException ex) | ||
224 | { | ||
225 | PuzzleApplication.INSTANCE.reportError(ex); | ||
226 | } catch (Error ex) | ||
227 | { | ||
228 | PuzzleApplication.INSTANCE.reportError(ex); | ||
229 | } | ||
230 | } | ||
231 | }; | ||
232 | |||
233 | if (thread) | 219 | if (thread) |
234 | { | 220 | { |
221 | Runnable transitionCall = new Runnable() { | ||
222 | public void run() | ||
223 | { | ||
224 | try { | ||
225 | Display.transition(out); | ||
226 | Game.setGameState(gameState); | ||
227 | Display.transition(in); | ||
228 | } catch (InterruptedException ex) { | ||
229 | return; | ||
230 | } catch (RuntimeException ex) | ||
231 | { | ||
232 | PuzzleApplication.INSTANCE.reportError(ex); | ||
233 | } catch (Error ex) | ||
234 | { | ||
235 | PuzzleApplication.INSTANCE.reportError(ex); | ||
236 | } | ||
237 | } | ||
238 | }; | ||
239 | |||
235 | transitioner.execute(transitionCall); | 240 | transitioner.execute(transitionCall); |
236 | } else { | 241 | } else { |
237 | transitionCall.run(); | 242 | Display.transition(out); |
243 | Game.setGameState(gameState); | ||
244 | Display.transition(in); | ||
238 | } | 245 | } |
239 | } | 246 | } |
240 | 247 | ||
241 | public static void transition(TransitionPair trans, GameState gameState, boolean thread) | 248 | public static void transition(TransitionPair trans, GameState gameState, boolean thread) throws InterruptedException |
242 | { | 249 | { |
243 | transition(trans.getOutTransition(), gameState, trans.getInTransition(), thread); | 250 | transition(trans.getOutTransition(), gameState, trans.getInTransition(), thread); |
244 | } | 251 | } |
diff --git a/src/com/fourisland/fourpuzzle/gamestate/mapview/MapViewGameState.java b/src/com/fourisland/fourpuzzle/gamestate/mapview/MapViewGameState.java index 68e611b..ccb1829 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/mapview/MapViewGameState.java +++ b/src/com/fourisland/fourpuzzle/gamestate/mapview/MapViewGameState.java | |||
@@ -141,6 +141,17 @@ public class MapViewGameState implements GameState { | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | } | 143 | } |
144 | } | ||
145 | } | ||
146 | |||
147 | if (EventHandler.isRunningEvent()) | ||
148 | { | ||
149 | if ((key.getKey() == KeyEvent.VK_F11) && (PuzzleApplication.INSTANCE.getContext().getResourceMap().getBoolean("debugMode"))) | ||
150 | { | ||
151 | for (LayerEvent ev : currentMap.getEvents()) | ||
152 | { | ||
153 | ev.getCallback().cancel(); | ||
154 | } | ||
144 | } | 155 | } |
145 | } | 156 | } |
146 | } | 157 | } |
diff --git a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/EventCall.java b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/EventCall.java index 7214528..c94fc80 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/EventCall.java +++ b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/EventCall.java | |||
@@ -22,20 +22,28 @@ public abstract class EventCall extends SpecialEvent { | |||
22 | }; | 22 | }; |
23 | } | 23 | } |
24 | 24 | ||
25 | public abstract void run(); | 25 | public abstract void run() throws InterruptedException; |
26 | 26 | ||
27 | private Future isRunning = null; | 27 | private Future eventThread = null; |
28 | public void activate(EventCallTime calltime) | 28 | public void activate(EventCallTime calltime) |
29 | { | 29 | { |
30 | if ((isRunning == null) || (isRunning.isDone())) | 30 | if ((eventThread == null) || (eventThread.isDone())) |
31 | { | 31 | { |
32 | if (calltime == EventCallTime.ParallelProcess) | 32 | if (calltime == EventCallTime.ParallelProcess) |
33 | { | 33 | { |
34 | isRunning = EventHandler.runParallel(this); | 34 | eventThread = EventHandler.runParallel(this); |
35 | } else { | 35 | } else { |
36 | isRunning = EventHandler.runEvent(this); | 36 | eventThread = EventHandler.runEvent(this); |
37 | } | 37 | } |
38 | } | 38 | } |
39 | } | 39 | } |
40 | 40 | ||
41 | public void cancel() | ||
42 | { | ||
43 | if ((eventThread != null) && (!eventThread.isDone())) | ||
44 | { | ||
45 | eventThread.cancel(true); | ||
46 | } | ||
47 | } | ||
48 | |||
41 | } | 49 | } |
diff --git a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/EventHandler.java b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/EventHandler.java index a8a626f..e24b79c 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/EventHandler.java +++ b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/EventHandler.java | |||
@@ -6,6 +6,7 @@ | |||
6 | package com.fourisland.fourpuzzle.gamestate.mapview.event; | 6 | package com.fourisland.fourpuzzle.gamestate.mapview.event; |
7 | 7 | ||
8 | import com.fourisland.fourpuzzle.PuzzleApplication; | 8 | import com.fourisland.fourpuzzle.PuzzleApplication; |
9 | import com.fourisland.fourpuzzle.gamestate.mapview.viewpoint.AutomaticViewpoint; | ||
9 | import com.fourisland.fourpuzzle.util.ResourceNotFoundException; | 10 | import com.fourisland.fourpuzzle.util.ResourceNotFoundException; |
10 | import java.util.concurrent.ExecutorService; | 11 | import java.util.concurrent.ExecutorService; |
11 | import java.util.concurrent.Executors; | 12 | import java.util.concurrent.Executors; |
@@ -51,6 +52,14 @@ public class EventHandler { | |||
51 | try | 52 | try |
52 | { | 53 | { |
53 | callback.run(); | 54 | callback.run(); |
55 | } catch (InterruptedException ex) { | ||
56 | /* Swallow the interrupt, as the interruption probably | ||
57 | * indicates that the event should be cancelled | ||
58 | * | ||
59 | * Also reset the viewpoint in case the viewpoint was | ||
60 | * fixed during the thread */ | ||
61 | |||
62 | SpecialEvent.mapView.setViewpoint(new AutomaticViewpoint(SpecialEvent.mapView.getCurrentMap())); | ||
54 | } catch (ResourceNotFoundException ex) | 63 | } catch (ResourceNotFoundException ex) |
55 | { | 64 | { |
56 | PuzzleApplication.INSTANCE.reportError(ex); | 65 | PuzzleApplication.INSTANCE.reportError(ex); |
diff --git a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/SpecialEvent.java b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/SpecialEvent.java index c3bec32..1a33158 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/SpecialEvent.java +++ b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/SpecialEvent.java | |||
@@ -282,18 +282,26 @@ public class SpecialEvent { | |||
282 | mapView.setViewpoint(new MovingViewpoint(viewpoint.getX(), viewpoint.getY(), x*16, y*16, new Runnable() { | 282 | mapView.setViewpoint(new MovingViewpoint(viewpoint.getX(), viewpoint.getY(), x*16, y*16, new Runnable() { |
283 | public void run() | 283 | public void run() |
284 | { | 284 | { |
285 | mapView.setViewpoint(new FixedViewpoint(x*16,y*16)); | ||
286 | |||
287 | if (block) | 285 | if (block) |
288 | { | 286 | { |
289 | blocker.countDown(); | 287 | blocker.countDown(); |
288 | } else { | ||
289 | mapView.setViewpoint(new FixedViewpoint(x*16,y*16)); | ||
290 | } | 290 | } |
291 | } | 291 | } |
292 | }, length)); | 292 | }, length)); |
293 | 293 | ||
294 | if (block) | 294 | if (block) |
295 | { | 295 | { |
296 | blocker.await(); | 296 | try |
297 | { | ||
298 | blocker.await(); | ||
299 | } catch (InterruptedException ex) | ||
300 | { | ||
301 | throw ex; | ||
302 | } finally { | ||
303 | mapView.setViewpoint(new FixedViewpoint(x*16,y*16)); | ||
304 | } | ||
297 | } | 305 | } |
298 | } | 306 | } |
299 | 307 | ||
@@ -334,4 +342,14 @@ public class SpecialEvent { | |||
334 | Audio.stopMusic(); | 342 | Audio.stopMusic(); |
335 | } | 343 | } |
336 | 344 | ||
345 | /** | ||
346 | * Ends the currently executing event thread | ||
347 | * | ||
348 | * @throws InterruptedException | ||
349 | */ | ||
350 | public void StopThread() throws InterruptedException | ||
351 | { | ||
352 | throw new InterruptedException(); | ||
353 | } | ||
354 | |||
337 | } | 355 | } |
diff --git a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java index 488331a..233c415 100755 --- a/src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java +++ b/src/com/fourisland/fourpuzzle/gamestate/mapview/event/specialmove/MoveEventThread.java | |||
@@ -8,10 +8,12 @@ package com.fourisland.fourpuzzle.gamestate.mapview.event.specialmove; | |||
8 | import com.fourisland.fourpuzzle.Game; | 8 | import com.fourisland.fourpuzzle.Game; |
9 | import com.fourisland.fourpuzzle.gamestate.mapview.event.Event; | 9 | import com.fourisland.fourpuzzle.gamestate.mapview.event.Event; |
10 | import com.fourisland.fourpuzzle.gamestate.mapview.event.LayerEvent; | 10 | import com.fourisland.fourpuzzle.gamestate.mapview.event.LayerEvent; |
11 | import java.util.ArrayList; | ||
11 | import java.util.List; | 12 | import java.util.List; |
12 | import java.util.Vector; | 13 | import java.util.Vector; |
13 | import java.util.concurrent.Executor; | 14 | import java.util.concurrent.ExecutorService; |
14 | import java.util.concurrent.Executors; | 15 | import java.util.concurrent.Executors; |
16 | import java.util.concurrent.Future; | ||
15 | import java.util.concurrent.Semaphore; | 17 | import java.util.concurrent.Semaphore; |
16 | 18 | ||
17 | /** | 19 | /** |
@@ -20,10 +22,11 @@ import java.util.concurrent.Semaphore; | |||
20 | */ | 22 | */ |
21 | public class MoveEventThread implements Runnable { | 23 | public class MoveEventThread implements Runnable { |
22 | 24 | ||
23 | private static Executor moveEventExecutor = Executors.newCachedThreadPool(); | 25 | private static ExecutorService moveEventExecutor = Executors.newCachedThreadPool(); |
24 | 26 | ||
25 | private static volatile List<Event> events = new Vector<Event>(); | 27 | private static volatile List<Event> events = new Vector<Event>(); |
26 | private static volatile Semaphore moveEventWait = new Semaphore(100); | 28 | private static volatile Semaphore moveEventWait = new Semaphore(100); |
29 | private static volatile List<Future> eventThreads = new ArrayList<Future>(); | ||
27 | 30 | ||
28 | private Event ev; | 31 | private Event ev; |
29 | private MoveEvent[] actions; | 32 | private MoveEvent[] actions; |
@@ -36,7 +39,15 @@ public class MoveEventThread implements Runnable { | |||
36 | 39 | ||
37 | public void start() | 40 | public void start() |
38 | { | 41 | { |
39 | moveEventExecutor.execute(this); | 42 | for (Future f : eventThreads) |
43 | { | ||
44 | if (f.isDone()) | ||
45 | { | ||
46 | eventThreads.remove(f); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | eventThreads.add(moveEventExecutor.submit(this)); | ||
40 | } | 51 | } |
41 | 52 | ||
42 | public void run() | 53 | public void run() |
@@ -44,7 +55,7 @@ public class MoveEventThread implements Runnable { | |||
44 | try { | 55 | try { |
45 | moveEventWait.acquire(); | 56 | moveEventWait.acquire(); |
46 | } catch (InterruptedException ex) { | 57 | } catch (InterruptedException ex) { |
47 | Thread.currentThread().interrupt(); | 58 | return; |
48 | } | 59 | } |
49 | 60 | ||
50 | while (ev.isMoving()) | 61 | while (ev.isMoving()) |
@@ -52,25 +63,49 @@ public class MoveEventThread implements Runnable { | |||
52 | try { | 63 | try { |
53 | Thread.sleep(2); | 64 | Thread.sleep(2); |
54 | } catch (InterruptedException ex) { | 65 | } catch (InterruptedException ex) { |
55 | Thread.currentThread().interrupt(); | 66 | return; |
56 | } | 67 | } |
57 | } | 68 | } |
58 | 69 | ||
59 | events.add(ev); | 70 | events.add(ev); |
60 | 71 | ||
61 | for (MoveEvent action : actions) | 72 | try |
62 | { | 73 | { |
63 | action.doAction(ev); | 74 | for (MoveEvent action : actions) |
64 | } | 75 | { |
76 | action.doAction(ev); | ||
65 | 77 | ||
66 | events.remove(ev); | 78 | if (Thread.currentThread().isInterrupted()) |
67 | moveEventWait.release(); | 79 | { |
80 | throw new InterruptedException(); | ||
81 | } | ||
82 | } | ||
83 | } catch (InterruptedException ex) | ||
84 | { | ||
85 | /* Swallow the interrupt because execution will drop to the finally | ||
86 | * and then the method will end anyway */ | ||
87 | } finally { | ||
88 | events.remove(ev); | ||
89 | moveEventWait.release(); | ||
90 | } | ||
68 | } | 91 | } |
69 | 92 | ||
70 | public static void moveAll() throws InterruptedException | 93 | public static void moveAll() throws InterruptedException |
71 | { | 94 | { |
72 | moveEventWait.acquire(100); | 95 | try |
73 | moveEventWait.release(100); | 96 | { |
97 | moveEventWait.acquire(100); | ||
98 | } catch (InterruptedException ex) | ||
99 | { | ||
100 | for (Future f : eventThreads) | ||
101 | { | ||
102 | f.cancel(true); | ||
103 | } | ||
104 | |||
105 | throw ex; | ||
106 | } finally { | ||
107 | moveEventWait.release(100); | ||
108 | } | ||
74 | } | 109 | } |
75 | 110 | ||
76 | public static boolean isHeroActive() | 111 | public static boolean isHeroActive() |
diff --git a/src/com/fourisland/fourpuzzle/window/MessageWindow.java b/src/com/fourisland/fourpuzzle/window/MessageWindow.java index 0057ca3..dab67d1 100644 --- a/src/com/fourisland/fourpuzzle/window/MessageWindow.java +++ b/src/com/fourisland/fourpuzzle/window/MessageWindow.java | |||
@@ -79,10 +79,16 @@ public class MessageWindow implements Renderable { | |||
79 | Display.registerRenderable(mw); | 79 | Display.registerRenderable(mw); |
80 | KeyboardInput.registerInputable(in); | 80 | KeyboardInput.registerInputable(in); |
81 | 81 | ||
82 | cdl.await(); | 82 | try |
83 | 83 | { | |
84 | Display.unregisterRenderable(mw); | 84 | cdl.await(); |
85 | KeyboardInput.unregisterInputable(in); | 85 | } catch (InterruptedException ex) |
86 | { | ||
87 | throw ex; | ||
88 | } finally { | ||
89 | Display.unregisterRenderable(mw); | ||
90 | KeyboardInput.unregisterInputable(in); | ||
91 | } | ||
86 | } | 92 | } |
87 | 93 | ||
88 | public static void displayMessage(String message) throws InterruptedException | 94 | public static void displayMessage(String message) throws InterruptedException |