That first way of doing button macros is very similar to a statemachine. However, some syntactic improvements can be made.
It is a good idea to enumerate your states using enum or enum class and it is better to use a switch statement instead of an if/elseif/else tree.
Here is an example:
enum class liftStates {
off,
up,
waitForPress
};
liftStates liftState = liftStates::off;
while(true) {
switch(liftState) {
case liftStates::off:
lift.move(0);
break;
case liftStates::up:
lift.move(127);
break;
case liftStates::waitForPress:
if(button press) liftState = liftStates::up;
break;
}
pros::delay(20);
}
You can see this leads to a cleaner and more concise code.
In my code last year, I ended up using a massive statemachine for my flywheel angler, that used a queue to load up a series of commands that would execute in a sequence, and insert new states if needed.
enum shootStates {
off, //control to flywheel and intake
standby, //back position, control to flywheel
angling, //indefinite angling
cycle, //head to back position
extend, //move to extended position
waitForSlip, //wait until hood slips
waitForRetract, //wait until hood back to 0 pos
angleTop, //drop hood to top angle
angleMiddle, //drop hood to middle angle
angleTopPlatform, //angle top from platform
angleMiddlePlatform, //angle middle from platform
angleOut, //drop hood to out (ground flag) angle
angleTarget, //drop hood to target angle
waitForDoubleShot, //if distance is large enough, wait before second shot
waitForBall, //wait for ball to be in indexer
waitForFlywheel, //wait until flywheel is ready
enableShoot, //shoot indexer
waitForShoot, //delay
reportDone, //lets autonomous know sequence is done
loopJob, //reloads current job
loopMacro //reloads current macro
};
I could then construct named macros with sequences of those actions, and have the macros trigger on button presses. For example, the doubleshot macro was done using this sequence: angleTop, enableShoot, angleMiddle, waitForDoubleShot, enableShoot, reportDone and the cycling would be automatically inserted in that sequence when needed.
I recommend everyone reads about statemachines, as they can be simply implemented (switch statements) and are very powerful.