I'm new to C++.
How can I implement a State Machine in C++ ?
I'm getting only the messages and should know the next state.
What is the proper structure I need to use ?
Thanks, Igal
For simple state machines you can just use a switch statement inside a loop, e.g.
for (;;)
{
switch (state)
{
case STATE_1:
// do stuff
// maybe change state
break;
case STATE_2:
// do stuff
// maybe change state
break;
case STATE_3:
// do stuff
// maybe change state
break;
// ...
}
}
typedef std::pair<State,Message> StateMessagePair;
typedef std::map<StateMessagePair,State> StateDiagram;
StateDiagram sd;
// add logic to diagram
...
State currentState = getInitialState();
...
// process message
Message m = getMessage();
StateDiagram::iterator it=sd.find(std::make_pair(currentState,m)));
if (it==sd.end()) exit("incorrect message");
currentState = it->second;
EDIT:
Building up the state diagram is done like this (example is for a cola-vending machine):
StateDiagram.insert(std::make_pair(State::Idle ,Message::MakeChoice ),State::WaitingForMoney);
StateDiagram.insert(std::make_pair(State::WaitingForMoney,Message::Cancel ),State::Idle);
StateDiagram.insert(std::make_pair(State::WaitingForMoney,Message::MoneyEntered ),State::FindCan);
StateDiagram.insert(std::make_pair(State::FindCan ,Message::CanSentToUser),State::Idle);
Default actions can be implemented using a second map, where the key is only the State, like this:
typedef std::map<State,State> StateDiagramForDefaults;
Instead of printing "incorrect message", the logic can perform a lookup in the StateDiagramForDefaults.
If actions needs to be added to the state diagram, the value of the map should be a pair consisting of an action, and a new state, like this:
typedef std::pair<State,Message> StateMessagePair;
typedef std::pair<State,IAction *> StateActionPair;
typedef std::map<StateMessagePair,StateActionPair> StateDiagram;
The logic that builds up the diagram should then "new" an instance of a class that implements IAction, and put that in the StateDiagram.
The executing logic then just executes the IAction implementation via a virtual method (e.g. execute() or the ()-operator).
The standard state machine implementation techniques are:
the nested switch statement (some
previous posts show examples of this
technique)
state-table
the GoF State design pattern
combination of the above
If you are new to state machines and implementation in C or C++, I would recommend my Dr.Dobbs article "Back to Basics" available at http://www.ddj.com/184401737 (you need to click on the Print link at the top to conveniently read the text.)
None of the standard techniques is suitable for the hierarchical state machines (such as UML statecharts). If you are interested in the modern UML state machines, I'd recommend my 3-part Embedded.com article "A crash course in UML state machines" (http://www.embedded.com/design/testissue/215801043).
Unless you are implementing a state machine for the sake of implementing one, I would highly recommend that you use a state machine generator instead. Ragel is one very good and robust solution.
http://www.complang.org/ragel/
One way is to use a class like this (rough example code ahead):
class State
{
//pass a new Message into the current State
//current State does (state-specific) processing of
//the message, and returns a pointer to the new State
//if there's a state change
virtual State* getNewState(const Message&) = 0;
};
class ExampleState
{
virtual State* getNewState(const Message& message)
{
switch (message.type)
{
case MessageType.Stop:
//change state to stopped
return new StoppedState();
}
//no state change
return 0;
}
};
On of the complications is whether states should be static flyweights, or whether they carry instance data and should therefore be newed and deleted.
Gosh, it isn’t as complicated as it seems. State machine code is very simple and short.
Coding a state machines is just about trivial. The hard part is designing a state machine that behaves correctly in all possible cases.
But let us assume that you have the correct design. How do you code it?
Store the state in an attribute, myState perhaps.
Whenever you receive a message switch on the myState attribute to execute the code for that state.
3 In each state, switch on the message to execute the code for that state AND that message
So you need a nested switch statement
cStateMachine::HandleMessage( msg_t msg )
{
switch( myState ) {
case A:
switch( msg ) {
case M:
// here is the code to handle message M when in state A
...
Once you have this up and running, it is fun and easy to add more states and messages.
See Implementing Finite Automata in a Program for several different ways of building finite state machines.
Checkout the hierarchical state machine article. Modeling of states as classes is described with an example.
The one i am using is based on this one: Machine Objects.
It seems to be well optimized and is a hell of a lot less complex to use than Boost Statechart.
Of course, boost has something in store for you: Boost Statechart library. You can also find some nice tutorials there.
switch(currentState) {
state1:
currentState = NEXT_STATE2;
break;
....
}
You can use the Ragel state machine compiler: http://www.complang.org/ragel/
Ragel compiles executable finite state machines from regular
languages. Ragel targets C, C++ and ASM. Ragel state machines can not
only recognize byte sequences as regular expression machines do, but
can also execute code at arbitrary points in the recognition of a
regular language. Code embedding is done using inline operators that
do not disrupt the regular language syntax.
The core language consists of standard regular expression operators
(such as union, concatenation and Kleene star) and action embedding
operators. The user’s regular expressions are compiled to a
deterministic state machine and the embedded actions are associated
with the transitions of the machine. Understanding the formal
relationship between regular expressions and deterministic finite
automata is key to using Ragel effectively.
Ragel also provides operators that let you control any non-determinism
that you create, construct scanners, and build state machines using a
statechart model. It is also possible to influence the execution of a
state machine from inside an embedded action by jumping or calling to
other parts of the machine, or reprocessing input.
Ragel provides a very flexible interface to the host language that
attempts to place minimal restrictions on how the generated code is
integrated into the application. The generated code has no
dependencies.
Ragel code looks like:
action dgt { printf("DGT: %c\n", fc); }
action dec { printf("DEC: .\n"); }
action exp { printf("EXP: %c\n", fc); }
action exp_sign { printf("SGN: %c\n", fc); }
action number { /*NUMBER*/ }
number = (
[0-9]+ $dgt ( '.' #dec [0-9]+ $dgt )?
( [eE] ( [+\-] $exp_sign )? [0-9]+ $exp )?
) %number;
main := ( number '\n' )*;
.. and it compiles to:
st0:
if ( ++p == pe )
goto out0;
if ( 48 <= (*p) && (*p) <= 57 )
goto tr0;
goto st_err;
tr0:
{ printf("DGT: %c\n", (*p)); }
st1:
if ( ++p == pe )
goto out1;
switch ( (*p) ) {
case 10: goto tr5;
case 46: goto tr7;
case 69: goto st4;
case 101: goto st4;
}
if ( 48 <= (*p) && (*p) <= 57 )
goto tr0;
goto st_err;
Related
I have an application that invokes callback function when a certain action is performed on the application.
Inside this callback function, I would like to invoke a Parser (a command line parser for instance).
This Parser would be running in a while loop and exits and comes back to the callback only when the user uses the command 'quit' on the command line.
Inside the while loop, the user always has access to the command line. Based on the user input on the command line, the Parser takes a unique action. For instance, it will set a variable and it goes to a database like so:
command-line>a 100
command-line>
Here the parameter a in DB would be set to 100.
I want to model the Parser using Object-Oriented Design. Which Design Pattern can I use in this case?
First and foremost, most design patterns are obsoleted by the introduction of first-class functions. What you need is a dispatch table of names to actions, which is basically the Command pattern.
Assuming the following definitions:
using Tokens = std::vector<std::string>;
using Action = std::function<void(const Tokens&)>;
Tokens read_and_tokenize_line();
void larger_command(const Tokens&);
std::map<std::string, Action> dispatch_table = {
{"a", [&](const Tokens& tokens){ my_database->set("a", tokens[1]); }},
{"larger_command", &larger_command},
};
You could write your core loop as follows:
while (true) {
auto tokens = read_and_tokenize_line();
if (tokens[0] == "quit")
break;
if (auto it = dispatch_table.find(tokens[0]); it != dispatch_table.end()) {
it->second(tokens);
} else {
std::cerr << "command " << tokens[0] << " not known" << std::endl;
}
}
The main problem you have is that your parser run in a while loop and that will obviously block your UI. I assume this issue is the (unstated) problem you are trying to solve.
First, there exist parsers that don't need to run in a while loop. bison can generate such parsers when in push mode. By using this kind of parser you can still rely on your main GUI event loop and feed the parser with tokens inside a callback without blocking.
Then, if you are writing yourself a recursive-descent parser, you can generate a parser that will interrupt itself and save its state each time it needs some input. This is going to be very tricky as you have to save the whole state of the parser including its stack. The way to do it is to use an explicit stack (or many stacks, one for each operand type) for all functions and rewrite the function calls as a big loop inside a switch statement. This is (very) hard and not maintainable. You can start by reading this article (which deals with a simpler version of the problem).
Finally, you can use a background thread to host your parser's while loop. Send data to the parser using a pipe or a queue with a semaphore (if you can customize the input method). The issue here is that this background thread will (probably) not be able to update the UI because most framework are not thread-safe. So you will need a mechanism to send back information from the parser to the main UI thread (something like PostMessage.
References
Bison - push-parser interface, GNU, https://www.gnu.org/software/bison/manual/html_node/Push-Parser-Function.html
Coroutines in C, Simon Tatham, https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
Win32 API - PostMessage, Microsoft, https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagea
I'm running some C++ code on an SDK that uses a switch statement for whenever particular events occur. I am working on the case that occurs when the signal strength of a bluetooth signal changes and it will report the new value back. I only want this to report back N times instead of continuously however, how could I achieve this?
case BLE_GAP_EVT_RSSI_CHANGED:
sd_ble_gap_rssi_get(p_ble_evt->evt.gap_evt.conn_handle, &RSSI);
printf("\nRSSI =%d dBm", RSSI);
break;
static int rssi_changed_counter = 0;
switch( /* ... */ ) {
// ...
case BLE_GAP_EVT_RSSI_CHANGED:
if(rssi_changed_counter < N) {
// ...
++rssi_changed_counter;
}
break;
// ...
}
This is not about bluetooth, or signals, or about making a case run N times.
This is about deactivating a piece of code after some condition has been met.
Your condition is that your code has been run through already, N times.
You want your code to do something different on the N+1th time (and, presumably, thereafter).
The best way to do this depends on code that we cannot see. It could be as simple as a counter and if statement. It could be the de-binding of a function pointer. It could be the removal of an event trigger from some third-party library. The choice is yours.
Im working on a real time machine control system, which performs a series of tasks, and should react to a large number of inputs. I've decided to implement this system using a state machine.
Ive used simple switch/case based state machines in the past and would like to transition to a more maintainable solution. At the moment I'm a little confused as to how to handle input and transitions.
For example I have an AnalogInput class which provides me with measurement values which i should monitor. Say I have a state WaitForThreshold, which should read a AnalogInput and then transition if the threshold is reached.
Do I
a) a pass a reference of the AnalogInput class to the WaitForThreshold class and allow it to monitor the input itself, signaling to the StateMachine class that it wishes to transition.
b) create dedicated events, LaserMeasurementAtThreshold and a state transition map: StateMachine.addTransition(State A, Event e, State B)
c)create more generic events AnalogInputChanged and implement event handlers for each of the events, which again signal to the StateMachine that a transition is desired
option a is essentially the larger version of a simple switch/case state machine, which could get messy with time, but offers great flexibility and b/c seems more structured and clean but seems like i may have to jump through alot of hoops to implement relatively simple tasks because the number of events can be very large.
Can someone offer some insight on the design of state machines where a large number of inputs sources and types must be monitored, and events are largely state-specific(Most event pertain only to a single state)?
Are there possibly other alternatives to state machine design to control a system where a sequence of steps must be implemented (non linear, looping and branchig must be possible)
Language: C++
Thanks
I believe this would be clearer to implement as a table of transitions:
typedef (void)((*Pointer_To_Transition_Function)());
struct Table_Entry
{
Input_Type input_value;
Pointer_To_Transisiton_Function p_trans_function;
};
static const Table_Entry Transition_Table[] =
{
{4, Read_Sensor},
};
static const size_t transition_quantity =
sizeof(Transition_Table) / sizeof(Transition_Table[0]);
//...
for (size_t index = 0; index < transition_quantity; ++index)
{
if (input_value = Transition_Table[index].input_value)
{
Pointer_To_Transition_Function p_function = Transition_Table[index].p_trans_function;
// Call the function:
p_function();
break;
}
}
You could use std::map, but the std::map has to be initialized during run-time. The table (array) is static and constant, thus it can be placed into a read-only memory segment (convenient for embedded systems); and doesn't use dynamic memory allocation.
Edit 1: ASCII drawing of the table
+-------------+--------------------------------+
| Input value | Pointer to transition function |
+-------------+--------------------------------+
| 4 | Read sensor |
+-------------+--------------------------------+
| 2 | Start motor |
+-------------+--------------------------------+
I have a class (lets call it checker) and diffrent kind of classes that execute tasks (lets call them tasks). each tasks belongs to several categories
each task runs and at some point asks checker if they are allowed to do something. checker answers according to system state and according to their category. a task can be in multiple categories
how would you implement that? (cpp but I don't really think its language specific).
I was thinking adding a list of categories in each task and have a function that gets a category and answers if the task belongs to it.
class checker {
bool is_allowed(Task * task);
}
class Task
{
bool is_belongging_to_category(Category cat);
void some_task_to_do()
{
...
if (checker::is_allowed(this)) { ....}
else {....}
}
}
Is there a better way to solve this? Maybe some known design pattern...
This looks like questionable design. You're making tasks the objects.
Let's say your tasks are: Eat, Drink, and Be_Merry
If you make each of those tasks objects, they'll have to maintain a reference to the actual individual that they operate on, then when the condition is met they'll need to modify state on the given individual.
This is a violation of Object Oriented Design which defines an object as:
A tight coupling or association of data structures with the methods or functions that act on the data
Notice that you have split the "methods or functions that act on the data" from the object. Instead you should have modeled the objects Jack and Jill which had methods: Eat, Drink, and BeMerry
As far as checker, whether it's parceled out will depend upon whether you're using a push or a pull coding. If you're doing push coding, then checker is simply a holding area for the behavioral properties of Jack and Jill, in such a case the properties should be pushed to Jack and Jill rather than held in checker. If they are properties for all Jack or Jill objects, use a static property. If however you are using pull coding then the information is unavailable until you attempt to execute the task. In this case the checker should probably be a singleton that Jack and Jill access in the process of performing their tasks.
EDIT:
Your comment reveals further tragedy in the design. It seems as though you've kicked off a bunch of threads which are doing busy waiting on checker. This indicates that you need to be using a pull coding. You're Jack and Jill objects need to maintain booleans for which tasks they are actively involved in, for example m_is_going_to_school, then when checker gets the condition that would stop your busy waiting in your design, instead kick off the goToSchool method.
You could make a vector to store all the possible allowed options. You can make a bool function (like you have) called IsAllowed with argument string and that will check if the option its going to do is allowed. If not, return false. That's just my idea though. Of course there's a zillion different ways to implement this. If you want multiple choices. Then you can make a 2d vector, and see if the corresponding row has any of the options. Good luck!
If you know the maximum number of categories in advance, I'd recommend using Bit Flags to do this.
enum Category {
CATEGORY_A = 1,
CATEGORY_B = 1 << 1,
CATEGORY_C = 1 << 2,
CATEGORY_D = 1 << 3,
};
class Task {
int32_t categories_;
public:
Task() : categories_(0) {}
void add_category(Category cat) {
categories_ |= cat;
}
void run() {
checker::can_run(categories_);
}
}
This allows to test for multiple categories all at once:
namespace checker {
bool can_run(int32_t categories) {
int32_t cannot_run_right_now = CATEGORY_A | CATEGORY_C;
if(categories & cannot_run_right_now != 0) {
return false;
}
...
}
}
Well, it depends. If you are 100% sure that you know how many categories there are to be and that is not some gigantic number then you might store this information as an integer. If n-th bit is 1 then task belongs to n-th category. Then depends on the state of system you might create some another integer that would serve as a mask. In the end you would just do some bit-AND ( mask & categories != 0 ) operation to determine if task and mask share common bit.
On the other hand if there will be unknown number of categories you might just make a list of categories it belongs to. Make a dictionary of [SYSTEM_STATE] => [CATEGORIES_AVAILABLE] and check
bool is_allowed(Task * task){
foreach (Category sysC in stateCategories[sys.GetState()])
{
foreach (Category taskC in task.GetCategories())
{
if(sysC == taskC) return true;
}
}
return false;
}
That would of course be slow for a big number of categories.
You could improve this method by making this list of categories some another data structure, in which searching is not O(n) such that the code would look like this :
bool is_allowed(Task * task){
foreach (Category sysC in stateCategories[sys.GetState()])
{
if task.GetCategories().Contains(sysC) {
return true;
}
}
It depends
Recently I was listening to a tech talk on clean coding. The speaker was a test engineer, who emphasized on avoiding the "if" statements in the code and use polymorphism as much as possible. Also he advocated against global states.
I quite agree with him, yet i need a clarification on replacing the global state and "if" statement using polymorphism for the below scenario,
I have 3 states in my document. I want to change the state of the UI components based on the document state. Right now, i use "if" blocks and an enumeration type holding the current state of document to transition the states of UI components.
eg:
enum DOC_STATE
{
DOC_STATE_A = 0,
DOC_STATE_B,
DOC_STATE_C
};
void QMainWindow::handleUi(_docState)
{
switch(_docState)
{
case (DOC_STATE_A):
{
menu.disable();
....
}
case (DOC_STATE_B):
{
menu.enable();
...
}
case (DOC_STATE_C):
{
...
}
}
I think i can have separate child classes for each state and have the handleUI() method in each class. Calling handleUi() method calls the right method call. But say i maintain these objects in my doc, how do i switch from one object to other each time there is a transition in state?
In other words, how to handle UI transition by tracking the change in state of document without using a global state and "if" or Switch statements?
I use Qt. Thanks.
If you are using Qt, take a look at The Qt State Machine Framework and the State Machine Examples. No need to re-invent the wheel when your framework already provides a sports car :)
I don't think I understand the problem because the answer is too trivial: you replace the pointer to your state instance with a new state instance and discard the old one.