User Functions
User-Defined Functions - a feature added with OBSE v18
OBSE allows scripters to define their own functions, which can be called from other scripts.
A simple function script might look like:
ScriptName Multiply ; the name of this function float arg1 ; holds an argument passed to the function float arg2 ; second arg float localVar ; a local variable Begin Function {arg1, arg2} ; function body, with parameter list in {braces} Let localVar := arg1 * arg2 SetFunctionValue localVar ; this is the value that will be returned Return ; optional, causes the function to return immediately End
To call this function you would use:
Call Multiply 10 5
To store the result (50, in this case):
Let someVar := Multiply 10 5
When a function is called, script execution passes to the function and resumes after the function call when a return statement is encountered or execution reaches the end of the function script.
Factoring commonly-used code out into a function prevents repetitious code and shortens scripts. Encapsulating complicated routines into stand-alone functions results in simplified, more readable code.
Functions are defined as Object scripts but are treated as a distinct type with special limitations.
A function script can contain only one block. The name of the script is the name of the function.
Parameters are stored in local variables and must be indicated within {braces} in the function definition.
A set of empty braces indicates the function takes no arguments.
When parsing a function call, the compiler will verify that the number and type of the arguments match those expected by the function's parameter list.
If the called function is specified as a ref variable this validation cannot be performed; it is the scripter's responsibility to ensure the argument list is valid to avoid errors at run-time.
Notes
- Function scripts should never be attached to any object.
- All variables in a function script must be declared before the function body.
- Local variables and argument variables retain their values only until the function returns.
- Numbers, references and strings passed as parameters are copied to their proper local variables. Changing these copies do not change the original variables in the calling script.
- Arrays, on the other hand, are passed as pointers to the original arrays, therefore changes to arrays passed as parameters will persist after the user function returns.
- Clean up
- Strings passed as parameters are destroyed when the function returns.
- Any other string stored in local variables must be explicitly destroyed with sv_Destruct before the function execution ends (or else they will bloat the savegame).
- Arrays passed as parameters are pointers to the original arrays, so no clean up is necessary (the pointer, itself, is destroyed automatically).
- Local arrays are destroyed automatically when the function execution ends.
- All other local variables (shorts, floats, refs etc.) are also destroyed when the function execution ends.
Functions have some useful properties.
- Because they are object scripts, you can call them on references using someRef.Call someFunc; any commands used inside the function will then operate implicitly on the calling reference.
- Because they are scripts, they can be stored in and called using ref variables, and even passed as arguments to other functions.
- Functions can call other functions, including themselves (i.e. recursively);
- for instance:
ScriptName Pow ; calculates base to the exp power float base short exp short val begin Function {base, exp} if exp == 0 let val := 1 else let val := base * Call Pow base, exp - 1 endif SetFunctionValue val end
OBSE allows a maximum of 30 nested function calls. This means the above function will only work with exponents less than 30.
Function
A blocktype which precedes the body of a function.
Begin Function {arg1, arg2, ... arg10} ; function body End
This blocktype is only valid within function scripts.
A parameter list consisting of up to ten local variables used to hold arguments passed to the function must follow this keyword enclosed in curly braces;
if the function takes no arguments the braces should be empty.
SetFunctionValue
Specifies the value to be returned from a function.
nothing) SetFunctionValue returnValue:expr
Valid only within a Function block.
If a function does not specify a return value, the return value is assumed to be numeric zero.
If multiple calls to SetFunctionValue are processed within a single Function block, the most recent value specified will be returned.
Call
Calls a user-defined function.
(returnValue:multi) ref.Call function:ref arg1:multi arg2:multi ... arg10:multi
Should be followed by a list of arguments matching the types expected by the function.
If a calling reference is specified, commands within the function body will operate on that reference.
Call returns whatever value is returned by the function.