Skip to content

Declaring Command and Button Public Methods

jmalins edited this page Dec 26, 2012 · 1 revision

When defining Command and Button classes, VexOS makes available a special global self variable of type Command* or Button* respectively inside of all standard methods. This gives an appearance similar to the automatic this variable in Java, making code simple and easy to understand. VexOS uses a number of tricks to make this happen in straight C. If you choose to define your own public methods for your Command and Button classes, these tricks are not available.

To work around this, instead of using self within these methods, you need to explicitly pass in an instance of the subclass you are working with. The examples below are given for Commands, but the techniques apply just as readily to Buttons.

Assume we have a Command class DriveWithJoystick and we want to add a public method to set a PowerScalar (ignore for a minute that this can be passed as an argument to the constructor). In Robot.h, you would declare not just the CommandClass, but also the public method. This is similar to Subsystem public methods.

DeclareCommandClass(DriveWithJoystick);
void DriveWithJoystick_setPowerScaler(Command*, PowerScaler* scaler);

Notice that the first argument is a command pointer, then the PowerScaler pointer is second. The first argument of all public methods is the instance to operate on. This is the same convention that is used for all VexOS API methods, so it should be familiar.

To create the command instance and call the public method, the following code is used:

Command* dwj = Command_new(&DriveWithJoystick);
PowerScaler* myScale = PowerScaler_new("default");
DriveWithJoystick_setPowerScaler(dwj, myScale);

To implement this method within the DriveWithJoystick definition file, the following code would be used:

void DriveWithJoystick_setPowerScaler(Command* cmd, PowerScaler* scaler) {
    checkInstance(cmd);
    cmd->fields->scaler = scaler;
}

There are two features to note: first is that the Command pointer cmd is passed to the checkInstance(Command*) function before it is used. This ensures that it actually is an instance of the DriveWithJoystick and not some other Command class. An exception is raised if the pointer is not to the right type and the code after the check call does not execute. If this step is omitted, you program is likely to crash, or at the very least, the Command pointer you pass in will be corrupted. The second feature to note is that we access the fields from the passed-in cmd pointer, not self which contains an is unspecified value during this method call (though it is visible to the method and you can reference it... don't do this).

Overall, it is relatively simple to define new public methods for you Command and Button classes, if these conventions are followed.

Clone this wiki locally