People using designs like the Node system tend to pass their script instance to each node for access to the API:
final class Bank extends Node {
private Script script;
public Bank(Script script) {
this.script = script;
}
//...
}
The problem with this is the ability to call onPaint, onLoop and other "critical" methods (onExit, onStart) from the script instance.
This tutorial will show you how to create an instance of the API to pass around. First thing we need is an instance that supplies the methods we need (from MethodProvider). We can do this by extending upon the API type:
final class DefaultAPI extends API {
}
You will be forced to declare an initializeModule method. Don't worry about it, just the devs not following interface segregation Leave it blank. You could fill it in, but you would be required to call it after instantiating API.
Once you have your API type, create an instance of it in onStart in your Script subclass:
final class MyScript extends Script {
private API api;
public void onStart() {
api = new DefaultAPI();
}
}
Finally, we need to pass the context of our script to our api instance. We do this by calling exchangeContext on our api instance, passing in the script's bot:
final class MyScript extends Script {
private API api;
public void onStart() {
api = new DefaultAPI();
api.exchangeContext(getBot());
}
}
Please use the getter method getBot() and not the public field bot. So now our API instance has the context; we can call methods such as myPlayer() from our API instance. We should now pass around the API, rather than the entire script:
final class Bank extends Node {
private API api;
public Bank(API api) {
this.api = api;
}
//...
}
For those who might say "Who's stupid enough to call onPaint or onLoop?":
Encapsulation does not only help prevent these miniscule mistakes, but helps lower the cognition needed by supplying you with only the things you actually need, rather than a bunch of other irrelevant things. The client should not be presented with onLoop or onPaint, since those do not have purpose within the Node class. Out of sight, out of mind.