Script Blocks and Called Modules
This was mentioned in an earlier topic but deserves to be emphasized.
If an action trigger statement includes a transition to another state, then any called modules in the current state will be stopped before the script block executes. For example, do not write code like the following:
AState [ Obj = MyCalledModule(); { the called module does a Return(Self) } { When Obj becomes valid, run a subroutine then change states } If Valid(Obj) BState; [ Obj.MySubroutine(); { Too late. MyCalledModule has stopped and Obj is again Invalid } ] ] BState [ ]
The preceding example should have been written with an explicit transfer to BState using a ForceState() function in the script block.
AState [ Obj = MyCalledModule(); { the called module does a Return(Self) } If Valid(Obj); { no state transfer in the action trigger } [ Obj.MySubroutine(); { Obj still points to the called module } ForceState("BState"); { After the subroutine, change states } ] ] BState [ ]
A script may contain more than one ForceState statement, but it is only the last one executed that sets the state to which the module will switch.
This statement does not act as an immediate exit point from the script - the script will still run in its entirety. That said, the first ForceState will cause the current state to end and any reference to objects in that state will fail.
If the script trigger statement did not specify a destination state to transfer to, this function will stop the current state as if one had been specified.
IF statements are the standard tool for specifying the next state. Use ForceState rarely and only when significant effort would be required otherwise to control the flow from one state to another.