Accessing Battle Results
I see in 0.9.5 notes: "Added a basic output parser for RoboRunner. Challenge run progress information in the main window is now updated on the fly..."
Does this mean you took care of this listener thing yourself since I never actually did it? Or are you still lacking some way to get updated with RoboRunner's results (and/or confidence estimates) on the fly?
Also, I'd like to merge back whatever changes you made to RoboRunner, at least to the GitHub repo. I guess I'll just wait and take a look at the source after 0.9.6.
The only information the output parser extracts is a count of battles completed. It is not able to determine the scores, nor does it parse out the confidence. The only thing it provides is on-the-fly information on how many battles have been run, in order to update the progress in running a challenge. It was a way to do a little more, but does not take the place of having a listener that actually provides score information.
The changes to RoboRunner so far have been very minimal. My focus has been almost exclusively on RoboJogger. The changes I have made to RoboRunner include only the following:
- In BattleRunner, I made it so that getAllFutures(List<Future<String>>) could be interrupted in order to provide a way to stop RoboRunner. However, my particular implementation needs to be done in a better way than I did it. It sets a flag on InterruptedException that causes all remaining futures to be cancelled (it calls future.cancel(false) on all remaining futures). It needs to be improved such that it can safely call future.cancel(true) without potentially corrupting a score log, or have the futures be able to detect the stop request to shut down cleanly if running.
- In ScoreLog, I added an ReentrantLock that is locked whenever loadScoreLog(...) or saveScoreLog(...) is called. Thus, only a single score log can be loaded or saved at a time. This was necessary as both RoboRunner and RoboJogger call the loadScoreLog(...) method and thus it needed some kind of synchronization. I know it would be safe to load and save different score logs at the same time, but I decided that there would not be enough concurrent loading and saving for it to be worth the added complexity.
- In ScoreLog, I close the XMLEventReader and input stream after a ScoreLog is loaded. Not sure if this really matters or not in practice.
And that's it. Even though you may not have specifically designed it for being used by another program, RoboRunner is quite easy to interact with and it required very little modification to put my UI on top of it. Very nice.
I'm still losing chunks of score logs on rare occasions, and I have no idea why. I still need to add checks to ensure RoboRunner is cleanly shut down before exiting RoboJogger, but I've had data loss at a time when I was absolutely sure RoboRunner was finished running, so there is still a problem somewhere that needs to be solved. If I can track down that problem and take care of the other things noted above, I will be very close to having a non-beta-ish release.
I just made another change to RoboRunner that will be part of 0.9.7. Again, I kept it pretty minor, but that makes 4 minor things now, so I should probably put the source out there where you can get to it. The new change I made was to add isTerminated() methods to RoboRunner and BattleRunner. These new methods return whether or not the main thread pool and the callback pool are terminated (by checking isTerminated() on both thread pools and then feeding that info back up the hierarchy).
isTerminated() returns true on a thread pool when shutdown() has been called and all threads in the pool are done. This is important to RoboJogger in determining whether or not RoboRunner has finished shutting down before starting a new runner or allowing a user to exit the program.
Another alternative would be to add a shutdown method to RoboRunner that is blocking, but I didn't think that would work as well, so I didn't take that approach.