Functions basically serve 3 purposes:
- They grant access to global input parameters.
- They grant access to the current item that is being evaluated.
- They can be used as "converters" in-between functions.
As a function can call another function, we will eventually end up with a whole hierarchy of functions, which is then basically a tree. As such we need to distinguish between leaf and non-leaf functions.
Leaf functions are those that have no parameters. Non-leaf functions do have one or more parameters, and each parameter in turn resolves as a further (nested) function call.
Examples of leaf functions:
- Global input parameter.
- Current item the query is iterating on.
- A literal value.
Examples of non-leaf functions:
- A custom function that adds 2 vectors and returns their sum.
- A custom function that returns the position of a given entity.
For the sake of convenience, the Universal Query System (UQS) automatically registers leaf functions for every registered item type. As such, each new item type will automatically add support for a global input parameter of exactly that type. The same can be said for functions that return a literal and grant access to the current item in a query.
Example Function: Vec3Add()
Custom functions always need to be non-leaf functions (i. e. functions that do take at least one parameter). There's currently no use-case which would require it to be different. Here's an example from the UQS's StdLib for for a custom function that takes 2 parameters:
Registering Custom Functions
In order for the UQS to be able to instantiate this new function later on at runtime, it needs a factory that knows about this specific function and how to create an instance of it:
To finally expose your new function factory to the UQS core, the you'd just call this static helper method once receiving the