(temp < 32)
if (temp < 32) { // SOLID water } else { // not SOLID water. is (LIQUID | GAS) }
if (temp < 32) {
} else {
}
if (temp > 212) { // GAS water } else { // not GAS water. is (SOLID | LIQUID) }
if (temp > 212) {
} else {
}
if (temp < 32) { // SOLID water } else { // not SOLID water. is (LIQUID | GAS) + (PLASMA?) // how did PLASMA get in here?? } if (temp > 212) { // GAS water + (PLASMA) // again with the PLASMA!! } else { // not GAS water. is (SOLID | LIQUID) }
class WaterSample { temp:int Water(temp:int) { this.temp = temp } // gas -> solid func depose() { // If not in GAS state, throw an error if (temp < WATER_GAS_TEMP) throw new IllegalStateError() // do depose while (temp > WATER_SOLID_TEMP) decreaseTemp(1) } // gas -> liquid func condense() { // If not in GAS state, throw an error if (temp < WATER_GAS_TEMP) throw new IllegalStateError() // do condense while (temp > WATER_GAS_TEMP) decreaseTemp(1) } // liquid -> gas func vaporize() { // If not in LIQUID state, throw an error if (!(temp < WATER_GAS_TEMP && temp > WATER_SOLID_TEMP)) throw new IllegalStateError() // do vaporize while (temp < WATER_GAS_TEMP) increaseTemp(1) } // liquid -> solid func freeze() { // If not in LIQUID state, throw an error if (!(temp < WATER_GAS_TEMP && temp > WATER_SOLID_TEMP)) throw new IllegalStateError() // do freeze while (temp > WATER_SOLID_TEMP) decreaseTemp(1) } // solid -> liquid func melt() { // If not in SOLID state, throw an error if (temp > WATER_SOLID_TEMP) throw new IllegalStateError() // do melt while (temp < WATER_SOLID_TEMP) increaseTemp(1) } // solid -> gas func sublimate() { // If not in SOLID state, throw an error if (temp > WATER_SOLID_TEMP) throw new IllegalStateError() // do sublimate while (temp < WATER_GAS_TEMP) increaseTemp(1) } func getState():string { if (temp < WATER_SOLID_TEMP) return "SOLID" if (temp > WATER_GAS_TEMP) return "GAS" return "LIQUID" } }
// liquid -> solid if (!(temp < WATER_GAS_TEMP && temp > WATER_SOLID_TEMP)) throw new IllegalStateError()
temp
lower than GAS boundary temperaturetemp
greater than SOLID limit temperature (temp < WATER_GAS_TEMP && temp > WATER_SOLID_TEMP) // is liquid?
!(temp < WATER_GAS_TEMP && temp > WATER_SOLID_TEMP) // Seriously?
bool isLiquidWater = (temp < WATER_GAS_TEMP && temp > WATER_SOLID_TEMP) if (!isLiquidWater) throw new IllegalStateError()
class FrameEvent { var _msg:String var _params:Object var _return:Object FrameEvent(msg:String, params:Object = null) { _msg = msg _params = params } }
@|message| : - _msg @[param1] : [] @^ : _return
|buttonClick| // Select for a "buttonClick" event _msg [firstName] = "Mark" // Set firstName _params property to "Mark" ^ = "YES" // Set the _return object to "YES"
#MyController
class MyController {}
#MyController<br> -block 1- -block 2- -block 3-
#MyController // controller declaration -machine- // machine block $S1 // state declaration
class MyController { // -machine- var _state(e:FrameEvent) = S1 // initialize state variable // to $S1 func S1(e:FrameEvent) { // state $S1 does nothing } }
func MyState(e:FrameEvent);
myController._state(new FrameEvent("buttonClick"))
myController.sendEvent(new FrameEvent("buttonClick"))
class MyController { func buttonClick() { FrameEvent e = new FrameEvent("buttonClick") _state(e) return e._return } }
#MyController -interface- buttonClick ...
interface
block has many other features, but this example gives us a general idea of how this works. I will give a further explanation in the following articles of the series. #MyController // controller declaration -machine- // machine block $S1 // state declaration |e1| ^ // e1 event handler and return
_msg
attribute of a _msg
event, the FMN notation uses brackets of vertical lines: |messageName|
class MyController { // #MyController // -machine- var _state(e:FrameEvent) = S1 func S1(e:FrameEvent) { // $S1 if (e._msg == "e1") { // |e1| return // ^ } } }
#MyController
class Mono { String status() { return "OFF" } }
#Mono -machine- $Working |status| ^("OFF")
class Mono { // #Mono // -machine- var _state(e:FrameEvent) = Working // initialize start state func Working(e:FrameEvent) { // $Working if (e._msg == "status") { // |status| e._return = "OFF" return // ^("OFF") } } }
^(return_expr)
@^ = return_expr
^ = return_expr
^(return_expr)
looks the most expressive. class Switch { boolean _isOn; func status() { if (_isOn) { return "ON"; } else { return "OFF"; } } }
#Switch1 -machine- $Off |status| ^("OFF") $On |status| ^("ON")
class Switch1 { // #Switch1 // -machine- var _state(e:FrameEvent) = Off func Off(e:FrameEvent) { // $Off if (e._msg == "status") { // |status| e._return = "OFF" return // ^("OFF") } } func On(e:FrameEvent) { // $On if (e._msg == "status") { // |status| e._return = "ON" return // ^("ON") } } }
->> $NewState
#Switch2 -machine- $Off |toggle| ->> $On ^ |status| ^("OFF") $On |toggle| ->> $Off ^ |status| ^("ON")
class Switch2 { // #Switch2 // -machine- var _state(e:FrameEvent) = Off func Off(e:FrameEvent) { if (e._msg == "toggle") { // |toggle| _state = On // ->> $On return // ^ } if (e._msg == "status") { // |status| e._return = "OFF" return // ^("OFF") } } func On(e:FrameEvent) { if (e._msg == "toggle") { // |toggle| _state = Off // ->> $Off return // ^("OFF") } if (e._msg == "status") { // |status| e._return = "ON" return // ^("ON") } } }
#Switch3 -machine- $Off |turnOn| ->> $On ^ |toggle| ->> $On ^ |status| ^("OFF") $On |turnOff| ->> $Off ^ |toggle| ->> $Off ^ |status| ^("ON")
class Switch3 { // #Switch3 // -machine- var _state(e:FrameEvent) = Off /********************************** $Off |turnOn| ->> $On ^ |toggle| ->> $On ^ |status| ^("OFF") ***********************************/ func Off(e:FrameEvent) { if (e._msg == "turnOn") { // |turnOn| _state = On // ->> $On return // ^ } if (e._msg == "toggle") { // |toggle| _state = On // ->> $On return // ^ } if (e._msg == "status") { // |status| e._return = "OFF" return // ^("OFF") } } /********************************** $On |turnOff| ->> $Off ^ |toggle| ->> $Off ^ |status| ^("ON") ***********************************/ func On(e:FrameEvent) { if (e._msg == "turnOff") { // |turnOff| _state = Off // ->> $Off return // ^ } if (e._msg == "toggle") { // |toggle| _state = Off // ->> $Off return // ^ } if (e._msg == "status") { // |status| e._return = "ON" return // ^("ON") } } }
$probeForState()
func probeForState():FrameState { if (temp < 32) return Solid if (temp < 212) return Liquid return Gas }
->> $probeForState()
_state = probeForState()
$S1 => $S2
func S1(e:FrameEvent) { S2(e) // $S1 => $S2 }
#Movement -machine- $Walking => $Moving |getSpeed| ^(3) |isStanding| ^(true) $Running => $Moving |getSpeed| ^(6) |isStanding| ^(true) $Crawling => $Moving |getSpeed| ^(.5) |isStanding| ^(false) $AtAttention => $Motionless |isStanding| ^(true) $LyingDown => $Motionless |isStanding| ^(false) $Moving |isMoving| ^(true) $Motionless |getSpeed| ^(0) |isMoving| ^(false)
class Movement { // #Movement // -machine- /********************************** $Walking => $Moving |getSpeed| ^(3) |isStanding| ^(true) ***********************************/ func Walking(e:FrameEvent) { if (e._msg == "getSpeed") { e._return = 3 return } if (e._msg == "isStanding") { e._return = true return } Moving(e) // $Walking => $Moving } /********************************** $Running => $Moving |getSpeed| ^(6) |isStanding| ^(true) ***********************************/ func Running(e:FrameEvent) { if (e._msg == "getSpeed") { e._return = 6 return } if (e._msg == "isStanding") { e._return = true return } Moving(e) // $Running => $Moving } /********************************** $Crawling => $Moving |getSpeed| ^(.5) |isStanding| ^(false) ***********************************/ func Crawling(e:FrameEvent) { if (e._msg == "getSpeed") { e._return = .5 return } if (e._msg == "isStanding") { e._return = false return } Moving(e) // $Crawling => $Moving } /********************************** $AtAttention => $Motionless |isStanding| ^(true) ***********************************/ func AtAttention(e:FrameEvent) { if (e._msg == "isStanding") { e._return = true return } Motionless(e) // $AtAttention => $Motionless } /********************************** $LyingDown => $Motionless |isStanding| ^(false) ***********************************/ func LyingDown(e:FrameEvent) { if (e._msg == "isStanding") { e._return = false return } Motionless(e) // $AtAttention => $Motionless } /********************************** $Moving |isMoving| ^(true) ***********************************/ func Moving(e:FrameEvent) { if (e._msg == "isMoving") { e._return = true return } } /********************************** $Motionless |getSpeed| ^(0) |isMoving| ^(false) ***********************************/ func Motionless(e:FrameEvent) { if (e._msg == "getSpeed") { e._return = 0 return } if (e._msg == "isMoving") { e._return = false return } } }
#WaterSample -machine- $Begin |create| // set temp to the event param value setTemp(@[temp]) // probe for temp state and change to it ->> $probeForState() ^ $Solid => $Default |melt| doMelt() ->> $Liquid ^ |sublimate| doSublimate() ->> $Gas ^ |getState| ^("SOLID") $Liquid => $Default |freeze| doFreeze() ->> $Solid ^ |vaporize| doVaporize() ->> $Gas ^ |getState| ^("LIQUID") $Gas => $Default |condense| doCondense() ->> $Liquid ^ |depose| doDepose() ->> $Solid ^ |ionize| doIonize() ->> $Plasma ^ |getState| ^("GAS") $Plasma => $Default |recombine| doRecombine() ->> $Gas ^ |getState| ^("PLASMA") $Default |melt| throw new InvalidStateError() |sublimate| throw new InvalidStateError() |freeze| throw new InvalidStateError() |vaporize| throw new InvalidStateError() |condense| throw InvalidStateError() |depose| throw InvalidStateError() |ionize| throw InvalidStateError() |recombine| throw InvalidStateError() |getState| throw InvalidStateError()
temp
. The probe function first checks the initial value temp
to determine the logical state, and then performs the transition of the machine to this state. class WaterSample { // -machine- var _state(e:FrameEvent) = Begin /********************************** $Begin |create| // set temp to the event param value setTemp(@[temp]) // probe for temp state and change to it ->> $probeForState() ^ ***********************************/ func Begin(e:FrameEvent) { if (e._msg == "create") { setTemp(e["temp"]) _state = probeForState() return } } /********************************** $Solid => $Default |melt| doMelt() ->> $Liquid ^ |sublimate| doSublimate() ->> $Gas ^ |sublimate| ^("SOLID") ***********************************/ func Solid(e:FrameEvent) { if (e._msg == "melt") { doMelt() _state = Liquid return } if (e._msg == "sublimate") { doSublimate() _state = Gas return } if (e._msg == "getState") { e._return = "SOLID" return } Default(e) } /********************************** $Liquid => $Default |freeze| doFreeze() ->> $Solid ^ |vaporize| doVaporize() ->> $Gas ^ |getState| ^("LIQUID") ***********************************/ func Liquid(e:FrameEvent) { if (e._msg == "freeze") { doFreeze() _state = Solid return } if (e._msg == "vaporize") { doVaporize() _state = Gas return } if (e._msg == "getState") { e._return = "LIQUID" return } Default(e) } /********************************** $Gas => $Default |condense| doCondense() ->> $Liquid ^ |depose| doDepose() ->> $Solid ^ |ionize| doIonize() ->> $Plasma ^ |getState| ^("GAS") ***********************************/ func Gas(e:FrameEvent) { if (e._msg == "condense") { doCondense() _state = Liquid return } if (e._msg == "depose") { doDepose() _state = Solid return } if (e._msg == "ionize") { doIonize() _state = Plasma return } if (e._msg == "getState") { e._return = "GAS" return } Default(e) } /********************************** $Plasma => $Default |recombine| doRecombine() ->> $Gas ^ |getState| ^("PLASMA") ***********************************/ func Plasma(e:FrameEvent) { if (e._msg == "recombine") { doRecombine() _state = Gas return } if (e._msg == "getState") { e._return = "PLASMA" return } Default(e) } /********************************** $Default |melt| throw new InvalidStateError() |sublimate| throw new InvalidStateError() |freeze| throw new InvalidStateError() |vaporize| throw new InvalidStateError() |condense| throw InvalidStateError() |depose| throw InvalidStateError() |ionize| throw InvalidStateError() |recombine| throw InvalidStateError() |getState| throw InvalidStateError() ***********************************/ func Default(e:FrameEvent) { if (e._msg == "melt") { throw new InvalidStateError() } if (e._msg == "sublimate") { throw new InvalidStateError() } if (e._msg == "freeze") { throw new InvalidStateError() } if (e._msg == "vaporize") { throw new InvalidStateError() } if (e._msg == "condense") { throw new InvalidStateError() } if (e._msg == "depose") { throw new InvalidStateError() } if (e._msg == "ionize") { throw new InvalidStateError() } if (e._msg == "recombine") { throw new InvalidStateError() } if (e._msg == "getState") { throw new InvalidStateError() } } }
Source: https://habr.com/ru/post/446330/
All Articles