OO Programming in Java
Class 8 Material
Threaded State Machine
Sometimes is might be useful for each 'output' routine in a state machine to run in a separate thread. Here's how to do it....
// PAStateMachine support routines public void playNumber() { new PlayNumber(this); } public void playSlip() { new PlaySlip(this); }
// PAStateMachine support classes class PlayNumber implements Runnable { private Thread thread_; private PlayAssistant playAssistant_; PlayNumber(PlayAssistant thePA) { playAssistant_ = thePA; thread_ = new Thread(this); thread_.start(); } public void run() { (Runner.instance().playNumber(playAssistant_); } } class PlaySlip implements Runnable { private Thread thread_; private PlayAssistant playAssistant_; PlaySlip(PlayAssistant thePA) { playAssistant_ = thePA; thread_ = new Thread(this); thread_.start(); } public void run() { (Runner.instance().playSlip(playAssistant_); } }
class TheRunner { // this class allows syncronization for the state machine... public synchronized void playNumber (PlayAssistant thePA) { thePA.updateSpeechControlFile("Green Light"); MessageSlip aSlip = thePA.messageSlipQueue().current(); Talker.instance().announce ("Message " + String.valueOf ( thePA.messageSlipQueue().messageNumber())); // do we need to do something faster here? ... // like checking for abort like we used to ... if (thePA.messageSlipQueue().current().handled()) { Talker.instance().announce("Erased"); } if (thePA.speechControlFileIsRed()) { thePA.abort(); } else thePA.done(); } public synchronized void playSlip (PlayAssistant thePA) { String fileName = (String) thePA.messageSlipQueue().current() .messageBlockFileNames().elementAt(0); MessageBlock theBlock = MessageBlock.fromFile(fileName); Talker.instance().announce(thePA .messageSlipQueue().current()); if (thePA.speechControlFileIsRed()) thePA.abort(); else thePA.done(); }
// PlayAssistant Routines.public void done() { this.paStateMachine().currentState().done(this); } public void abort() { this.updateSpeechControlFile ("Green Light"); this.paStateMachine().currentState().abort(this); }