Design an UML State Machine
- Open the state diagram of CoinMachineStateMachine StateDiagram_1, in the Domain Diagram Editor
First, we create two superstates, called NormalMode and DiagnosticMode:
-
Select SuperState from the Palette and left-click in the Diagram Editor to create a superstate
-
Enter NormalMode as the name of the new SuperState in the New Resource Wizard
-
In the same way, create a SuperState called DiagnosticMode
-
Select Start from the palette and right-click in the Diagram Editor to create a start state (i.e., the default or initial state of the state machine)
-
In the Select mode, you can now re-size and re-position the states as usual in the Diagram Editor
- Select Relation from the Palette and insert a relation from the start state symbol to the superstate NormalMode
Now, we create nested states to define the behavior in the NormalMode
-
Select State from the Palette and left-click in the lower section of the NormalMode state to create a nested state in the superstate NormalMode
-
Enter the name Locked as name of the State in the New Resource Wizard
-
In the same way create the two nested states Locked and Empty in the NormalMode and the two nested states TestLock and TestCoin in the superstate DiagnosticMode
-
Select Start from the Palette and left-click in the lower section of the NormalMode state (see above) to create a default or start state
-
As before, select Relation from the Palette and create a relation from the start state to the state Locked
-
In the same way, create a start state in the DiagnosticMode and create a relation from this start state to the state TestLock
Next, we define the state transitions and events:
-
Select Relation from the Palette and create a relation from the state Locked to the state Unlocked
-
With Control+Click on the GUID of the newly created relation, you can now open the transition in the Resource Editor
-
In the Resource Editor, create a new Event for the transition from state Locked to Unlocked
-
Give the name Coin to the newly created event
-
Switch to the open StateDiagram_1 in the Diagram Editor and check that the transition from Locked to Unlocked is
now labeled 'Coin'
-
In the same way, create the following transition and events: Unlocked Empty Empty TestCoin TestLock
We want to create a condition that is only true if the machine is non-empty. Thereto, we introduce a variable stockItems that keeps track of the number of items left in the machine:
- Open CoinMachineStateMachine the Resource Editor
- Add a PrivateVariableField to the CoinMachineStateMachine
- Create a VariableField with name stockItems and with type
INTEGER
as field
Next, we add guards to transitions such that the corresponding transitions only fire if the guard evaluates to TRUE:
- By Control+Click on the transition Unlocked open the transition in the resource editor
- Use the Content Assist to create a new ModelGuardImpl named hasStockItems as guard of the transition (see above)
- Add a GreaterExpression as booleanExpression to the ModelGuardImpl
- Create an operand1 of type VariableFieldExpression with a fieldRef with the VariableField stockItems as field
- Create an operand2 of type LiteralExpression with value
- Close the booleanExpression:
Info
Note that the Boolean expression stockItems > 0
is now displayed to represent the condition of the guard
Next, we add actions that are executed together with transitions and introduce shared functions which can be used as actions by multiple transitions:
- Open CoinMachineStateMachine in the Resource Editor
- Create a new SharedFunction called lightOff as sharedFunction to CoinMachineStateMachine
- Create a new ManualFunctionImpl with viewName lightOff as functionImpl to the SharedFunction
- Add a transitionFunction of type SharedFunctionRef to the transition TestLock which uses the sharedFunction lightOff
When the event Refilled occurs, the variable stockItems (i.e, the private variable that counts the number of stock items) should be set to the initial numbers of items:
- Add a transitionFunction of type ModelFunctionImpl to the transition Empty
- Add a statement of type Assignment to the ModelFunctionImpl
- Insert a fieldRef with field stockItems
- Add an operand of LiteralExpression with value INITIAL_STOCK_ITEMS
Each time the machine is unlocked, the number of stock items should be decremented by one:
- Create a new ModelFunctionImpl named decrementStockItems as entryFunction of the state Unlocked
- Add an Assignment as statement with an operand of type DecExpression
- Add an operand of type VariableFieldExpression to the DecExpression
- Add a fieldRef of type FieldRef to the VariableFieldExpression and use stockItems as field
- Open the StateDiagram_1 in the Diagram Editor and check that all the actions are displayed correctly as shown above
We add a transition that is triggered by an event Diagnose from the NormalMode to the DiagnosticMode (i.e., a technician should be able to switch to this diagnose state from any state in the normal mode). To save the state of the machine before switching modes, we introduce a history state:
- Add a history state by selecting History from the Palette
- Insert a transition triggered by a new event Return from the DiagnosticMode to the history state
- Create a transition triggered by a new event Diagnose from the NormalMode to the DiagnosticMode
Since the state of the DiagnosticMode is not saved before returning to the NormalMode, the light should be switched off when entering the diagnostic mode:
- Open the CoinMachineStateMachine in the Resource Editor
- Add an entryFunction of type SharedFunctionRef to the DiagnosticMode and use lightOff as the sharedFunction
- The entry function is now displayed when selecting the DiagnosticMode in the Diagram Editor (see above)