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 |
