State variables may have associated state transitions.
Note: If you are new to state variables, see State Variables.
State transitions occur when the value of a state variable changes. These transitions are explicitly handled with a transition element inside of a state element which references the state variable. See transition, state. Whatever is declared inside a particular transition element occurs when the associated state variable 'transitions' to the value declared for that transition. This includes running any scripts and displaying any visual elements declared in the transition element. See Visual Elements. If the state variable transitions away to a different value, then any visual elements declared in the transition element are no longer painted on the device screen.
Note: Visual elements in a state transition that are no longer being painted may continue to show on the device display unless the UJML application is painting something else at that location. For this reason, it is always a good idea to use a colored backdrop which fills the screen in your applications. See Visual Elements, background.ujms sample.
State transitions are similar to subroutines in the sense that they control branches to a transition when they occur (through the 'calling code' changing a state variable) and branches back when the transition has been executed. See Execution Order.
State transitions are different from subroutines in the sense that transitions contain both procedural (scripting) and declarative elements. A procedural element is executed once when the state transition occurs (like a subroutine), but a declarative element turns 'on' when the state transition occurs and stays on until the state transitions away. Declarative elements include things like visual elements and sounds. See Visual Elements, Audio Elements.
For example, if a state transition declares a visual element like a box, that box appears on the device screen when the state transition occurs and is no longer drawn on the device screen when the state transitions out (see above). In the same way, an event handler inside that box is active only when the state transition is active and stops accepting events when the state transitions out. See Handling Events.
When the transition becomes active and visual elements are displayed, the current values of any variables referred to in the visual element declaration are used. In this way, you can determine, for example, the position or text of a label element by setting the appropriate variables and then setting the state variable to a value activating that transition. If the variables change after the state becomes active, the label is not affected—it stays in the same position displaying the same text. Only if the state transitions out (hiding the label) and back (showing the label), will any new values for the variables be used.
It is possible to delay execution of a scripting element in a transition. See Delayed Execution in Transitions, Scripting. However, all non-scripting UJML code in a transition is still executed immediately when the transition occurs and control still branches back to calling code. This means that the delayed script is executed later, in a manner similar to an event; but any visual elements in the transition will display right away, any audio elements will play right away, and so on.
The variable values used by delayed script elements are the current variable values when the script is executed, not the values at the time the state transition occurred. Depending on your code and the length of the delay, there is a chance that the values will be different.
The scripting code in a state transition may change variables and state variables in the same module scope as the transition declaration. See Data Scoping and Sharing. This means that changing a state variable may have side effects because the module is in a different state after the state variable was changed than before it was changed. See Side Effects.
For a boolean state variable, you can only declare two possible transitions: true and false. Other data types may contain a range of thousands of possible values. See Data Types. You can declare a transition element for each possible state value for which you want to do something or show something on the screen. When a state variable is set to the value declared for a state transition, that transition occurs and becomes 'active'.
However, the nature of state transitions is such that only one transition within a state element may be active at a time. When a state transition occurs for one state variable value, any existing active state transition for that state variable must 'transition out' and become inactive. In this way, you can have one state variable with as many different possible states as you need, only one of which is active at a time.
When a state variable is an array you can specify which element of the state variable array the transitions apply to using the index attribute of the state element. For example '<state var="sFoo" index="1, 3">'. In this case, the transition elements contained in that state element apply only when that particular index is changed. For example, 'sFoo[1][3] = true' applies to the above state element and 'sFoo[2][1] = true' does not.
UJML provides a way to create 'default' states for a state variable array which apply to all elements of that array. In this case, you replace the element reference in the index attribute of the state element with asterisks ('*') for each dimension. For example, '<state var="sFoo" index="*,*">'. In this case, the transition elements contained in that state element apply to all elements of the state variable array. For example, 'sFoo[1][3] = true' applies to the above state element, as does 'sFoo[2][1] = true'.
You can retrieve the current index of a default state within a transition using the _state_index() function. See _state_index() function.
There are two ways to cause a state to transition out and become inactive. The first method is to simply change the state variable to a different value as described above. If you change it to a value for which a transition element exists, that transition will become active. But if you change it to a value for which no transition element exists, then no transition is active for that state element.
You can also cause a state to transition out without changing its value using the _clear_state() function. See _clear_state() function. This is useful when you need to refresh a transition to its current value. In that case, you would call the _clear_state() function with your state variable and then assign the state variable to itself.
State transitions may be declared in a separate partition from the one declaring the state variable. See Linking Files, Scope, Data Scoping and Sharing.
You can declare state transitions in an application or partition module for a public state variable which is contained by a state machine. See State Machines, Scope, Data Scoping and Sharing.
You may declare more than one state element for the same state variable. In each case, the state transitions contained in that state element will become active with the appropriate value. However, if there is more than one state transition element with the same state value, only the transition with the highest z-order will be active when the state variable is set to that value. See Z-Order. The others will be ignored. This applies to transitions inside of different state elements in the same module or shared across different modules. Linking Files, Scope, State Machines.
Because of the way UJML creates and uses variables, a UJML state transition is not re-entrant. Code inside of a state transition that clears the state variable and sets it back to the current state will reset any local variables in the state to their initial values and start executing the transition over again, leading to a possible infinite loop. For this reason, you cannot use state transitions recursively.
|
Topic |
Description |
|
State transitions may delay execution of a scripting element. |
The following example shows some text on the device screen when the 'sShow' state variable transitions to true. It is part of the transition1.ujml sample.
<ujml>
<application>
<state-variables>
<state-var name="sShow" type="boolean"/>
</state-variables>
<script>
sShow = true;
</script>
<states>
<state var="sShow">
<transition value="true">
<display>
<label><text>Hello World!</text></label>
</display>
</transition>
</state>
</states>
</application>
</ujml>
The following example shows how to use the integer state variable 'sShow' with transition elements for the values 1, 2, 3, and 4. The transitions display the word 'Foo' in a looping animation by using script and delay elements to set 'sShow' to the next value in the series after a short time. When the end of the series is reached, 'sShow' is set to the first value in the series, starting the animation over again. It is part of the transition2.ujml sample.
<ujml>
<application>
<state-variables>
<state-var name="sShow" type="int"/>
</state-variables>
<script>
sShow = 1;
</script>
<states>
<state var="sShow">
<transition value="1">
<display>
<label><text>F</text></label>
</display>
<delay>100</delay>
<script>sShow = 2;</script>
</transition>
<transition value="2">
<display>
<label><text>Fo</text></label>
</display>
<delay>100</delay>
<script>sShow = 3;</script>
</transition>
<transition value="3">
<display>
<label><text>Foo</text></label>
</display>
<delay>200</delay>
<script>sShow = 4;</script>
</transition>
<transition value="4">
<delay>100</delay>
<script>sShow = 1;</script>
</transition>
</state>
</states>
</application>
</ujml>
The following example shows how to use an array state variable to show a message multiple times on the device screen. Each time a state transition occurs it displays the message, waits for a short time, and then forces the next state transition to occur. The _state_index() function is used to determine the current state variable index and activate the next. It is part of the transition3.ujml sample.
<ujml>
<application>
<state-variables>
<state-var name="sShow" type="boolean" size="20"/>
</state-variables>
<script>
sShow[0] = true;
</script>
<states>
<state var="sShow" index="*">
<transition value="true">
<display>
<label>
<text>Hello World</text>
<x><eval>_state_index(0) * 10</eval></x>
<y><eval>_state_index(0) * 10</eval></y>
</label>
</display>
<delay>200</delay>
<script>
if (_state_index(0) &_LT; 19)
{
sShow[_state_index(0) + 1] = true;
}
</script>
</transition>
</state>
</states>
</application>
</ujml>
The following example shows how to use a state transition to create a 'slide show' by getting text from an array with an index variable. It contains a delayed script block which updates the index variable and calls the _clear_state() function to clear the associated state transition so setting the state variable to true causes the state transition to occur again even if the state variable is already true. It is part of the assignment.ujml sample.
<state var="sText">
<transition value="true">
<display>
<multi-label>
<text><eval>mMessages[mMessageIdx]</eval></text>
<width><eval>mScreenWidth</eval></width>
<height><eval>mScreenHeight</eval></height>
</multi-label>
</display>
<delay>&DELAY_MSEC;</delay>
<script>
// Set index for next message.
mMessageIdx = mMessageIdx + 1;
if (mMessageIdx &_GTE; &MESSAGE_COUNT;)
{
mMessageIdx = 0;
}
// Show next message.
_clear_state(sText);
sText = true;
</script>
</transition>
</state>Delayed Execution in Transitions, Data Types, Arrays, Literals and Constants, Data Scoping and Sharing, Script Expressions, User Defined Functions, Using Functions, Handling Events, Linking Files, Scope, State Machines, <state-var>, <state-variables>, <transition>, <state>, _state_index(), _clear_state(), transition1.ujml, transition2.ujml, transition3.ujml, assignment.ujml, background.ujms
|
Copyright (c) 2000-2007 UIEvolution, Inc. All rights reserved.
|
|
What do you think about this topic? Send feedback!
|