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);
    }