Prev Next

Example: Simulation Commands

This example demonstrates how we can use the Simulation window to observe Trace messages or send commands to control a StateMachine. Through the example, you can examine:

  • An attribute of a context - the member variable defined in the Class, which is the context of the StateMachine; these attributes carry values in the scope of the context for all state behaviors and transition effects, to access and modify
  • Each attribute of a Signal - the member variable defined in the Signal, which is referenced by an Event and which can serve as an Event Parameter; each Signal Event occurrence might have different instances of a Signal
  • The use of the 'Eval' command to query the runtime value of a context's attribute
  • The use of the 'Dump' command to dump the current state's active count; it can also dump the current event deferred in the pool

This example is taken from the EAExample model:

     Example Model.Model Simulation.Executable StateMachine.Simulation Commands

Access From the ribbon:

  • Simulate > Core > Events    (for the Simulation Events window)
  • Simulate > Dynamic Simulation > Open Simulation Window)

These two windows are frequently used together in the simulation of Executable StateMachines.

Create Context and StateMachine

In this section we will create a Class called TransactionServer, which defines a StateMachine as its behavior. We then create an Executable StateMachine Artifact as the simulation environment.

Create the Context of the StateMachine

  1. Create a Class element calledTransactionServer.
  2. In this Class, create an attribute called authorizeCnt with initial value 0.
  3. In the Project Browser, right-click on TransactionServer and select the 'Add | State Machine' option.

Create the StateMachine

  1. Create an Initial pseudostate called Initial.
  2. Transition to a State called idle.
  3. Transition to a State called busy, with the trigger NEW_REQUEST.
  4. Transition:
         -  To a Final pseudostate called Final, with the trigger QUIT
         -  Back to idle, with the trigger AUTHORIZED, with the effect "this.authorizeCnt++;"

Create a Deferred Event for the State busy

  1. Draw a self-transition for busy.
  2. Change the 'kind' of the transition to 'internal'.
  3. Specify the Trigger to be the event you want to defer.
  4. In the 'Effect' field, type 'defer();'.

Create a Signal and attributes

  1. Create a Signal element called RequestSignal.
  2. Create an attribute called requestType with type 'int'.
  3. Configure the Event NEW_REQUEST to reference RequestSignal.

Create the Executable StateMachine Artifact

  1. From the 'Artifacts' page of the Diagram Toolbox, drag an Executable StateMachine icon onto the diagram and call the element Simulation with Deferred Event.
  2. Ctrl+Drag theTransactionServer element from the Project Browser and drop it onto the Artifact as a property, with the name server.
  3. Set the language of the Artifact to JavaScript, which does not require a compiler (for the example; in production you could also use C, C++, C#, or Java, which also support Executable StateMachines).
  4. Click on the Artifact and select the 'Simulate > Executable > Statemachines > Generate, Build and Run' ribbon option.

Simulation window and Commands

When the simulation starts, idle is the current state.

The Simulation window shows that the Transition Effect, Entry and Do behavior is finished for state idle, and the StateMachine is waiting for a trigger.

Event Data via Values for Signal attributes

For the Trigger Signal Event NEW_REQUEST, the 'Trigger Parameter Entry' dialog displays to prompt for values for the listed attributes defined in the Signal RequestSignal, referenced by NEW_REQUEST.

Type the value '2' and click on the OK button. The Signal attribute values are then passed to invoked methods such as the State's behaviors and the Transition's effects.

These messages are output to the Simulation window:

     [03612562]      Waiting for Trigger

     [03611358]      Command: broadcast NEW_REQUEST.RequestSignal(2)

     [03611362]      [server:TransactionServer] Event Queued: NEW_REQUEST.RequestSignal(requestType:2)

     [03611367]      [server:TransactionServer] Event Dispatched: NEW_REQUEST.RequestSignal(requestType:2)

     [03611371]      [server:TransactionServer] Exit Behavior: ServerStateMachine_idle

     [03611381]      [server:TransactionServer] Transition Effect: idle__TO__busy_61772

     [03611390]      [server:TransactionServer] Entry Behavior: ServerStateMachine_busy

     [03611398]      [server:TransactionServer] Do Behavior: ServerStateMachine_busy

     [03612544]      [server:TransactionServer] Completion: TransactionServer_ServerStateMachine_busy

     [03612562]      Waiting for Trigger

We can broadcast events by double-clicking on the item listed in the Simulation Events window. Alternatively, we can type a command string in the text field of the Simulation window (underneath the toolbar).

     [03612562]      Waiting for Trigger

     [04460226]      Command: broadcast NEW_REQUEST.RequestSignal(3)

     [04460233]      [server:TransactionServer] Event Queued: NEW_REQUEST.RequestSignal(requestType:3)

     [04461081]      Waiting for Trigger

The Simulation message indicates that the event occurrence is deferred (Event Queued, but not dispatched). We can run further commands using the text field:

     [04655441]      Waiting for Trigger

     [04664057]      Command: broadcast NEW_REQUEST.RequestSignal(6)

     [04664066]      [server:TransactionServer] Event Queued: NEW_REQUEST.RequestSignal(requestType:6)

     [04664803]      Waiting for Trigger

     [04669659]      Command: broadcast NEW_REQUEST.RequestSignal(5)

     [04669667]      [server:TransactionServer] Event Queued: NEW_REQUEST.RequestSignal(requestType:5)

     [04670312]      Waiting for Trigger

     [04674196]      Command: broadcast NEW_REQUEST.RequestSignal(8)

     [04674204]      [server:TransactionServer] Event Queued: NEW_REQUEST.RequestSignal(requestType:8)

     [04674838]      Waiting for Trigger

dump: Query 'active count' for a State and Event pool

Type dump in the text field; these results display:

From the 'active count' section, we can see that busy is the active state (active count is 1).

Tips: For a Composite State, the active count is 1 (for itself) plus the number of active regions.

From the 'Event Pool' section, we can see that there are four event occurrences in the Event Queue. Each instance of the signal carries different data.

The order of the events in the pool is the order in which they are broadcasted.

eval: Query Run Time Value of the Context

     Trigger AUTHORIZED,

     [04817341]      Waiting for Trigger

     [05494672]      Command: broadcast AUTHORIZED

     [05494678]      [server:TransactionServer] Event Queued: AUTHORIZED

     [05494680]      [server:TransactionServer] Event Dispatched: AUTHORIZED

     [05494686]      [server:TransactionServer] Exit Behavior: ServerStateMachine_busy

     [05494686]      [server:TransactionServer] Transition Effect: busy__TO__idle_61769

     [05494687]      [server:TransactionServer] Entry Behavior: ServerStateMachine_idle

     [05494688]      [server:TransactionServer] Do Behavior: ServerStateMachine_idle

     [05495835]      [server:TransactionServer] Completion: TransactionServer_ServerStateMachine_idle

     [05495842]      [server:TransactionServer] Event Dispatched: NEW_REQUEST.RequestSignal(requestType:3)

     [05495844]      [server:TransactionServer] Exit Behavior: ServerStateMachine_idle

     [05495846]      [server:TransactionServer] Transition Effect: idle__TO__busy_61772

     [05495847]      [server:TransactionServer] Entry Behavior: ServerStateMachine_busy

     [05495850]      [server:TransactionServer] Do Behavior: ServerStateMachine_busy

     [05496349]      [server:TransactionServer] Completion: TransactionServer_ServerStateMachine_busy

     [05496367]      Waiting for Trigger

  • The transition from busy to idle is made, so we expect the effect to be executed
  • One event is recalled from the pool and dispatched when idle is completed, causing busy to become the active state
  • Type dump and notice that there are three events left in the pool; the first one is recalled and dispatched

     [05693348]      Event Pool: [

     [05693349]          NEW_REQUEST.RequestSignal(requestType:6),

     [05693351]          NEW_REQUEST.RequestSignal(requestType:5),

     [05693352]          NEW_REQUEST.RequestSignal(requestType:8),

     [05693354]      ]

Type eval server.authorizeCnt in the text field. This figure indicates that the run time value of 'server.authorizeCnt' is 1.

Trigger AUTHORIZED again. When the StateMachine is stable at busy, there will be two events left in the pool. Run eval server.suthorizeCnt again; the value will be 2.

Access Context's member variable from State behavior and Transition Effect

Enterprise Architect's Executable StateMachine supports simulation for C, C++, C#, Java and JavaScript.

For C and C++, the syntax differs from C#, Java and JavaScript in accessing the context's member variables. C and C++ use the pointer '->' while the others simply use '.'; however, you can always use this.variableName to access the variables. Enterprise Architect will translate it to this->variableName for C and C++.

So for all languages, simply use this format for the simulation:

     this.variableName

Examples:

In the transition's effect:

     this.authorizeCnt++;

In some state's entry, do or exit behavior:

     this.foo += this.bar;

Note: by default Enterprise Architect is only replacing 'this->' with 'this' for C and C++; For example:

     this.foo = this.bar + myObject.iCount + myPointer->iCount;

will be translated to:

     this->foo = this->bar + myObject.iCount + myPointer->iCount;

A complete list of commands supported

Since the Executable StateMachine Artifact can simulate multiple contexts together, some of the commands can specify an instance name.

run statemachine:

As each context can have multiple StateMachines, the 'run' command can specify a StateMachine to start with.

  • run instance.statemachine
  • run all.all
  • run instance
  • run all
  • run

For example:

     run

     run all

     run server

     run server.myMainStatemachine

broadcast & send event:

  • broadcast EventString
  • send EventString to instance
  • send EventString (equivalent to broadcast EventString)

For example:

     broadcast Event1

     send Event1 to client

dump command:

  • dump
  • dump instance

For example:

     dump

     dump server

     dump client

eval command:

  • eval instance.variableName

For example:

     eval client.requestCnt

     eval server.responseCnt

exit command:

  • exit

The EventString's format:

  • EventName.SignalName(argument list)

Note: the argument list should match the attributes defined in the signal by order.

For example, if the Signal defines two attributes:

  • foo
  • bar

Then these EventStrings are valid:

  • Event1.Signal1(10, 5)    --------- foo = 10; bar = 5
  • Event1.Signal1(10,)    --------- foo = 10; bar is undefined
  • Event1.Signal1(,5)    --------- bar = 10; foo is undefined
  • Event1.Signal1(,)    --------- both foo and bar are not defined

If the Signal does not contain any attributes, we can simplify the EventString to:

  • EventName