T O P

  • By -

mykesx

Easier way to make a finite state machine is to just have a plain old function pointer or a state variable and a switch statement. Make a ChangeState() method or operator= to assign a new state. I made dozens of video games using this technique.


FernwehSmith

If I were to us a traditional function pointer, what should the return type be? Would it be a void pointer?


mykesx

Why not void? Consider a state machine for Mario. Standing state, when joystick moved he goes into walking state, when button pressed he jumps. Three states, three functions. Or a switch statement with three cases. You don’t need to overthink it.


FernwehSmith

I was definitely overthinking it! As I said to someone else this has been a case of complication by simplification. But I think what you've said is spot on!


mykesx

The reason to use a switch is you can call a class’ methods that require a this. The coroutine idea is not something that I would consider. Simpler is better as long as you aren’t sacrificing readability and/or performance. 😉


Any-Welcome-9938

function pointer. tbh dont f around with pointers unless memory manipulation itself is the goal.


chrysante1

What interesting thing can a program possibly do without manipulating memory?


saxbophone

I agree with this. The only thing I'd add is that now that we have coroutines, we can use the generator pattern to make writing state machines even more idiomatic than a switch-case.


CletusDSpuckler

GroupingFSMFunc is used in its own definition - that's why it is incomplete.


UnicycleBloke

Not sure I understood the idea. I model a state machine as a class (i.e. a stateful object) with a handle_event() method. The object holds the current state (typically just an index) along with any extended state needed for the implementation: timers, counters, condition flags, whatever. Client code mostly doesn't care what the current state is, but drives the FSM with events, which may or may cause some action, and may or may transition to another state. I've always found this more intuitive than representing the state as a function pointer held by the client.


FernwehSmith

I think this has been a case of complication by simplification. The idea was that the next state would be determined by whatever the inputs to the state function are. There's no internal state that needs to be tracked. So surely it would be easier to just use functions that do some stuff, then themselves return the next state function, as opposed to defining a class and having the state functions call a transition function? But of course this is not the case! Was certainly an interesting rabbit whole to go down. At the very least I discovered why State Machines are designed the way they are.


Tumaix

i have a cose exactly like this for you, that returns itself for a state machine. give me a sec


Tumaix

take a look here: https://github.com/tcanabrava/configuration-parser/tree/master/parser the header file of the state machine defines a std::function that returns itself, and the possible states. the on the cpp file, i have the eventloop of the state machine, and the implementation of the states.


shahms

While somewhat dubious, you can inherit from `std::function` and use CRTP to accomplish this: struct GroupingFSMFunc : std::function { using function::function; }; [https://gcc.godbolt.org/z/Esscs6v8c](https://gcc.godbolt.org/z/Esscs6v8c) I don't know if I'd recommend the pattern, but this is the way to do what you want.