10 Steps to Creating Your First MiceOnABeam Script ◄Previous Next► Tutorial
Although MiceOnABeam has a set of very powerful modeling features, only three of these are essential to creating a script model, and in many cases are all you need. These three are the State, the Transition and the Choice Point.
A State is the key modeling feature used to partition the model for a script. When creating a new script model, one of the first things that must be done is to decide how to break down the design specification (i.e., what you want the script to do) into a set of one or more States.
One way to look at this is to examine the LSL Events that will be handled by the script. Events are things that happen in your virtual world; for example, someone arrives at the door of your house and touches the door to open it. For a particular event, is the required action or response always the same? If not, then this distinction can then serve as a basis for defining a separate state.
For example, if the script receives an event, say touch_start, in State S1, it will perform one set of actions (calculations and calling various functions), whereas if it is in State S2 when it receives a touch_start event it will perform a different set of actions. Further, if the script is in State S3, it is not expected to receive the touch_start event at all, and if it does, it will be simply ignored.
Users already familiar with LSL, and who only use the built-in default state, often seem to struggle with this; but the reality is that even without thinking in terms of state machines, the "state" of any such script is represented by the value of it's global variables. Typically only one of these globals is key to determing how events are to be handled, and it is this variable (i.e., it's values) that should be replaced by actual States.
A State in MiceOnABeam is represented by the graphic:
It can have an Entry Action which is a sequence of LSL statements that is executed whenever the state is newly entered, as well as an Exit Action which is executed whenever the state is exited.
A State can also have variables and functions which are only accessible within it's scope. The value of a State Variable persists between events.
MiceOnABeam also permits States to contain other States! In this way, a Composite State can serve as a high-level abstraction, with only the appropriate design details shown at every level of the model. Complex scripts can be nicely modularized in this way. A Composite State is represented by the icon placed on the state:
For more information see State Machine.
To specify that a script model is to respond to an LSL event, you use a Transition which defines an event handler. In the simplest case, a Transition has a source State, which identifies the State in which the event can be received, and a destination State which identifies the next State the script model should move to if the appropriate conditions are satisfied.
A Transition in MiceOnABeam is represented by a directed line as shown in the following graphic:
It's full set of attributes include:
Transition Source: The State the script must be in to receive the event; indicated by the State the Transition is drawn from.
Transition Event: This is the LSL Event which the Transition will respond to, and is also referred to as the Transition's Trigger. Each event has a set of parameters which contains the data that is provided to the script along with the event.
Guard Condition: This represents an additional constraint and is the condition under which the occurring event, if received, should be responded to. An LSL boolean expression is used for this which defaults to TRUE.
Transition Action: An action to take when the transition is fired, consisting of a set of LSL statements.
Transition Destination: The next State to proceed to after processing the event; indicated by the State the Transition arrow is pointing to.
So if in our model we start start in an Off State, and want to move to the On State when the touch_start event is received, we simply draw a transition from the Off state to the On State and assign the touch_start event to the Transition.
There are in fact several types of Transitions which are distinguished by the source and destination components of the Transition. The most significant of these is the handy Group Transition, which when drawn from a State's border acts as if the same Transition had been drawn from every State contained within that State's border. This can be used when the handling of an event is common to several States.
It's often the case when an event is received while a particular State is active, that a more complex set of conditions are required to determine which State to move to. A single Guard Condition as described above is insufficient to handle this case as it can only control the transition to a single State.
The Choice Point solves this by providing a decision point with multiple outgoing transitions, each with it's own Guard Condition. When a Choice Point is entered, the Guard Condition of each of it's outgoing transitions is evaluated in turn. The first transition whose Guard Condition evaluates to TRUE is then taken and the model moves to that transition's destination State.
A Choice Point (named C1) is represented by the following graphic:
In the following example a menu dialog with the three buttons, "Off", "Standby" and "Active" has been previously opened. The end-user can select one of three buttons putting the script into one of it's three major modes. Each mode (i.e., State), will have a different set of events (possibly overlapping) that the script will respond to.
The response from the menu dialog is the listen event. The model excerpt below shows how this response can be handled to direct the script model to the appropriate State.
Each of the three outgoing Transitions from the Choice Point would have a unique Guard Condition that tests the listen event's message argument for equality with "Off", "Standby" and "Active" respectively.
►It's important to note that a Choice Point is NOT the graphical analog for every LSL if... else if sequence of statements. It should ONLY be used when a decision has to be made as to which State to move to after receiving a particular event.
► Outgoing transitions of a Choice Point with multiple incoming transitions require the use of the EVENT_xxx functions to access the event's arguments. See Event Data for further details.
► Outgoing transitions of a Choice Point with only a single incoming transition (with a defined event) do not require the use of the EVENT_xxx functions to access the event's arguments. The argument names can be referenced directly!
For example, in the above example the Guard Condition for the Active Transition could be: message == "Active" in order to access the message argument of the listen event. On the other hand, to access the same message argument within the Entry Action code of the Active state, you would use: EVENT_STR("message").
The running MiceOnABeam-generated script always keeps track of the last State it was in when it receives and processes a new event.
Using the Group Transition feature you can specify a common event that will be handled when the script is in any one of a set of States. After processing the event you can have the script automatically return to the original State in which it received the event by using the History feature.
The distinction between Shallow vs. Deep History handles the case when the last State returned to is a Composite State.
With Shallow History the State returned to will re-initialize. With Deep History, the set of last active States within the Composite State's decomposition will all be re-entered right to the most deeply-nested State.
In effect, the use of a Group Transition along with History provides an "interrupt"-like mechanism for your scripts.
Shallow and Deep History modeling features are represented by the following graphics respectively:
In the following script model we have three States which lead the end-user through three sets of questions. Via the GetCurrentStats transition, the model can be queried at any time to get the current statistics on the questions that have been answered so far. The model then returns to it's previous State via the Deep History component.
In addition to supporting the standard set of LSL events, MiceOnABeam also provides a Completion Event (%%completion_event) which can be assigned to a Transition. This is used in conjunction with a Final State to indicate the completion of a sequence of events.
When a transition is taken to a Final State, the Composite State containing the Final State is considered to be completed, and a Completion Event is automatically generated for the Composite State. In order to handle the Completion Event, the Composite State must have an originating Transition whose event has been set to %%completion_event.
A Final State is represented by the following graphic:
A Terminate Point is used to immediately stop execution of the entire script. When a Transition is taken to a Terminate Point, the script is considered to be completed, and the running state of the script is set to FALSE.
A Terminate Point is represented by the following graphic:
10 Steps to Creating Your First MiceOnABeam Script ◄Previous Next► Tutorial