@@ -40,8 +40,8 @@ class BotWrapper {
4040 private Thread botThread ;
4141 private boolean gameOver ;
4242 private PerformanceMetrics performanceMetrics ;
43- private Exception lastBotException ;
44- private ReentrantLock lastBotExceptionLock = new ReentrantLock ();
43+ private Throwable lastBotThrow ;
44+ private ReentrantLock lastBotThrowLock = new ReentrantLock ();
4545
4646 BotWrapper (BWClientConfiguration configuration , BWEventListener eventListener ) {
4747 this .configuration = configuration ;
@@ -96,9 +96,9 @@ void onFrame() {
9696 while (!frameBuffer .empty ()) {
9797
9898 // Make bot exceptions fall through to the main thread.
99- Exception lastBotException = getLastBotException ();
100- if (lastBotException != null ) {
101- throw new RuntimeException (lastBotException );
99+ Throwable lastThrow = getLastBotThrow ();
100+ if (lastThrow != null ) {
101+ throw new RuntimeException (lastThrow );
102102 }
103103
104104 if (configuration .unlimitedFrameZero && isFrameZero ) {
@@ -116,9 +116,6 @@ void onFrame() {
116116 }
117117 } else {
118118 handleEvents ();
119- if (lastBotException != null ) {
120- throw new RuntimeException (lastBotException );
121- }
122119 }
123120 }
124121
@@ -133,10 +130,10 @@ void endGame() {
133130 }
134131 }
135132
136- Exception getLastBotException () {
137- lastBotExceptionLock .lock ();
138- Exception output = lastBotException ;
139- lastBotExceptionLock .unlock ();
133+ Throwable getLastBotThrow () {
134+ lastBotThrowLock .lock ();
135+ Throwable output = lastBotThrow ;
136+ lastBotThrowLock .unlock ();
140137 return output ;
141138 }
142139
@@ -155,8 +152,12 @@ private Thread createBotThread() {
155152 }
156153 game .clientData ().setBuffer (frameBuffer .peek ());
157154 performanceMetrics .frameBufferSize .record (frameBuffer .framesBuffered () - 1 );
158- handleEvents ();
159- frameBuffer .dequeue ();
155+ try {
156+ handleEvents ();
157+ } finally {
158+ // In the case where t
159+ frameBuffer .dequeue ();
160+ }
160161 }
161162 });
162163 }
@@ -166,19 +167,21 @@ private void handleEvents() {
166167 if (gameData .getFrameCount () > 0 || ! configuration .unlimitedFrameZero ) {
167168 performanceMetrics .botResponse .startTiming ();
168169 }
170+ // Populate gameOver before invoking event handlers (in case the bot throws)
171+ for (int i = 0 ; i < gameData .getEventCount (); i ++) {
172+ gameOver = gameOver || gameData .getEvents (i ).getType () == EventType .MatchEnd ;
173+ }
169174 try {
170175 for (int i = 0 ; i < gameData .getEventCount (); i ++) {
171- ClientData .Event event = gameData .getEvents (i );
172- EventHandler .operation (eventListener , game , event );
173- if (event .getType () == EventType .MatchEnd ) {
174- gameOver = true ;
175- }
176+ EventHandler .operation (eventListener , game , gameData .getEvents (i ));
176177 }
177- } catch (Exception exception ) {
178- lastBotExceptionLock .lock ();
179- lastBotException = exception ;
180- lastBotExceptionLock .unlock ();
178+ } catch (Throwable throwable ) {
179+ lastBotThrowLock .lock ();
180+ lastBotThrow = throwable ;
181+ lastBotThrowLock .unlock ();
182+ throw throwable ;
183+ } finally {
184+ performanceMetrics .botResponse .stopTiming ();
181185 }
182- performanceMetrics .botResponse .stopTiming ();
183186 }
184187}
0 commit comments