I need to write an application using C++ which handles input signal from various sources and end up with something like this:
InputManager: handle input signals and convert them to messages.
Processor: it will receive all messages from the input. Put it in a
queue and operating one by one.
Other modules.
// define states of the instance
enum class State {
A,
B,
C,
....
};
// handle input message, all the message passed to the Processor queue should be redirect to this function.
void onInput(std::shared_ptr<Message> msg) {
switch(msg->mgsId) {
case 1:
// do something
break;
case 2:
// do something
break;
default:
break;
}
}
....
The thing is, the Processor Class getting bigger and bigger when the number of signals increases; and if I have to do something break the flow like waiting for a specific event before continue operating, the code becomes very hard to read.
I know it's a very newbie question. But I have no idea how to restructure my code in a readable way.
Use the following answer (which I took from a comment by Aconcagua):
I'd write one class per signal type, create one class instance per
concrete signal and have all of them keep a link to the single queue
instance. If you give the classes one common base class, you might
even put all of them into a single std::vector (not by value, though,
otherwise you run into object slicing). – Aconcagua
I've written my own access layer to a game engine. There is a GameLoop which gets called every frame which lets me process my own code. I'm able to do specific things and to check if these things happened. In a very basic way it could look like this:
void cycle()
{
//set a specific value
Engine::setText("Hello World");
//read the value
std::string text = Engine::getText();
}
I want to test if my Engine-layer is working by writing automated tests. I have some experience in using the Boost Unittest Framework for simple comparison tests like this.
The problem is, that some things I want the engine to do are just processed after the call to cycle(). So calling Engine::getText() directly after Engine::setText(...) would return an empty string. If I would wait until the next call of cycle() the right value would be returned.
I now am wondering how I should write my tests if it is not possible to process them in the same cycle. Are there any best practices? Is it possible to use the "traditional testing" approach given by Boost Unittest Framework in such an environment? Are there perhaps other frameworks aimed at such a specialised case?
I'm using C++ for everything here, but I could imagine that there are answers unrelated to the programming language.
UPDATE:
It is not possible to access the Engine outside of cycle()
In your example above, std::string text = Engine::getText(); is the code you want to remember from one cycle but execute in the next. You can save it for later execution. For example - using C++11 you could use a lambda to wrap the test into a simple function specified inline.
There are two options with you:
If the library that you have can be used synchronously or using c++11 futures like facility (which can indicate the readyness of the result) then in your test case you can do something as below
void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (!Engine::isResultReady());
//read the value
assert(Engine::getText() == "WHATEVERVALUEYOUEXPECT");
}
If you dont have the above the best you can do have a timeout (this is not a good option though because you may have spurious failures):
void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (Engine::getText() != "WHATEVERVALUEYOUEXPECT") {
wait(1 millisec);
if (total_wait_time > 1 sec) // you can put whatever max time
assert(0);
}
}
I have tried looking for answer to this since three days back. It is either I have done something fundamentally wrong (that there's an obvious mistake) or the thing is too new to have any references, I can't seem to figure why simple cases like this would fail.
The following code uses PPL task library in C++ in a Windows Store application, simulating a file loading operation that takes 2 seconds before breaking out of the loop (of course this is to illustrate the problem with minimal codes, the real loop does other rendering to show progress, too).
The continuation part of the code (i.e. "fileLoaded = true") never gets called if I use "use_current" as the continuation context:
bool fileLoaded = false;
while (!fileLoaded)
{
concurrency::task<void>([this]()
{
// Simulate file load delay
concurrency::wait(2000);
}).then([this, &fileLoaded]()
{
fileLoaded = true; // This never gets executed!
// If the following is changed to "use_default" or
// "use_arbitrary", then this continuation gets called.
}, concurrency::task_continuation_context::use_current());
concurrency::wait(50);
}
The same code works if I use "use_default" or "use_arbitrary", and properly set "fileLoad" to "true". This code can be placed anywhere in a Windows Store C++ app (e.g. Direct2D app), and it would fail (I have placed it in "DirectXPage::DirectXPage" constructor body, which I expect it to be the main UI thread). Did I do something horribly wrong?
Thanks in advance for your help! :)
Since you are calling .then() on the UI thread, use_current() will cause the continuation to be scheduled for execution on the UI thread.
However, that continuation cannot run until the UI thread is free (i.e., when it is not doing any work). But, in your example, the UI thread is never free: the DirectXPage constructor is running on the UI thread. The DirectXPage constructor will not return until the continuation executes and the continuation cannot execute until the DirectXPage constructor returns.
You need to allow the constructor to return so that the UI thread is free to do other work (like execute the continuation).
Also note that if you are using fileLoaded for cross-thread communication, you need to use an std::atomic<bool> or some other proper synchronization object. A simple bool is insufficient for synchronization.
I've run into the following issue which is not difficult to solve by any stretch of the imagination but I would like to know what the best / most elegant solution is.
I have the following method that the prototype of looks like this:
bool Team::isEveryoneDead(int teamOnTurn);
There are two teams available and depending on what instance of the team is currently on turn, I would like to check whether every Character in the team is dead in this very particular order:
Loop trough all the Characters in the team that's not on turn first. Should there be any character that's alive, stop looping (and goto step 2.). Should there be noone alive, terminate the function and return.
Now that I know that the team that's not on turn contains at least one character that's alive, loop trough the team that's currently on turn and check for the same thing. Should I find someone alive, stop looping and terminate / return.
The argument int teamOnTurn allows me to resolve the instance of Team that's currently on turn. The order in which i evaluate the "alive condition" is of great importance here.
Now, there are several approaches that can be taken, say hardcoding the order (since there are only 2 possible orders) and resolving the order by checking who's on turn and then executing the branch that already has the specific order like this:
bool Team::isEveryoneDead(int teamOnTurn) {
if (Team::Blue == teamOnTurn) {
checkThis();
checkThat();
} else {
checkThat();
checkThis();
}
}
This solution however wouldn't quite work for say 5! permutations for specific call-ordering for more items. What technique should one deploy to solve this with the utmost elegance :) ?
Thanks in advance, Scarlet.
Try creating another internal method that actually does the checking, and let the isEveryoneDead() method orchestrate the order in which the teams are checked, maybe something like this:
bool Team::isEveryoneDead(int teamOnTurn) {
bool isFound = isEveryoneDeadInternal( /* params for team not on turn */ );
if(isFound) {
isFound = isEveryoneDeadInternal( /* params for team on turn */ );
}
return isFound;
}
// This method know nothing about on turn or off turn
bool Team:isEveryoneDeadInternal() {
// Loop through all characters in the team, checking if any are alive
// When the first live character is found, return true
// else return false
}
This is a concept called DRY : Dont Repeat Yourself
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;