Basic State Machines
[Previous]  [Next] 
|
User Manual [Previous]  [Next] Basic State MachinesA state machine has a fixed set of of values (called states) The state machine transitions from state to state by the occurrence of events. State machines are very useful for quickly defining a program's behaviour. In Umple, a state machine is modeled as a special type of attribute. In any class, simply specify the state machine name, and follow the name by a block starting with '{' and ending with '}'. This indicates to Umple that you are defining a state machine, and not an ordinary attribute. Within the block, you list the names of the various states. Each state is followed by a block, again indicated using '{' to start and '} to end. This block defines the details of a state. Details of each state can include:
Note that, in addition, you can specify code to be executed whenever an event is processed by using before or after directives. The following diagram shows a garage door state machine as a UML diagram. The Umple code for this is in the second example shown, and is further explained in the video below. Basic Garage Door Example// This example shows a simple state machine // without any actions or guards // // In the following, status is a state machine, // and acts like an attribute, whose value is set // by various events. // // Open, Closing, Closed, Opening and HalfOpen are // the possible values, or states, of status. // // buttonOrObstacle, reachBottom and reachTop are // events. These become generated methods that can // be called to cause a state change. // // To make the state diagram appear in // UmpleOnline, select 'Options' then choose // 'GraphViz State Diagram' class GarageDoor { status { Open { buttonOrObstacle -> Closing; } Closing { buttonOrObstacle -> Opening; reachBottom -> Closed; } Closed { buttonOrObstacle -> Opening; } Opening { buttonOrObstacle -> HalfOpen; reachTop -> Open; } HalfOpen { buttonOrObstacle -> Opening; } } } Load the above code into UmpleOnline Garage Door Example with Actions// This is a more fully-featured state machine for // a garage door corresponding to the diagram // above class Garage { Boolean entranceClear=true; GarageDoor { Closed { entry/{stopMotor();} entry/{triggerEnergySaveMode();} exit/ {triggerNormalEnergyMode();} pressButton -> /{turnLightOn();} Opening; } Opening { entry/{runMotorForward();} openingCompleted -> Open; } Open { entry/{stopMotor();} // do {wait(60000); turnLightOff();} pressButton [getEntranceClear()] -> Closing; } Closing { entry/{runMotorInReverse();} closingCompleted -> Closed; pressButton -> /{flashLightOn();} Opening; } } boolean runMotorInReverse() Java { System.out.println( "Running motor in reverse"); return true; } boolean runMotorInReverse() Python { print("Running motor in reverse") return True } boolean flashLightOn() Java { System.out.println("Flashing light on"); return true; } boolean flashLightOn() Python { print("Flashing light on") return True; } boolean turnLightOn() Java { System.out.println("Turning light on"); return true; } boolean turnLightOn() Python { print("Turning light on") return True } boolean turnLightOff() Java { System.out.println( "Turning light off"); return true; } boolean turnLightOff() Python { print("Turning light off") return True } boolean runMotorForward() Java { System.out.println( "Running motor forwards"); return true; } boolean runMotorForward() Python { print("Running motor forwards") return True } boolean triggerEnergySaveMode() Java { System.out.println( "Triggering Energy Saving Mode"); return true; } boolean triggerEnergySaveMode() Python { print("Triggering Energy Saving Mode") return True } boolean stopMotor() Java { System.out.println("Stopping motor"); return true; } boolean stopMotor() Python { print("Stopping motor") return True } boolean triggerNormalEnergyMode() Java { System.out.println( "Triggering Normal Energy Mode"); return true; } boolean triggerNormalEnergyMode() Python { print("Triggering Normal Energy Mode") return True } boolean waitawhile() Java { System.out.println("Waiting"); return true; } boolean waitawhile() Python { print("Waiting") return True } boolean test() Java { System.out.println("Testing"); return true; } boolean test() Python { print("Testing") return True } } // @@@skipcppcompile Load the above code into UmpleOnline YouTube Video with Additional ExplanationSyntaxstateMachine : [[enum]]  | [[inlineStateMachine]]  | [[referencedStateMachine]]  | [[activeDefinition]] //Issue 148 inlineStateMachine : [=queued]? [=pooled]? [~name] {  ( [[comment]]  | [[state]]  | [[trace]]  | [[mixsetDefinition]]  | [=||]  | [[standAloneTransition]]  )* } // An enum is a state machine that has no events // stateName is prefixed with ~ to match alphanumeric names only. // This is needed to solve issue 399, which is cause when a terminating } is parsed as part of the statename. enum : [~name:key] { [~stateName]? (, [~stateName])* } state : [=final]? [stateName] { [[stateInternal]]* } stateEntity- : [=||]  | [[mixsetDefinition]]  | [[entryOrExitAction]]  | [[autoTransition]]  | [[transition]]  | [[activity]]  | [[state]]  | [[displayColor]]  | [[trace]]  | ; autoTransition : [[activity]]? [[autoTransitionBlock]] // Autotransitions have no event. The transition is immediately taken // or taken after the do activity ends[[guard]]? -> [[action]]? // The action can come before or after the arrow autoTransitionBlock- : [[guard]]?  ( [[action]] -> | -> [[action]] | ->  ) [stateName] ; // A transition guard can come before or after the arrow // The order of guard and event definition can also be interchanged transition :  ( [[eventDefinition]] [[guard]]  | [[guard]] [[eventDefinition]]  | [=unspecified]? [[guard]]  | [[eventDefinition]]  )?  ( [[action]] ->  | -> [[action]]  | ->  ) [stateName] ; eventDefinition- : [[afterEveryEvent]] | [[afterEvent]] | [~event]  ( [[parameterList]]  )? // The timer in a timed event can be an number, variable, function() or function(num) afterEveryEvent- : afterEvery ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] ) afterEvent- : after ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] ) // An action can be executed on a transition, or on entry or exit action : / [[moreCode]]+ entryOrExitAction : [=type:entry|exit] [[guardCode]]? / [[moreCode]]+ // A do activity is long-lasting and can be interrupted activity : do [[moreCode]]+ guard : [ [[constraint]] ] |