@@ -151,28 +151,41 @@ Throwable getLastBotThrow() {
151151
152152 private Thread createBotThread () {
153153 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 ();
163169 }
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+
172175 configuration .log ("Bot: Handling frame #" + game .getFrameCount ());
173176 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 ()) {
176189 frameBuffer .dequeue ();
177190 }
178191 }
@@ -184,21 +197,14 @@ private void handleEvents() {
184197 if (gameData .getFrameCount () > 0 || ! configuration .unlimitedFrameZero ) {
185198 performanceMetrics .botResponse .startTiming ();
186199 }
200+
187201 // Populate gameOver before invoking event handlers (in case the bot throws)
188202 for (int i = 0 ; i < gameData .getEventCount (); i ++) {
189203 gameOver = gameOver || gameData .getEvents (i ).getType () == EventType .MatchEnd ;
190204 }
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 ));
202207 }
208+ performanceMetrics .botResponse .stopTiming ();
203209 }
204210}
0 commit comments