Metaprogramming
The preprocessor is an incredibly powerful tool, so this page goes over how to use it in a more advanced way to both generate and use functions and values with fully dynamic names.
Introduction
To introduce this topic, we're going to begin with a set of example data to use across the page. It consists of a list of mob names that we wish to create two utility functions for; count_(mob name)
and killAll_(mob name)
.
Iterating
The first step to accomplish this example is to iterate over all the items in the mobs
preprocessor variable. This can be done using $iterate
. For every item in the list of mobs, we want to create a function which will kill all of that specific mob.
This is possible because the function
command accepts a string input as a name, not just an identifier. This allows you to use preprocessor variables in the name, thus becoming a foothold into metaprogramming.
Without doing anything else, you now have five functions available, each with the correct code inside:
Calling
Next, let's create a function called killAll
which runs all the created killAll functions we've created using metaprogramming. You could do it the obvious way:
Or you could use the $call
command, which calls a function based on a string name. The command accepts parameters the same as a regular function call does, and it even compiles exactly the same.
As your "mobs" list expands, so will their functions and the killAll
function. This lowers the time cost of making changes, as well as guarding against user error. If the code works, it will continue to work as the data changes/expands.
Values
Next, we're going to expand the example to include a count_(mob name)
function which stores the mob count in a value created specifically for that mob.
Identical to the function
command, the define
command also can accept a string as the name input.
Using the Values
Using a value defined by a string is a little more challenging than with functions. The getValueByName
function is built-in to the compiler, see built-in functions for more information about these. The function accepts one string parameter, being the name of the value to get. If the function successfully finds a value with the given name, it will be replaced with that value.
Completed Example
With all of these concepts combined, here is the final file, containing:
A
killAll_$mob
function for every mob in the list.A
count_$mob
function for every mob in the list.A value
amountOf_$mob
for every mob in the list.A function
killAll
which calls all defined "killAll" functions.A function
countAll
which calls all defined "countAll" functions.
Expanded Example
Without metaprogramming, the code would look like this; it's simpler but harder to maintain the larger the data gets, as well as being more tedious when trying to make changes to the logic of the code.