So as you probably guessed there are plenty of frameworks out there which actually help you build state
machines and we're going to take a look at one of them which is called Boost MSM short for me the state
machine now boost actually has two different state machine libraries but I can only show you one unfortunately
so there is another library that you can check out if you want to.
So how does the model state machine works.
Well I have some includes here and you'll notice I have includes for the back and that's when you define
the structure of the state machine and the front end which is the part which actually executes the state
machine.
Or as we say orchestrates the state machine.
So let me get a couple of name spaces in here so namespace MSM is going to be boost the MSM and namespace
MPO.
Yes we're using the metaprogramming library is going to be used.
Yeah and I also need to learn how to spell obviously namespace like so and will have using namespace
MSM from the get go.
OK so now we're going to define the state machine.
And this time round and this time we're kind of we're hostages to the boost Mehta's state machine library.
We're going to be using actual types as opposed to just in our members so for every single part of the
phone call that we're once again going to simulate we're going to be using types instead of just apps.
So I'll have a structure called Call dialed and we'll have all of the other structures that we are used
to.
So let me just drop those in here.
So here are the structures as you've seen them before maybe with different spending because now there
are actually types.
I'm going to have just a utility vector of strings representing their names so that we get to print
them later on.
So these are some of the state names we're going to be just doing some printing later on.
So let's actually build a state machine.
So in order to build the state machine you have to inherit from a particular class and that class is
called state machine def.
So struct fones state machine.
And this is a state machine def and it says RTP thing so you have to provide the phone state machine
as the template argument.
There we go.
So what are we going to do here.
Well first of all we are actually going to define the individual states.
So up here we haven't actually defined states we defined the triggers.
So these are the triggers and the states are going to be called here.
So for example the state will be off the hook.
It's going to be a state.
Notice the I'm inheriting a special state type here and you would essentially define all of the other
states in a similar fashion.
Now because this is an industry strength state machine framework we're also going to take a look at
some particular customizations some of the things that you can do in terms of getting additional behaviors
out of states for example so let's suppose we have a connecting state.
So this is a state.
And now what I can do is I can define a function which will be called on the entry to the state so whenever
you enter the connecting state we're going to print something.
Now it isn't particularly intuitive the way that these things are defined that you suddenly cannot just
go and implement an override for example because well I don't know what sea line is going to say about
overrides to state that might give us a meaningful list.
I know give us anything at the moment it looks like it's just crashed or I don't know it seems to have
been hidden from you.
So here we go.
It was all operation requires more time.
Let's just sit here and wait.
OK.
So actually we do get something the one that we're interested in is called On entry so let's just press
return here and see what it actually generates.
So you can see it is generated roughly what we want except that for God the template argument so let's
add those here.
So class event class FSM.
So essentially what we're doing is we're handling the situation where you enter the particular state
machine.
And in this case what particular state to be specific and here we can say for example that we are connecting.
So that's all that we're going to do and essentially as we enter into this state we're actually going
to we're going to call this particular thing we're going to call this particular function.
And yes it's not an override.
So you can see that relying on the idea completely is not the best way to go.
It generates lots of weird stuff in the way that it's search for members is also both slow as well as
just bizarre so it's easier to just type these things by hand.
OK so we have this connecting state.
Let's add a couple of more states like so.
So these states as well.
Let me in them.
Hold on the nation seems to have.
There we go.
I think we are Kaino.
So these are a couple of more states that we have and now of course what we can do is we can actually
define the transition table so the transition tables kind of similar to the map that we've been defining
by hand.
And this is the thing that uses boost MPO the metaprogramming Larbi.
So what we're going to be building is a type list essentially a vector of Rose of type names.
So here it is struct transition table which is an MPO vector.
And inside you make these rows row.
So you make a row where you specify the starting state like off hook for example.
You specify what happens what's the trigger.
So that's called Diebold for example and you also specify what what is the final the outcome state like
connecting for example.
OK.
So this is an example so it's interesting that we don't actually actually yeah this transition table.
I'm putting it in the wrong place.
It has to be inside the state machine.
It has to be in here.
And that explains why we have some red coding here.
So this is the transition table that you need to define.
And without the state machine isn't going to work.
Let me actually show you the full transition tables so I've got some more transitions here but there
are some customizations that I've added So you see for the last row when you are placed on hold and
you throw the phone against the wall and the phone gets destroyed there was also some customization.
So there were two points of customization there is can destroy phone and phone being destroyed.
So let's take a look at those because these are actually rather interesting so we have this idea of
the phone being destroyed which is once again it's quite simply an action that is going to be invoked
whenever somebody goes off and actually destroys the phone so we can define it as follows.
We can define it like this.
So once again you see the ugly template stuff for the type of state machine as well as the source that
you went from and you went to and what we're essentially doing here is we're handling a transition.
So we're transitioning from the source state to the target state and in the process we can actually
print something out.
In this case.
So that's what I'm specifying here.
Now the other thing is more of a guard condition.
So we're saying that this transition from on hold to phone destroyed can only happen if the guards condition
which is cold can destroy phone is actually allowing this sort of thing to happen.
So what can we do about this Garth condition once again the Garth condition is a struct so we can define
it as follows and you can see that here it has a boolean operator which returns.
Well true or false obviously.
So here I can take the state machine and I can get some field from the state machine.
We have actually added this field.
Yes but I'm going to add it in here.
And this is a field indicating whether I'm angry or not.
And let's suppose that I'm the Hulk and I'm always angry.
So we're going to return to here and this means that this transition is allowed.
If I said angry to false this transition wouldn't be possible we wouldn't be able to call it basically.
So this is our transition table there are a couple of things more that we need to define.
So first of all we need to define the starting state.
So this is done using a typedef.
So we say that all Flook is the initial state.
Once again if you try to compile without these type def the system will complain and it will fail to
compile.
And finally we can define a function which gets cold if there is no transition.
So we don't have any way to go from the current state.
We can run the following function so here I'm adding a function which is called No transition.
And once again it takes a reference to the event a reference to the state machine and so on and so forth.
And we are saying there's no transition on the event.
And then here is the actual name of the event.
I'm printing it out for us to see.
So this is the definition of the state machine then we can now run the state machine as before.
Well this time around let's not do an interactive scenario because I think we've spent too much time
already.
So here well I'm going to do is I'm going to first of all make the phone so I'll use the backend to
make a state machine.
So remember we have a state machine def and you feed it into the state machine so state machine def
goes as a template argument of the state machine.
So here is the state machine.
And then what I'm going to do is just make a function called info which is going to print out information
about the current state of the phone.
What's going on here.
So what I'm going to do is I'll get the current state of the phone so that's phone daughter current
state at 0 and then what I'm going to do is I'm going to see out and remember I made this list of strings
here specifically so that I can print out the different states.
So let's do exactly that.
I'm going to say seek out the phone is currently and then get the state names and index I and then a
line break at the end of it all.
So that's going to be my info function I'm going to call it and then I'm going to be doing various things
in terms of the state machine.
So essentially let me actually add a couple of definitions in here and we have a state machine that
we may actually experiment with so we Diala call we connect we get placed on hold and then all of a
sudden we we throw the phone into the wall so let's actually run this and see what we get.
All right so as you can see we're getting the expected output here so the phone is off the hook we're
connecting we're connected we're placed on hold.
We throw the phone into the wall and then breaks into a million pieces and the phone is currently destroyed.
The final thing I want to show you is what happens afterwards because at this point in time we don't
have any transition.
So if we try to process an event if we try to do a process event let's say call dialed again.
Let's take a look at what actually happens here.
So as you can see what's happening is since the phone is on the hook and we don't have any transitions
from that state it tells us no transition from state destroyed on events trucked called Dial.
And this is our handler our transition handler helping us out when we don't have any transitions from
this state.
So this has been a small demo of how you use an industry strength state machine framework to actually
build your state machine and certainly it does have its set of requirements like for example the requirement
that states are actually structures and the transitions are structures as well but provided you're OK
with it you get a lot of customization so you have things like Garth conditions you have all sorts of
handlers like here handling on entry but you can simply handle the on exit when you are leaving a particular
state.
You have no transition function for when you don't have any transitions and lots of more customization.
Besides what I've shown you here.