@@ -151,28 +151,41 @@ Throwable getLastBotThrow() {
151
151
152
152
private Thread createBotThread () {
153
153
return new Thread (() -> {
154
- configuration .log ("Bot: Thread started" );
155
- while ( ! gameOver ) {
156
- configuration .log ("Bot: Attempting to handle next frame" );
157
- frameBuffer .lockSize .lock ();
158
- try {
159
- while (frameBuffer .empty ()) {
160
- configuration .log ("Bot: Waiting for next frame" );
161
- performanceMetrics .botIdle .startTiming ();
162
- frameBuffer .conditionSize .awaitUninterruptibly ();
154
+ try {
155
+ configuration .log ("Bot: Thread started" );
156
+ while (!gameOver ) {
157
+
158
+ configuration .log ("Bot: Attempting to handle next frame" );
159
+ frameBuffer .lockSize .lock ();
160
+ try {
161
+ while (frameBuffer .empty ()) {
162
+ configuration .log ("Bot: Waiting for next frame" );
163
+ performanceMetrics .botIdle .startTiming ();
164
+ frameBuffer .conditionSize .awaitUninterruptibly ();
165
+ }
166
+ performanceMetrics .botIdle .stopTiming ();
167
+ } finally {
168
+ frameBuffer .lockSize .unlock ();
163
169
}
164
- performanceMetrics .botIdle .stopTiming ();
165
- } finally {
166
- frameBuffer .lockSize .unlock ();
167
- }
168
- configuration .log ("Bot: Peeking next frame" );
169
- game .clientData ().setBuffer (frameBuffer .peek ());
170
- performanceMetrics .frameBufferSize .record (frameBuffer .framesBuffered () - 1 );
171
- try {
170
+
171
+ configuration .log ("Bot: Peeking next frame" );
172
+ game .clientData ().setBuffer (frameBuffer .peek ());
173
+ performanceMetrics .frameBufferSize .record (frameBuffer .framesBuffered () - 1 );
174
+
172
175
configuration .log ("Bot: Handling frame #" + game .getFrameCount ());
173
176
handleEvents ();
174
- } finally {
175
- // In the case where t
177
+ frameBuffer .dequeue ();
178
+ }
179
+ } catch (Throwable throwable ) {
180
+ // Record the throw,
181
+ // Then allow the thread to terminate silently.
182
+ // The main thread will look for the stored throw.
183
+ lastBotThrowLock .lock ();
184
+ lastBotThrow = throwable ;
185
+ lastBotThrowLock .unlock ();
186
+
187
+ // Awaken any threads waiting on bot progress
188
+ while (!frameBuffer .empty ()) {
176
189
frameBuffer .dequeue ();
177
190
}
178
191
}
@@ -184,21 +197,14 @@ private void handleEvents() {
184
197
if (gameData .getFrameCount () > 0 || ! configuration .unlimitedFrameZero ) {
185
198
performanceMetrics .botResponse .startTiming ();
186
199
}
200
+
187
201
// Populate gameOver before invoking event handlers (in case the bot throws)
188
202
for (int i = 0 ; i < gameData .getEventCount (); i ++) {
189
203
gameOver = gameOver || gameData .getEvents (i ).getType () == EventType .MatchEnd ;
190
204
}
191
- try {
192
- for (int i = 0 ; i < gameData .getEventCount (); i ++) {
193
- EventHandler .operation (eventListener , game , gameData .getEvents (i ));
194
- }
195
- } catch (Throwable throwable ) {
196
- lastBotThrowLock .lock ();
197
- lastBotThrow = throwable ;
198
- lastBotThrowLock .unlock ();
199
- throw throwable ;
200
- } finally {
201
- performanceMetrics .botResponse .stopTiming ();
205
+ for (int i = 0 ; i < gameData .getEventCount (); i ++) {
206
+ EventHandler .operation (eventListener , game , gameData .getEvents (i ));
202
207
}
208
+ performanceMetrics .botResponse .stopTiming ();
203
209
}
204
210
}
0 commit comments