statecharts and object orientation everything you always wanted to know –but were afraid to ask
Post on 19-Dec-2015
213 views
TRANSCRIPT
active
modeservice
active
quick
intense
on
washing
rinsing
dryingopen
off
normal>
faulty
H
DONE
DONE
evMode
evMode
tm(1000)/--dryTime;
tm(1000)/--rinseTime;
tm(1000)/--washTime;
[isDried()]/cycles++;evClose
evStart[IS_IN(normal)]/setup();
evOpen
[isInNeedOfService()]
evService
evService
Transitions• Default Transition
– No events or conditions
– Can have actions
• Regular transition– Event[condition]/action
– tm() is an event
• Null transition– [condition]
active idleidleactive evGo[ready]/doit();
What happens when evGo is taken?
• Condition is evaluated– Is ready true?
• If condition is true, actions on exit from state active are executed– In this case there aren’t any
• object exits state “active” • actions on transition are executed
– /doit()
• object enters state “idle”• Object executes action on entry to state “idle”
– In this case there aren’t any
timeout
rinsingrinsing
tm(1000)/--rinseTime;
• object enters state “rinsing”
• timer is set: set tm(1000)
• tm(1000) occurs 1000 ms later
Null Transition
isRinsed() is a guard on null transition
isRinsed() is evaluated every time object takes event
rinsing washing[isRinsed()]
rinsing washing
tm(1000)/--rinseTime
[isRinsed()]
/rinseTime=2;
Timeout with Null Transition
isRinsed() is a guard on null transition
Boolean isRinsed() {return(0==rinseTime);}
isRinsed() is evaluated every time tm(1000) occurs
If “rinsing” is entered for the first time at 0000, at what time(s) is isRinsed() invoked?
Timeout with guarding Condition
If “rinsing” is entered for the first time at 0000, at what time(s) is isRinsed() invoked?
rinsing washingC
[else]/--rinseTime
[isRinsed()]
/rinseTime=2;
tm(1000)
Or-states (1)
quickMode>
normalMode>
intensiveMode>quickMode>
normalMode>
intensiveMode>
evNormal
evNormal
evQuickevQuick
evIntensive
evIntensive
idle
running
pulsingspraying
evJ etPulseevJ etOffevJ etSpray
Or-states (2)-transition from superStates
• Object is in state “pulsing”
• Object takes event “evJetOff”
• What happens?
Or-states (3)-transition to superStates
• Object is in state “idle”
• Object takes event “evX”
• What happens?
idle
running
pulsingspraying
evJ etPulseevJ etOffevJ etSpray evX
Or-states (4)-transition to history
• Object is in state “rinsing”
• Object takes event “evOpen”
• What happens?• Object takes event• “evClose”• What happens?
activeactive
idle
busy
polling
evGo
tm(3000)
tm(2000)/GEN(evGo)
and-states(1)
event generated in one state, used in another • What is the
default state of the object?
• If startBehavior finished at 0000, what happens between 0000 and 7000?
active
runningmaintenance
mode
active
doorOpened>
doorClosed
filling>
rinsing>
washing>
draining>
off>
drying>
maintenanceOk>
maintenanceRequired>
quickMode>
normalMode>
intensiveMode>
DONE
DONE
H
tm(dryTime)
evFull
tm(washTime)
tm(rinseTime)
evStart/setup();
evEmpty
evOpen
evClose
evService[isInNeedOfService()]
evService
evNormal
evNormal
evQuickevQuick
evIntensive
evIntensive
and-states(2)what is default state?
Events sent between objects
full>
draining
empty>
filling
tm(4000)/itsDishwasher->GEN(evFull);
tm(4000)/itsDishwasher->GEN(evEmpty); evTankDrain
evTankFill
fillingoff rinsing
evStart/itsTank->GEN(evFill)
evFull
Dishwasher
TankDishwasher takes event evStart.
What happens?
Tracer Commands• output
– output mytrace.txt
• timestamp– OMTracer (0:00:00.000)
• go– Run
• go idle– takes next event in queue
– if no event in queue, but there is a scheduled timeout, advances clock and takes timeout event
Tracer Messages (1)• Invoked
– Dishwasher[0] Invoked isInNeedOfService()
• Returned– Dishwasher[0]->isInNeedOfService() Returned
• set tm()– Dishwasher[0] set tm(10000) at ROOT.active.running.doorClosed.rinsing
• Sent Event– Dishwasher[0] Sent to AcmeTank[0] Event evTankFill()
• Received Event– AcmeTank[0] Received from Dishwasher[0] Event evTankFill()
• Note: object can send event to itself– AcmeTank[0] Sent to itself Event tm(4000) at ROOT.filling– AcmeTank[0] Received from itself Event tm(4000) at ROOT.filling
• Object entered state– Dishwasher[0] Entered State ROOT.active
• Object exited state– Dishwasher[0] Exited State ROOT.active.mode.normalMode
Tracer Messages (2)• object cancelled timeout
– AcmeJet[0] cancelled tm(1000) at ROOT.running.pulsing.left
– When does this occur?
• Object modified Attribute values – Dishwasher[0] Modified Attribute Values
dryTime 3000
washTime 8000
cycles 1
rinseTime 10000
Start Behavior (1)
• Object enters root state – Display[0] enters ROOT
• Object enters each sub-state– Display[0] enters ROOT.active
• For each state entered, object executes entry actions (if there are any)
• Object executes actions on default transition (if there are any)
Start Behavior (2)
• If the initial state has an exit transition triggered by timeout:– Object does set tm() when state entered
• If there is a state with a null transition:– Object sends OMStartBehaviorEvent– After StartBehavior finishes, object receives
OMStartBehaviorEvent, and evaluates the condition on the null transition.
StartBehavior-countdown
OMTracer (0:00:00.000) main() Invoked Display[0]->Start Behavior
OMTracer (0:00:00.000) Display[0] Entered State ROOT
OMTracer (0:00:00.000) Display[0] Invoked print(string = started)
OMTracer (0:00:00.000) Display[0]->print(string = started) Returned
OMTracer (0:00:00.000) Display[0] Entered State ROOT.active
OMTracer (0:00:00.000) Display[0] set tm(200) at ROOT.active
OMTracer (0:00:00.000) Display[0]->Start Behavior Returned
StartBehavior-dishwasherOMTracer (0:00:00.000) main() Invoked Dishwasher[0]->Start BehaviorOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOTOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOT.activeOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOT.active.runningOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOT.active.running.doorClosedOMTracer (0:00:00.000) Dishwasher[0] Entered State ROOT.active.running.doorClosed.offOMTracer (0:00:00.100) Dishwasher[0] Entered State ROOT.active.modeOMTracer (0:00:00.100) Dishwasher[0] Entered State ROOT.active.mode.normalModeOMTracer (0:00:00.100) Dishwasher[0] Entered State ROOT.active.maintenanceOMTracer (0:00:00.100) Dishwasher[0] Entered State ROOT.active.maintenance.maintenanceOkOMTracer (0:00:00.100) Dishwasher[0] Sent to itself Event OMStartBehaviorEventOMTracer (0:00:00.100) Dishwasher[0]->Start Behavior ReturnedOMTracer (0:00:00.100) Dishwasher[0] Modified Attribute Values modeRinseTime 10000 modeWashTime 20000 modeDryTime 5000
After Start Behavior returns-dishwasher takes OMStartBehavior Event
(0:00:00.100) Dishwasher[0] Received from itself Event OMStartBehaviorEvent
(0:00:00.100) main() Invoked Dishwasher[0]->Take Event OMStartBehaviorEvent()
(0:00:00.100) Dishwasher[0] Invoked isInNeedOfService()
(0:00:00.100) Dishwasher[0]->isInNeedOfService() Returned
(0:00:00.100) Dishwasher[0]->Take Event OMStartBehaviorEvent() Returned
Take event-countdown(1)first cycle
Please enter OMTracer Command>> go idle
OMTracer (0:00:00.200) Display[0] Sent to itself Event tm(200) at ROOT.active
OMTracer (0:00:00.200) Display[0] Received from itself Event tm(200) at ROOT.active
OMTracer (0:00:00.200) main() Invoked Display[0]->Take Event Timeout
OMTracer (0:00:00.200) Display[0] Invoked isDone()
OMTracer (0:00:00.200) Display[0]->isDone() Returned
OMTracer (0:00:00.200) Display[0] Exited State ROOT.active
OMTracer (0:00:00.200) Display[0] Invoked print(n = 1)
OMTracer (0:00:00.200) Display[0]->print(n = 1) Returned
OMTracer (0:00:00.200) Display[0] Entered State ROOT.active
OMTracer (0:00:00.200) Display[0] set tm(200) at ROOT.active
OMTracer (0:00:00.200) Display[0]->Take Event Timeout Returned
Executable is Idle
Take event-countdown(2)termination
Please enter OMTracer Command>> go idleOMTracer (0:00:00.400) Display[0] Sent to itself Event tm(200) at ROOT.activeOMTracer (0:00:00.400) Display[0] Received from itself Event tm(200) at ROOT.activeOMTracer (0:00:00.400) main() Invoked Display[0]->Take Event TimeoutOMTracer (0:00:00.400) Display[0] Invoked isDone()OMTracer (0:00:00.400) Display[0]->isDone() ReturnedOMTracer (0:00:00.400) Display[0] Exited State ROOT.activeOMTracer (0:00:00.400) Display[0] Invoked print(n = 0)OMTracer (0:00:00.400) Display[0]->print(n = 0) ReturnedOMTracer (0:00:00.400) Display[0] Invoked print(string = Done)OMTracer (0:00:00.400) Display[0]->print(string = Done) ReturnedOMTracer (0:00:00.400) Display[0] Reached Termination StateOMTracer (0:00:00.400) Display[0]->Take Event Timeout ReturnedOMTracer (0:00:00.400) main() Invoked Display[0]->~Display()OMTracer (0:00:00.400) Display[0]->~Display() ReturnedOMTracer (0:00:00.400) Instance Display[0] of class Display deleted by main() Executable is Idle
off filling> rinsingevFull
evStart/setup(); state filling:
action on entry:itsTank->GEN(evTankFill)
Take event-dishwasherDishwasher takes evStart
full>
draining
empty>
filling
tm(4000)/itsDishwasher->GEN(evFull);
tm(4000)/itsDishwasher->GEN(evEmpty); evTankDrain
evTankFill
Take event-dishwasher(1)Dishwasher takes evStart
Please enter OMTracer Command>> go idleOMTracer (0:00:00.100) <user via GUI> Sent to Dishwasher[0] Event evStart()OMTracer (0:00:00.100) Dishwasher[0] Received from <user via GUI> Event evStart() Executable is IdleOMTracer (0:00:00.100) main() Invoked Dishwasher[0]->Take Event evStart()OMTracer (0:00:00.100) Dishwasher[0] Exited State
ROOT.active.running.doorClosed.offPlease enter OMTracer Command>> go idleOMTracer (0:00:00.100) Dishwasher[0] Invoked setup()OMTracer (0:00:00.100) Dishwasher[0]->setup() ReturnedOMTracer (0:00:00.100) Dishwasher[0] Modified Attribute Values dryTime 3000 washTime 8000 cycles 1 rinseTime 10000
OMTracer (0:00:00.100) Dishwasher[0] Entered State
ROOT.active.running.doorClosed.fillingOMTracer (0:00:00.100) Dishwasher[0] Sent to AcmeTank[0] Event evTankFill()OMTracer (0:00:00.100) Dishwasher[0] Invoked isInNeedOfService()OMTracer (0:00:00.100) Dishwasher[0]->isInNeedOfService() ReturnedOMTracer (0:00:00.100) Dishwasher[0]->Take Event evStart() Returned
Take event-dishwasher(2)Dishwasher takes evStart
OMTracer (0:00:00.100) AcmeTank[0] Received from Dishwasher[0] Event evTankFill()OMTracer (0:00:00.200) main() Invoked AcmeTank[0]->Take Event evTankFill()OMTracer (0:00:00.200) AcmeTank[0] Exited State ROOT.emptyOMTracer (0:00:00.200) AcmeTank[0] Entered State ROOT.fillingOMTracer (0:00:00.200) AcmeTank[0] set tm(4000) at ROOT.fillingOMTracer (0:00:00.200) AcmeTank[0]->Take Event evTankFill() Returned Executable is IdlePlease enter OMTracer Command>> go idleOMTracer (0:00:04.200) AcmeTank[0] Sent to itself Event tm(4000) at ROOT.fillingOMTracer (0:00:04.200) AcmeTank[0] Received from itself Event tm(4000) at
ROOT.fillingOMTracer (0:00:04.200) main() Invoked AcmeTank[0]->Take Event TimeoutOMTracer (0:00:04.200) AcmeTank[0] Exited State ROOT.fillingOMTracer (0:00:04.200) AcmeTank[0] Sent to Dishwasher[0] Event evFull()OMTracer (0:00:04.300) Dishwasher[0] Received from AcmeTank[0] Event evFull()OMTracer (0:00:04.300) main() Invoked Dishwasher[0]->Take Event evFull()OMTracer (0:00:04.300) Dishwasher[0] Exited State
ROOT.active.running.doorClosed.fillingOMTracer (0:00:04.300) Dishwasher[0] Entered State
ROOT.active.running.doorClosed.rinsing
Sequence Diagrams
• System Line (for main)
• Instance lines (for each object)
• Time goes from top to bottom
• Events- slanted line between objects
• Operations- horizontal line between objects
• object can send to itself– Events, operations, timeouts
off filling> rinsingevFull
evStart/setup(); state filling:
action on entry:itsTank->GEN(evTankFill)
Dishwasher
full>
draining
empty>
filling
tm(4000)/itsDishwasher->GEN(evFull);
tm(4000)/itsDishwasher->GEN(evEmpty); evTankDrain
evTankFill