Version 2 of Object Oriented Moore Type State Models

Updated 2013-12-31 21:57:57 by gam
What:   oomoore package
Where:  http://repos.modelrealization.com/cgi-bin/fossil/mrtools/doc/tip/oomoore/wiki/intro.wiki 
        http://chiselapp.com/user/mangoa01/repository/mrtools/doc/tip/oomoore/wiki/intro.wiki 
Description:   The oomoore package defines a TclOO meta-class which
               can be used to create a state model class with specified state
               model behavior.

This package is a rework of the moore package to use new Tcl 8.6 object oriented capabilites.


Here's an example of a simple two state pump from a question that came up on C.L.T.

package require Tcl 8.6
# See http://repos.modelrealization.com/cgi-bin/fossil/mrtools
# to obtain the "oomoore" package.
package require oomoore

# This class embodies all the state behavior.

oomoore model create ::pump_operation {
    initialState PumpOff

    state PumpOff {} {
        chan puts "[self] is now off"
    }
    transition PumpOff - BelowLower -> PumpOn
    transition PumpOff - WithinLimits -> IG
    transition PumpOff - AboveUpper -> IG

    state PumpOn {} {
        chan puts "[self] is now on"
    }
    transition PumpOn - BelowLower -> IG
    transition PumpOn - WithinLimits -> IG
    transition PumpOn - AboveUpper -> PumpOff
}

# This class adds some variables and compares the new value of limits
# in order to signal the right event.
oo::class create ::reactorPump {
    superclass ::pump_operation

    constructor {{lower 10} {upper 100}} {
        next
        my variable lLimit
        set lLimit $lower
        my variable uLimit
        set uLimit $upper
    }

    method evalConcentration {conc} {
        my variable uLimit
        my variable lLimit
        if {$conc < $lLimit} {
            my signal BelowLower
        } elseif {$conc > $uLimit} {
            my signal AboveUpper
        } else {
            my signal WithinLimits
        }
    }
}

# Create an object
reactorPump create pump1
# We want to see the trace
pump1 loglevel info
puts "Initial state: [pump1 currentstate]"

# This sequence just increments a variable to show
# how an asychronous measurement would be reported into
# the "::pump1" object. Here, every second a new concentration is
# fed in.
set conc 0
proc raiseConcentration {who value} {
    global conc
    $who evalConcentration $conc
    incr conc $value
    if {$conc > 100} {
        set value -20
    } elseif {$conc <= 0} {
        set ::done 1
    }
    after 1000 [list raiseConcentration $who $value]
}
# Kick things off
raiseConcentration ::pump1 20

set ::done 0
vwait ::done