Several compiler directives are available which can be inserted within the LSL code segments of a MiceOnABeam model. They provide for the following features:
Conditional compilation can be used to control the inclusion of blocks of LSL code within the generated code. This is very useful during the development of a model whereby certain code is included (for example for debug purposes) which ultimately must be excluded in the production version of the model.
To facilitate the conditional compilation of LSL code included within MiceOnABeam models, several compilation directives are supported.
The directives #define and #undef set the symbol names listed to TRUE and FALSE respectively and each line must be terminated with a "#". These symbols are maintained in a single global list and so can be accessed throughout the model.
The directive #if follows the standard C# convention, providing #elif (i.e., else if) and #else branches and must be terminated with an #endif. The operators ==, !=, && and || can be used to evaluate multiple symbols within a boolean expression. Parentheses can also be used to group symbols and operators.
- #define symbol1,symbol2,symbol3#
Set symbols symbol1, symbol2 & symbol3 all to TRUE.
- #undef symbol1,symbol2,symbol3#
Set symbols symbol1, symbol2 & symbol3 all to FALSE.
- #if aBooleanExpression
If aBooleanExpression evaluates to TRUE, the following lines till the next #elif/#else/#endif will be included within the generated LSL code.
- #elif aBooleanExpression
If the previous #if/#elif is false, and aBooleanExpression evaluates to TRUE, the following lines till the next #elif/#else/#endif will be included within the generated LSL code.
If the previous #if/#elif is false, the following lines till the next #endif will be included within the generated LSL code.
End of conditional compilation sequence.
For example, the following code will emit a trace statement on a variable only when the debug symbol is true. When the symbol is false, the trace statement is not included within the generated code.
Propagation of Code to Simple States
Compiler directives #leaf and #endleaf can be used within the Entry/Exit Action code of a Composite State to propagate LSL statements contained between the two directives to all it's contained Simple States.
LSl statements contained between the two directives and entered in the Entry Action code of a Composite State and will be automatically inserted at the beginning of the Entry Action code within each of the Composite State's Simple States. Similarly so for a Composite State's Exit Action.
Designates the start of a block of LSL code to be propagated to the Composite State's contained Simple States.
Designates the end of a block of LSL code to be propagated to the Composite State's contained Simple States.
The following example shows how the llListen and llSensorRepeat filters can be included within a #leaf block within the Entry Action of a Composite State. The code will be appended to every Simple State contained within the state decomposition hierarchy of the Composite State.
When Performance Analysis has been enabled within the Performance Analysis panel of the Options dialog (Tools...Options), several component types can be selected for monitoring. If the Components Monitored status is set to Specify for State Entry/Exit, State Functions or Transitions, then the following directives must be used to indicate which specific components will be monitored, and which group of LSL statements within their corresponding code segments will be analyzed.
Indicates the start of timing measurements for the code segment. Code will be inserted for the required timing varables and the baseline time will be saved.
Indicates the end of timing measurements for the code segment. Code will be inserted to calculate and save the elapsed time from the baseline point. In addition if the Each Time option has been selected, then code will be inserted to output the current values of the timing variables for this code segment.
The following example shows how performance measurements can be gathered for a particular section of LSL code within a script model.
An LSL Action can be selected from the Code Editor context menu item Insert Action sub-menu. The selected LSL Action is then customized through the LSL Action Configuration Wizard and is inserted into your code as the #action compiler directive.
The #action directive is then processed during code generation and automatically mapped to a set of LSL statements.
#action anAction parm1=parm1Value;parm2=parm2Value;...
The following example shows the #action directive that is entered by the SetColor action configured to set the color of an object to blue:
#define & #undef directives entered without the terminating "#" in a model imported from an earlier release will still be processed correctly. However if the code is subsequently edited, the Code Editor's syntax checker will issue an error regarding the missing "#".
The directives #stats, #endstats and #action can be contained within the sections of code bounded by the #if..#elif..#else..#endif conditional compilation directives. The nested directive will be ignored if it's code block is not outputted (the value of the boolean expression provided for the #if.. or #elif.. directives evaluates to FALSE). All other directives will be processed as they are encountered.
If a #leaf directive is used within a Simple State itself, the contained block of code will be removed inline and will not be part of the generated code.
As they operate globally to the entire model it is recommended that the #define and #undef directives only be used within the Custom Globals section.
A #stats...#endStats sequence can only be used once within a given component's code segment. As well they may not be used with #leaf #endleaf directives.