API State: Draft
Unfinished
This part of the API is brand-new. It will be changed if there are any bugs, missing features or usability improvements. This part of the API might receive breaking changes within a minor version.It is not recommended relying on this part of the API, it will most likely change.
Draft
Our own usage and testing has shown that this part of the API is complete and seems bug free. However, other plugins may have other use cases which are not covered by our testing. Therefore, please go ahead and use this API part. Let us know if there are missing features or bugs. This API part will be changed if there are more bugs, missing features or usability improvements. We will try to keep it compatible with previous versions if changes are needed. This part of the API won't receive breaking changes within a minor version.Please use this part of the API and give us feedback!
Stable
Both our own and third party testing showed that this part of the API is complete. Only bugs and major conceptual problems would lead to more changes. This part of the API will only change over at least one major version and will likely carry deprecation as long as possible.This part of the API should be safe to use. We try to keep it compatible with previous versions if changes are needed.
Function API Classes
org.betonquest.betonquest.api.service.function.Functionsorg.betonquest.betonquest.api.function.FunctionProviderorg.betonquest.betonquest.api.identifier.FunctionIdentifierorg.betonquest.betonquest.api.function.MathFunctionorg.betonquest.betonquest.api.function.FunctionDefinitionorg.betonquest.betonquest.api.function.FunctionExpressionorg.betonquest.betonquest.api.function.FunctionAssignmentorg.betonquest.betonquest.lib.function.FunctionParserorg.betonquest.betonquest.lib.function.token.FunctionTokenizer
Functions Overview🔗
This page covers the functions API and the underlying concepts.
Function Basics
See Functions for more information about how functions work in the script.
Introduction🔗
Functions solve a problem that is not common in BetonQuest's scripting language, but not having them is a huge pain in specific situations. They combine logic with math and are a powerful tool for creating complex behaviors that otherwise would be very verbose with just actions and conditions or completely impossible in the first place.
Accessing Functions🔗
Functions are accessed through the Functions interface. It allows you to find and evaluate functions.
public void myFunction(final Functions functions, final FunctionIdentifier identifier) throws QuestException {
final MathFunction mathFunction = functions.getFunction(identifier); //(1)!
final FunctionProvider functionProvider = functions.getFunctionProvider(identifier.getPackage()); //(2)!
final FunctionAssignment result = mathFunction.evaluate(functionProvider, List.of(new NumberSourceAssignment(10)); //(3)!
final Number value = result.asNumber(); //(4)!
}
getFunctionreturns aMathFunctionobject that can be used to evaluate the function. This may throw aQuestExceptionif the function is not found.getFunctionProviderreturns aFunctionProviderobject that can be used to resolve relative function identifiers toMathFunctionobjects.evaluatetakes a list ofFunctionAssignmentobjects that are used to evaluate the function. Functions can be evaluated with any number of arguments, but the required number of arguments is defined by the function definition. Missing arguments might result in an error, too many arguments might be just ignored and have no effect.- Functions produce their result as
FunctionAssignments that can be passed to other functions or resolved to java values.asNumber(as an example) returns the result of the function as aNumberobject.
You can also skip the getFunction step and use the evaluate method directly.
public void myFunction(final Functions functions, final FunctionIdentifier identifier) throws QuestException {
final FunctionAssignment result = functions
.evaluate(identifier, List.of(new NumberSourceAssignment(10))); //(1)!
final Number value = result.asNumber();
}
evaluateis essentially a shortcut forgetFunction(identifier).evaluate(functions, arguments)if you don't need to access theMathFunctionobject itself.
Registering Subroutines🔗
Subroutines are functions that can be called within other functions. They are registered with the Functions interface before functions can use them.
Availablity
Subroutines are only available once registered. If you define functions in the script that use subroutines, they will cause an error when evaluated without the subroutine being registered beforehand. Since subroutines are not checked at parse-time, they may be registered after the script has been loaded.
public void myFunction(final Functions functions, final MathFunction subroutine) {
functions.registerSubroutine("foo", subroutine);
}
Parsing Functions🔗
Functions are parsed from String by the FunctionTokenizer and FunctionParser classes.
They are currently not exposed to the API and only available in the library.
public MathFunction parseFunction(final String functionAsString) throws QuestException {
final FunctionTokenizer tokenizer = new FunctionTokenizer(); //(1)!
final FunctionParser parser = new FunctionParser(); //(2)!
final List<FunctionToken> tokens = tokenizer.tokenize(functionAsString); //(3)!
return parser.parse(tokens); //(4)!
}
FunctionTokenizeris used to tokenize the function string into a list ofFunctionTokens.FunctionParseris used to parse the list ofFunctionTokens into aMathFunction.- Invalid strings will cause a
QuestExceptionto be thrown. - Invalid tokens will cause a
QuestExceptionto be thrown.