Skip to content

Custom Objects

pumbas600 edited this page Aug 16, 2021 · 7 revisions

Written for HalpBot-Core-1.0.1

In HalpBot, a custom object is defined as a type that doesn't have a built-in TypeParser. In this case, HalpBot attempts to construct an instance of that object by matching a constructor with the passed in parameters.

The syntax for creating custom objects when invoking a command is: TypeName[Parameters]

For example: Vector3[1 0 1] Would construct a Vector3 with x, y, z components of 1, 0, 1 respectively. If you prefer not to specify a type name, or just want more control around how your custom object is parsed, then you can construct a custom TypeParser for it. More information on how to do that can be found here.

NOTE: When constructing custom objects the type name is NOT case-sensitive.

Setting up Custom Object

Unless otherwise specified, HalpBot will only use the first constructor defined in a class, however, in some cases it can be useful to support multiple constructors. In this case, you need to annotate all the constructors you want to HalpBot to be able to use with @ParameterConstruction. Constructors without this annotation will not be usable when creating instances of that object.

TIP: You can treat custom object constructors exactly like you would normal command methods. This means they support parameter annotations too!

public class Vector3 {
    private final double x,y,z;
    
    @ParameterConstruction
    public Vector3(double x, double y) {
        this(x, y, 0);
    }
    
    @ParameterConstruction
    public Vector3(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
    
    //... Getters and other methods
}

As the Vector3 class has 2 constructors annotated with @ParameterConstruction, this means that you can either use Vector3[10 2 4] or Vector3[5, 3] when specifying a Vector3 parameter.

If you want to be able to refer to your class as something else, rather than the classes name, you can annotate the class with @CustomParameter("OtherName").

Example

@CustomParameter("Vec3")
public class Vector3 {
    //...
}

This means you would now be able to use Vec3[1 4 3] to create the custom object, however, do note that you will no longer be able to use Vector3 as the type name.

Displaying Custom Objects

When a custom object is returned by a command, it is displayed by calling to toString() method. As such, to make it return a meaningful result, you'll need to override this method.

Example

@CustomParameter("Vec3")
public class Vector3 {
    //...
    
    @Override
    public String toString() {
        return String.format("Vector3 = [%.4f %.4f %.4f]", this.x, this.y, this.z);
    }
}

Now when a Vector3 is returned by a command, it will display as Vector3 = [x y z].

Custom Objects in Action

Now that we've set up our custom object's class, we can now use it in our commands simply be specifying it as a parameter in the command method. Let's start by making a command that can sum a number of Vector3's for us.

@Command(alias = "Sum", description = "Returns the sum of the specified vector3s")
public Vector3 sum(@Implicit List<Vector3> vectors) {
    return vectors.stream()
        .reduce(new Vector3(0, 0), Vector3::Add);
}

Usage: __.

Clone this wiki locally