|
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]] ] |