User Functions

From the Oblivion ConstructionSet Wiki
Revision as of 09:32, 17 August 2009 by imported>QQuix (Added link to the list of user functions (Category page))
Jump to navigation Jump to search

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.

Function scripts should never be attached to any object.

And all variables in a function script must be declared before the function body.


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.

Local variables and argument variables retain their values only until the function returns.


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.

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.

See also

List of user functions