For parameters sent by reference, i.e. with the &
modifier it is necessary to specify in which direction the value is passed, in
, out
, or inout
, e.g. &out
. If no keyword is used, the compiler assumes the inout
modifier. For parameters marked with in
, the value is passed in to the function, and for parameters marked with out
the value is returned from the function.
Parameters can also be declared as const
which prohibits the alteration of their value. It is good practice to declare variables that will not be changed as const
, because it makes for more readable code and the compiler is also able to take advantage of it some times. Especially for const &in
the compiler is many times able to avoid a copy of the value.
Note that although functions that return types by references can't be declared by scripts you may still see functions like these if the host application defines them. In that case the returned value may also be used as the target in assignments.
int MyFunction(int a, int b) { return a + b; }
The global variables may be initialized by simple expressions that do not require any functions to be called, i.e. the value can be evaluated at compile time.
Variables declared globally like this are accessible from all functions. The value of the variables are initialized at compile time and any changes are maintained between calls. If a global variable holds a memory resource, e.g. a string, its memory is released when the module is discarded or the script engine is reset.
int MyValue = 0; const uint Flag1 = 0x01;
Variables of primitive types are initialized before variables of non-primitive types. This allows class constructors to access other global variables already with their correct initial value. The exception is if the other global variable also is of a non-primitive type, in which case there is no guarantee which variable is initialized first, which may lead to null-pointer exceptions being thrown during initialization.
With classes the script writer can declare new data types that hold groups of variables and methods to manipulate them. The classes also supports inheritance and polymorphism through interfaces.
// The class declaration class MyClass { // The default constructor MyClass() { a = 0; }
// A class method void DoSomething() { a *= 2; }
// A class property int a; }
// The interface declaration interface MyInterface { void DoSomething(); }
// A class that implements the interface MyInterface class MyClass : MyInterface { void DoSomething() { // Do something } }
A class can implement multiple interfaces; Simply list all the interfaces separated by a comma.
This allows the script to be compiled using these imported functions, without them actually being available at compile time. The application can then bind the functions at a later time, and even unbind them again.
If a script is calling an imported function that has not yet been bound the script will be aborted with a script exception.
import void MyFunction(int a, int b) from "Another module";
Even though enums list the valid values, you cannot rely on a variable of the enum type to only contain values from the declared list. Always have a default action in case the variable holds an unexpected value.
The enum values are declared by listing them in an enum statement. Unless a specific value is given for an enum constant it will take the value of the previous constant + 1. The first constant will receive the value 0, unless otherwise specified.
enum MyEnum { eValue0, eValue2 = 2, eValue3, eValue200 = eValue2 * 100 }
Currently a typedef can only be used to define an alias for primitive types, but a future version will have more complete support for all kinds of types.
typedef float real32; typedef double real64;