![]() UJML Language Reference |
UJML allows you to create and call your own functions.
In addition to the built-in functions you may call from your scripting code, UJML provides a way to declare and call custom functions. See Scripting, Using Functions.
User-defined functions let you wrap up your own frequently reused code into something you can call from within your UJML scripts. Functions can build on one another, with higher-level functions calling low-level functions which call lower-level functions and so on. The end result is simplified code maintenance and reduced code size; thereby reducing your application download times.
User-defined functions are declared using one or more function elements inside of a functions element. See functions, function. The function element has attributes for the function name, the return value type, and (optionally) access and visibility modifiers. The function name attribute must be a valid UJML identifier. See Identifiers. Function return value types may be any of the UJML data types. See Data Types. You may also declare functions which do not return anything, in which case the type is 'void'. For example, '<function name="doSomething" type="void">'. Function access and visibility modifiers fall under the scoping rules and may change which function elements are required. See Scope, Function Scoping and Sharing.
Function declarations may be contained by applications, partitions, and state machines. See Application Files, Partition Files, State Machines.
A function declaration may contain elements for function parameters, variables, script, and return value. Which of the optional elements is included depends on what is needed for the function to fill its purpose. Some functions are more complex and require variable and script elements. Other functions can perform their entire calculation in the return element. Some functions have return values and other functions are 'void' and do not require a return element.
The parameters element indicates what values the scripting code calling the function must provide. See Parameters. Function variables and script elements work just like they do anywhere. See Variables, Scripting. The return element specifies what value is returned after the function is executed. See Returning Function Results.
Often a function may be declared with just the parameters element and a return element expression. For example, the following two function declarations are equivalent:
<!-- Add two values in script -->
<function name="add1" type="int">
<parameters>
<var name="right" type="int"/>
<var name="left" type="int"/>
</parameters>
<variables>
<var name="result" type="int"/>
</variables>
<script>
result = right + left;
</script>
<return><ref>result</ref></return>
</function>
<!-- Add two values in eval -->
<function name="add2" type="int">
<parameters>
<var name="right" type="int"/>
<var name="left" type="int"/>
</parameters>
<return><eval>right + left</eval></return>
</function>Function variables are scoped only to the function and cannot be accessed from outside of it. Function variables exist for the lifetime of the application and are not re-entrant. This means that the values of the function variables are cleared each time the function is called.
The scripting code in a function may change variables and state variables in the same module scope as the function declaration. See Data Scoping and Sharing. This means that calling a function may have side effects because the module is in a different state after the function was called than before.
A function is 're-entrant' when it may be called again before it has finished executing. Because of the way UJML creates and uses variables, a UJML function is not re-entrant. For this reason UJML functions may not perform recursion.
Recursion happens when a function calls itself, or calls another function that calls itself. Recursion is not supported by UJML and the results of a recursive function are undefined.
A component exposes public functions by implementing interface methods. See Components, Interfaces. When declaring an interface method implemented in a component you must refer to the interface name and the interface method name using 'dot notation'. For example 'InterfaceName.methodName'. When calling a component function, the component instance must be assigned to a variable of the appropriate interface type. See Interface Types. You then call the function by variable name and method name in 'dot notation'. For example 'variableName.methodName()'.
|
Topic |
Description |
|
Functions may return the results of a calculation to the calling code. | |
|
Functions are scoped identifiers and may be shared. |
The following example shows how to calculate what percentage of one value another value represents. It is part of the math.ujml sample.
<function name="pct" type="int">
<parameters>
<var name="val" type="int"/>
<var name="percentOf" type="int"/>
</parameters>
<return>
<eval>
((val * 100) + (percentOf / 2)) / percentOf
</eval>
</return>
</function>
The following example shows how to set some module level variables and state variables. It is part of the events.ujml sample.
<function name="flashButton" type="void">
<parameters>
<var name="button" type="int"/>
</parameters>
<script>
// Set flash colors.
mButtonBackColor = &_COLOR_YELLOW; ;
mButtonForeColor = &_COLOR_BLUE; ;
// Show button in flashing mode.
_clear_state(sButton[button]);
sButton[button] = true;
// Restore colors.
mButtonBackColor = &_COLOR_BLUE; ;
mButtonForeColor = &_COLOR_YELLOW; ;
// Start flash countdown.
if (mSoundLoaded)
{
sButtonFlasher[button] = &FLASH_SOUND; ;
}
else
{
sButtonFlasher[button] = &FLASH_DELAY; ;
}
</script>
</function>
The following example is a function that builds a font style value based on argument values. It is part of the venclude.ent sample.
<function name="makeFontStyle" type="int">
<parameters>
<var name="bold" type="boolean"/>
<var name="italic" type="boolean"/>
<var name="underlined" type="boolean"/>
<var name="outlined" type="boolean"/>
</parameters>
<variables>
<var name="style" type="int"/>
</variables>
<script>
style = &_FONT_STYLE_PLAIN;;
if (bold)
{
style = style + &_FONT_STYLE_BOLD;;
}
if (italic)
{
style = style + &_FONT_STYLE_ITALIC;;
}
if (underlined)
{
style = style + &_FONT_STYLE_UNDERLINED;;
}
if (outlined)
{
style = style + &_FONT_STYLE_OUTLINED;;
}
</script>
<return>
<eval>style</eval>
</return>
</function>
The following example declares a component function that implements the update method of the ILifeBlock interface. It is part of the lifeblock.ujml sample.
<function name="ILifeBlock.update" type="void">
<script>
// Color depends on alive state.
if (mAlive)
{
mCurrBlockColor = &COLOR_BLOCK_ALIVE_BG;;
}
else
{
mCurrBlockColor = &COLOR_BLOCK_DEAD_BG;;
}
// Update view.
_clear_state(sShow);
sShow = sShow;
</script>
</function>
The following example calls the component function declared above, where the component instance is an element of a multi-dimensional array. It is part of the lifegrid.ujml sample.
mBlocks[row][column].update();
|
Copyright (c) 2000-2007 UIEvolution, Inc. All rights reserved.
|
|
What do you think about this topic? Send feedback!
|