In what situation should we adopt state pattern? - c++

In what situation should we adopt state pattern?
I've been assigned to maintain a project, the project state machine was implemented by switch-case that are 2000+ lines long. It will be hard to expand function, so I would like to refactor it.
I'm surveying state design pattern, but I have some confusions.
A simple example:
1. Initial state "WAIT", wait user send download command
2. While user send download command, move to "CONNECT" state, connect to server
3. After connection is created, move to "DOWNLOADING" state, keep receive data from server
4. While the data download complete, move to "DISCONNECT", disconnect link with server
5. After disconnect, move to "WAIT" state, wait user send download command
A simple state machine pic
Method 1: Before I survey state pattern, I think a trivial method --- wrapper different state behavior in different function, use a function pointer array to point each state function, and change state by call function.
typedef enum {
WAIT,
CONNECT,
DOWNLOADING,
DISCONNECT
}state;
void (*statefunction[MAX_STATE])(void) =
{
WAITState,
CONNECTState,
DOWNLOADINGState,
DISCONNECTState
};
void WAITState(void)
{
//do wait behavior
//while receive download command
//statefunction[CONNECT]();
}
void CONNECTState(void)
{
//do connect behavior
//while connect complete
//statefunction[DOWNLOADING]();
}
void DOWNLOADINGState(void)
{
//do downloading behavior
//while download complete
//statefunction[DISCONNECT]();
}
void DISCONNECTState(void)
{
//do disconnect behavior
//while disconnect complete
//statefunction[WAIT]();
}
Method 2: The state pattern encapsulates different state and its behavior in different class (object-oriented state machine), uses polymorphism to implement different state behavior, and defines a common interface for all concrete states.
class State
{
public:
virtual void Handle(Context *pContext) = 0;
};
class Context
{
public:
Context(State *pState) : m_pState(pState){}
void Request()
{
if (m_pState)
{
m_pState->Handle(this);
}
}
private:
State *m_pState;
};
class WAIT : public State
{
public:
virtual void Handle(Context *pContext)
{
//do wait behavior
}
};
class CONNECT : public State
{
public:
virtual void Handle(Context *pContext)
{
//do connect behavior
}
};
class DOWNLOADING : public State
{
public:
virtual void Handle(Context *pContext)
{
//do downloading behavior
}
};
class DISCONNECT : public State
{
public:
virtual void Handle(Context *pContext)
{
//do disconnect behavior
}
};
I'm wondering whether the state pattern batter than function pointer in this case or not...
Using function pointer only also can improve readability (compare with switch-case), and more simple.
The state pattern will create several class, and more complex than using function pointer only.
What's the advantage of using state pattern?
Thanks for your time!

What's the advantage of using the state pattern?
First, one needs to notice, that both of the methods you've provided, are in fact examples of the very same pattern. One of the methods describes a function-based implementation, while the other one takes more of an object oriented approach.
That being said, the pattern itself has a few advantages:
It limits the number of states, a program can be in, and thus - eliminates undefined states,
It allows for easier expansion of the application, by adding new states, instead of refactoring the whole code,
From a company perspective, it is safe, even when multiple people work on the same class,
Since you tagged the question as related to c++, it is best to take into account what the language both gives and requires. While classes offer inheritance, a large number of classes can greatly increase the compilation time. Hence, when it comes to implementations, if your state machine is large, static polymorphism may be the way to go.

Related

Communication between 2 threads C++ UNIX

I need your help with wxWidgets. I have 2 threads (1 wxTimer and 1 wxThread), I need communicate between this 2 threads. I have a class that contains methods to read/write variable in this class. (Share Memory with this object)
My problem is: I instanciate with "new" this class in one thread but I don't know that necessary in second thread. Because if instanciate too, adress of variable are differents and I need communicate so I need even value in variable :/
I know about need wxSemaphore to prevent error when to access same time.
Thanks you for your help !
EDIT: My code
So, I need make a link with my code. Thanks you for all ;)
It's my declaration for my wxTimer in my class: EvtFramePrincipal (IHM)
In .h
EvtFramePrincipal( wxWindow* parent );
#include <wx/timer.h>
wxTimer m_timer;
in .cpp -Constructor EvtFramePrincipal
EvtFramePrincipal::EvtFramePrincipal( wxWindow* parent )
:
FramePrincipal( parent ),m_timer(this)
{
Connect(wxID_ANY,wxEVT_TIMER,wxTimerEventHandler(EvtFramePrincipal::OnTimer),NULL,this);
m_timer.Start(250);
}
So I call OnTimer method every 250ms with this line.
For my second thread start from EvtFramePrincipal (IHM):
in .h EvtFramePrincipal
#include "../Client.h"
Client *ClientIdle;
in .cpp EvtFramePrincipal
ClientIdle= new Client();
ClientIdle->Run();
In .h Client (Thread)
class Client: public wxThread
public:
Client();
virtual void *Entry();
virtual void OnExit();
In .cpp Client (Thread)
Client::Client() : wxThread()
{
}
So here, no probleme, thread are ok ?
Now I need that this class that use like a messenger between my 2 threads.
#ifndef PARTAGE_H
#define PARTAGE_H
#include "wx/string.h"
#include <iostream>
using std::cout;
using std::endl;
class Partage
{
public:
Partage();
virtual ~Partage();
bool Return_Capteur_Aval()
{ return Etat_Capteur_Aval; }
bool Return_Capteur_Amont()
{ return Etat_Capteur_Amont; }
bool Return_Etat_Barriere()
{ return Etat_Barriere; }
bool Return_Ouverture()
{ return Demande_Ouverture; }
bool Return_Fermeture()
{ return Demande_Fermeture; }
bool Return_Appel()
{ return Appel_Gardien; }
void Set_Ouverture(bool Etat)
{ Demande_Ouverture=Etat; }
void Set_Fermeture(bool Etat)
{ Demande_Fermeture=Etat; }
void Set_Capteur_Aval(bool Etat)
{ Etat_Capteur_Aval=Etat; }
void Set_Capteur_Amont(bool Etat)
{ Etat_Capteur_Amont=Etat; }
void Set_Barriere(bool Etat)
{ Etat_Barriere=Etat; }
void Set_Appel(bool Etat)
{ Appel_Gardien=Etat; }
void Set_Code(wxString valeur_code)
{ Code=valeur_code; }
void Set_Badge(wxString numero_badge)
{ Badge=numero_badge; }
void Set_Message(wxString message)
{
Message_Affiche=wxT("");
Message_Affiche=message;
}
wxString Get_Message()
{
return Message_Affiche;
}
wxString Get_Code()
{ return Code; }
wxString Get_Badge()
{ return Badge; }
protected:
private:
bool Etat_Capteur_Aval;
bool Etat_Capteur_Amont;
bool Etat_Barriere;
bool Demande_Ouverture;
bool Demande_Fermeture;
bool Appel_Gardien;
wxString Code;
wxString Badge;
wxString Message_Affiche;
};
#endif // PARTAGE_H
So in my EvtFramePrincipal(wxTimer), I make a new for this class. But in other thread (wxThread), what I need to do to communicate ?
If difficult to understand so sorry :/
Then main thread should create first the shared variable. After it, you can create both threads and pass them a pointer to the shared variable.
So, both of them, know how interact with the shared variable. You need to implement a mutex or wxSemaphore in the methods of the shared variable.
You can use a singleton to get access to a central object.
Alternatively, create the central object before creating the threads and pass the reference to the central object to threads.
Use a mutex in the central object to prevent simultaneous access.
Creating one central object on each thread is not an option.
EDIT 1: Adding more details and examples
Let's start with some assumptions. The OP indicated that
I have 2 threads (1 wxTimer and 1 wxThread)
To tell the truth, I know very little of the wxWidgets framework, but there's always the documentation. So I can see that:
wxTimer provides a Timer that will execute the wxTimer::Notify() method when the timer expires. The documentation doesn't say anything about thread-execution (although there's a note A timer can only be used from the main thread which I'm not sure how to understand). I can guess that we should expect the Notify method will be executed in some event-loop or timer-loop thread or threads.
wxThread provides a model for Thread execution, that runs the wxThread::Entry() method. Running a wxThread object will actually create a thread that runs the Entry method.
So your problem is that you need same object to be accessible in both wxTimer::Notify() and wxThread::Entry() methods.
This object:
It's not one variable but a lot of that store in one class
e.g.
struct SharedData {
// NOTE: This is very simplistic.
// since the information here will be modified/read by
// multiple threads, it should be protected by one or more
// mutexes
// so probably a class with getter/setters will be better suited
// so that access with mutexes can be enforced within the class.
SharedData():var2(0) { }
std::string var1;
int var2;
};
of which you have somewhere an instance of that:
std::shared_ptr<SharedData> myData=std::make_shared<SharedData>();
or perhaps in pointer form or perhaps as a local variable or object attribute
Option 1: a shared reference
You're not really using wxTimer or wxThread, but classes that inherit from them (at least the wxThread::Entry() is pure virtual. In the case of wxTimer you could change the owner to a different wxEvtHandler that will receive the event, but you still need to provide an implementation.
So you can have
class MyTimer: public wxTimer {
public:
void Notify() {
// Your code goes here
// but it can access data through the local reference
}
void setData(const std::shared_ptr<SharedData> &data) {
mLocalReference=data
}
private:
std::shared_ptr<SharedData> mLocalReferece
};
That will need to be set:
MyTimer timer;
timer.setData(myData);
timer.StartOnece(10000); // wake me up in 10 secs.
Similarly for the Thread
class MyThread: public wxThread {
public:
void Entry() {
// Your code goes here
// but it can access data through the local reference
}
void setData(const std::shared_ptr<SharedData> &data) {
mLocalReference=data
}
private:
std::shared_ptr<SharedData> mLocalReferece
};
That will need to be set:
MyThread *thread=new MyThread();
thread->setData(myData);
thread->Run(); // threads starts running.
Option2 Using a singleton.
Sometimes you cannot modify MyThread or MyTimer... or it is too difficult to route the reference to myData to the thread or timer instances... or you're just too lazy or too busy to bother (beware of your technical debt!!!)
We can tweak the SharedData into:
struct SharedData {
std::string var1;
int var2;
static SharedData *instance() {
// NOTE that some mutexes are needed here
// to prevent the case where first initialization
// is executed simultaneously from different threads
// allocating two objects, one of them leaked.
if(!sInstance) {
sInstance=new SharedData();
}
return sInstance
}
private:
SharedData():var2(0) { } // Note we've made the constructor private
static SharedData *sInstance=0;
};
This object (because it only allows the creation of a single object) can be accessed from
either MyTimer::Notify() or MyThread::Entry() with
SharedData::instance()->var1;
Interlude: why Singletons are evil
(or why the easy solution might bite you in the future).
What is so bad about singletons?
Why Singletons are Evil
Singletons Are Evil
My main reasons are:
There's one and only one instance... and you might think that you only need one now, but who knows what the future will hold, you've taken an easy solution for a coding problem that has far reaching consequences architecturally and that might be difficult to revert.
It will not allow doing dependency injection (because the actual class is used in the accessing the object).
Still, I don't think is something to completely avoid. It has its uses, it can solve your problem and it might save your day.
Option 3. Some middle ground.
You could still organize your data around a central repository with methods to access different instances (or different implementations) of the data.
This central repository can be a singleton (it is really is central, common and unique), but is not the shared data, but what is used to retrieve the shared data, e.g. identified by some ID (that might be easier to share between the threads using option 1)
Something like:
CentralRepository::instance()->getDataById(sharedId)->var1;
EDIT 2: Comments after OP posted (more) code ;)
It seems that your object EvtFramePrincipal will execute both the timer call back and it will contain the ClientIdle pointer to a Client object (the thread)... I'd do:
Make the Client class contain a Portage attribute (a pointer or a smart pointer).
Make the EvtFramePrincipal contain a Portage attribute (a pointer or smart pointer). I guess this will have the lifecycle of the whole application, so the Portage object can share that lifecycle too.
Add Mutexes locking to all methods setting and getting in the Portage attribute, since it can be accessed from multiple threads.
After the Client object is instantiated set the reference to the Portage object that the EvtFramePrincipal contains.
Client can access Portage because we've set its reference when it was created. When the Entry method is run in its thread it will be able to access it.
EvtFramePrincipal can access the Portage (because it is one of its attributes), so the event handler for the timer event will be able to access it.

How can I do automata/state machine coding in C++?

I have used it in another programming language and It's very usefull.
I cannot find anything about this for C++.
Let's for example take the following code:
void change();
enum
{
end = 0,
gmx
}
int
gExitType;
int main()
{
gExitType = end;
SetTimer(&change, 10000, 0);
return 0;
}
void ApplicationExit()
{
switch (gExitType)
{
case end:
printf("This application was ended by the server");
case gmx:
printf("This application was ended by the timer");
}
::exit(0);
}
void change()
{
gExitType = gmx;
ApplicationExit();
}
That's kind of how we would do it in C++, but when using state machine/automata I could do something like this in the other language:
void change();
int main()
{
state exitType:end;
SetTimer(&change, 10000, 0);
return 0;
}
void ApplicationExit() <exitType:end>
{
printf("This application was ended by the server");
}
void ApplicationExit() <exitType:gmx>
{
printf("This application ended by the timer");
}
void change()
{
state exitType:gmx;
ApplicationExit();
}
In my opition this is a really elegant way to achieve things.
How would I do this in C++? This code doesn't seem to work (obviously as I cannot find anything automata related to C++)
To clarify my opinion:
So what are the advantages to using this technique? Well, as you can clearly see the code is smaller; granted I added an enum to the first version to make the examples more similar but the ApplicationExit functions are definately smaller. It's also alot more explicit - you don't need large switch statements in functions to determine what's going on, if you wanted you could put the different ApplicationExits in different files to handle different sets of code independently. It also uses less global variables.
There are C++ libraries like Boost.statechart that specifically try to provide rich support for encoding state machines:
http://www.boost.org/doc/libs/1_54_0/libs/statechart/doc/tutorial.html
Besides this, one very elegant way to encode certain types of state machines is by defining them as a couroutine:
http://c2.com/cgi/wiki?CoRoutine
http://eli.thegreenplace.net/2009/08/29/co-routines-as-an-alternative-to-state-machines/
Coroutines are not directly supported in C++, but there are two possible approaches for
implementing them:
1) Using a technique similar to implementing a duff's device, explained in details here:
http://blog.think-async.com/search/label/coroutines
This is very similar to how C#'s iterators work for example and one limitation is that yielding form the coroutine can be done only from the topmost function in the coroutine call-stack. OTOH, the advantage of this method is that very little memory is required for each instance of the coroutine.
2) Allocating a separate stack and registers space for each coroutine.
This essentially makes the coroutine a full-blown thread of execution with the only difference that the user has full responsibility for the thread scheduling (also known as cooperative multi-tasking).
A portable implementation is available from boost:
http://www.boost.org/doc/libs/1_54_0/libs/coroutine/doc/html/coroutine/intro.html
For this particular example, you could use objects and polymorphism to represent the different states. For example:
class StateObject
{
public:
virtual void action(void) = 0;
};
class EndedBy : public StateObject
{
private:
const char *const reason;
public:
EndedBy( const char *const reason_ ) : reason( reason_ ) { }
virtual void action(void)
{
puts(reason);
}
};
EndedBy EndedByServer("This application was ended by the server");
EndedBy EndedByTimer ("This application ended by the timer");
StateObject *state = &EndedByServer;
void change()
{
state = &EndedByTimer;
}
void ApplicationExit()
{
state->action();
::exit(0);
}
int main()
{
SetTimer(&change, 10000, 0);
// whatever stuff here...
// presumably eventually causes ApplicationExit() to get called before return 0;
return 0;
}
That said, this isn't great design, and it isn't an FSM in the general sense. But, it would implement your immediate need.
You might look up the State Pattern (one reference: http://en.wikipedia.org/wiki/State_pattern ) for a more general treatment of this pattern.
The basic idea, though, is that each state is a subclass of some common "state" class, and you can use polymorphism to determine the different actions and behaviors represented by each state. A pointer to the common "state" base class then keeps track of the state you're currently in.
The state objects may be different types, or as in my example above, different instances of the same object configured differently, or a blend.
You can use Template value specialization over an int to achieve pretty much what you want.
(Sorry I'm at my tablet so I cannot provide an example, I will update on Sunday)

Cancelling a thread running a long operation

I'm trying to work out a design predicament I have.
ClassWithLongOperation
{
Run()
{
RecrusiveOperation();
}
RecrusiveOperation()
{
/* RECURSION */
}
}
MyThread
{
ClassWithLongOperation Op1(10);
Op1.Run(); // Takes several minutes.
ClassWithLongOperation Op2(20);
Op2.Run();
SomeOtherClassWithLongOperation Op3;
Op3.Run();
// Do some other stuff
}
The GUI starts MyThread, which runs for a good 5-6 minutes. I want to be able to have a big fat Cancel button on my GUI, so the user can cancel the operation.
I could create a global boolean variable bCancelled, and check if its been set in RecursiveOperation, but I want to be a good C++ & OO programmer and avoid global variables. Especially if they would have to spread across multiple files.
So how would I (following good design) safely cancel MyThread? What could I change in my setup to allow this?
I'm also using _beginthreadex to start the thread, but I could use boost if it would allow for an easier solution.
Your flag not need to be global to your entire program, but it needs to be visible to your class code. Create the flag to be a private instance member and a public function to change it to false/true. In your recursive function, test its value to verify if the task should continue. When you want, set its value to false (through the function of course) to stop the recursive calls, i.e., when the user clicks the button you call the function in the desired instance. This way you will not break any OO principle, since you have a private flag and a public member function to safely change it.
Using a global variable is actually not the worst thing in the world. Having a proliferation of unnecessary global variables leads to maintenance nightmares, but it actually sounds like a quick and easy-to-understand solution here. But if you want a clean OO solution, this is certainly possible:
EDIT My original post overlooked the fact that you want to be able to run several operations in sequence, and if any of them is cancelled, none of the remaining operations are performed. This means it's more useful to keep the bool flag inside the canceller, instead of separately in each cancellable operation; and exceptions are the nicest way to handle the actual control flow. I've also tightened up a few things (added volatile for the flag itself, made names clearer, restricted unnecessary access rights).
// A thing that can cancel another thing by setting a bool to true.
class Canceller {
public:
Canceller : cancelledFlag(false) {}
void RegisterCancellee(Cancellee const& c) {
c.RegisterCanceller(cancelledFlag);
}
void Cancel() {
cancelledFlag = true;
}
private:
volatile bool cancelledFlag;
};
class CancelButton : public Canceller {
...
// Call Cancel() from on-click event handler
...
};
class Cancellation : public std::exception {
public:
virtual const char* what() const throw() {
return "User cancelled operation";
}
};
// A thing that can be cancelled by something else.
class Cancellee {
friend class Canceller; // Give them access to RegisterCanceller()
protected:
Cancellee() : pCancelledFlag(0) {}
// Does nothing if unconnected
void CheckForCancellation() {
if (pCancelledFlag && *pCancelledFlag) throw Cancellation();
}
private:
void RegisterCanceller(volatile bool& cancelledFlag) {
pCancelledFlag = &cancelledFlag;
}
volatile bool* pCancelledFlag;
};
class Op1 : public Cancellee { // (And similarly for Op2 and Op3)
...
// Poll CheckForCancellation() inside main working loop
...
};
MyThread
{
CancelButton cancelButton("CANCEL!");
try {
ClassWithLongOperation Op1(10);
cancelButton.RegisterCancellee(Op1);
Op1.Run(); // Takes several minutes.
ClassWithLongOperation Op2(20);
cancelButton.RegisterCancellee(Op2);
Op2.Run();
SomeOtherClassWithLongOperation Op3;
cancelButton.RegisterCancellee(Op3);
Op3.Run();
} catch (Cancellation& c) {
// Maybe write to a log file
}
// Do some other stuff
}
The "double bouncing" registration allows the canceller to give access to a private flag variable.
The most important thing is to not use thread termination functions, except in very specialised cases. Why? They don't run destructors. Nor do they give the target thread any chance to "clean up".
Instead of using a global variable, add a method to ClassWithLongOperation and/or MyThread, something like cancelOperation() that will set an internal boolean variable. The appropriate class methods would then need to check the variable at appropriate moments.
You could implement a Stop() method for your ClassWithLongOperation and have the event handler for BigFatCancelButton to call this Stop() method for the current operation.
... Or add a Stop() method to the Thread class and make the work objects be aware of the threads they're running in. You may as well throw in a Stop() method for the work objects. Depending on what's more important: Stop the thread or the work object.

State machine in C++ via singleton?

I think a good way of implementing a state machine is to use the singleton pattern.
For example it can look like this:
class A
{
private:
friend class State;
State* _state;
void change_state(State* state) { _state = state; }
};
class State
{
virtual void action(A *a) = 0;
private:
void change_state(A *a, State *state) { a->change_state(state); }
};
class StateA : public State
{
public:
static State* get_instance()
{
static State *state = new StateA;
return state;
}
virtual void action(A *a) { change_state(a, StateB::get_instance(); }
};
class StateB : public State
{
public:
...
virtual void action(A *a) { change_state(a, StateA::get_instance(); }
};
My question is: I have read many articles about that the singleton pattern is so evil. Implementing this without a singleton pattern you have to call new everytime you change state, so for those who dont like singleton, how would you implement the state machine pattern?
I don't think that the singleton pattern is appropriate here. Singletons are good for representing abstract entities or physical objects for which there really is only one copy. To steal an example from Java, there is only one runtime environment in which a particular instance of the program executes. Singletons are good for representing these objects because they give the entire program the ability to name and reference it while preserving encapsulation and allowing for multiple possible backends.
Given this, I disagree that the singleton is the best route to take for your state machine. If you do implement it as a singleton, you're saying that is always exactly one copy of that state machine. But what if I want to have two state machines running in parallel? Or no state machines at all? What if I want my own local state machine so I can experiment on it to see what happens to it? If your state machine is a singleton, I can't do any of these things because there really is only one state machine used by the entire program.
Now, depending on how you're using the state machine, perhaps it is appropriate. If the state machine controls the overall execution of the program, then it might be a good idea. For example, if you're developing a video game and want a state machine to control whether you're in the menu, or in a chat area, or playing the game, then it would be totally fine to have a singleton state machine because there is only one logical state of the program at any time. From your question, though, I can't deduce if this is the case.
As for how to implement the state machine without a singleton, you might want to make the state machine object allocate its own copy of every state and build up the transition table (if you need explicit state objects), or just have a giant switch statement and a single enumerated value controlling what state you're in. If you have a single instance of the state machine this is no less efficient than the current version, and if you have multiple instances it allows you to store local information in each state without polluting a global copy of the states that could be read by other parts of the program.
Your StateA, StateB classes have no data members. Presumably other states won't have modifiable data members either, since if they did then that state would be weirdly shared between different instances of A, that is different state machines running concurrently.
So your singletons have avoided half of the problem with the pattern (global mutable state). In fact with only a small change to your design, you could replace the state classes with functions; replace the pointers to their instances with function pointers; and replace the virtual call to action with a call through the current function pointer. If someone gives you a lot of hassle for using singletons, but you're confident that your design is correct, you could make this minor change and see if they notice that their "correction" has made no significant difference at all to the design.
The other half of the problem with singletons still wouldn't be fixed though, and that's fixed dependencies. With your singletons, it is not possible to mock StateB in order to test StateA in isolation, or to introduce flexibility when you want to introduce a new state machine to your library which is the same as the current one except that StateA goes to StateC instead of StateB. You may or may not consider that a problem. If you do, then rather than making each state a singleton, you need to make things more configurable.
For example, you could give each state some identifier (a string or perhaps a member of an enum), and for each identifier register a State* somewhere in class A. Then rather than flipping to the singleton instance of StateB, StateA could could flip to whatever state object is used to represent "state B" in this state machine. That could then be a test mock for certain instances. You would still call new once per state per machine, but not once per state change.
In effect, this is still the strategy pattern for class A as in your design. But rather than having a single strategy to move the state machine forward, and continually replace that as the state changes, we have one strategy per state the machine passes through, all with the same interface. Another option in C++, that will work for some uses but not others, is to use (a form of) policy-based design instead of strategies. Then each state is handled by a class (provided as a template argument) rather than an object (set at runtime). The behavior of your state machine is therefore fixed at compile time (as in your current design), but can be configured by changing template arguments rather than by somehow altering or replacing the class StateB. Then you don't have to call new at all - create a single instance of each state in the state machine, as a data member, use a pointer to one of those to represent the current state, and make a virtual call on it as before. Policy-based design doesn't usually need virtual calls, because usually the separate policies are completely independent, whereas here they implement a common interface and we select between them at runtime.
All of this assumes that A knows about a finite set of states. This may not be realistic (for example, A might represent an all-purpose programmable state machine that should accept an arbitrary number of arbitrary states). In that case, you need a way to build up your states: first create an instance of StateA and an instance of StateB. Since each state has one exit path, each state object should have one data member which is a pointer to the new state. So having created the states, set the StateA instances "next state" to the instance of StateB and vice-versa. Finally, set A's current state data member to the instance of StateA, and start it running. Note that when you do this, you are creating a cyclic graph of dependencies, so to avoid memory leaks you might have to take special resource-handling measures beyond reference-counting.
In your code, you're not associating a state with the state machine the state belongs to (assuming that class A is the state machine). This information is passed in to the action method. So, if you had two instances of class A (i.e. two state machines) then you could end up having a state update the wrong state machine.
If you're doing this to avoid repeated calls to new and delete for speed purposes, then this is probably a premature optimisation. A better solution, if you can show that using new and delete is too slow / causes other issues (memory fragmentation for example), is to define an operator new / delete in the State base class that allocates from its own memory pool.
Here's some pseudocode for how the state machine I'm currently using works:
class StateMachine
{
public:
SetState (State state) { next_state = state; }
ProcessMessage (Message message)
{
current_state->ProcessMessage (message);
if (next_state)
{
delete current_state;
current_state = next_state;
next_state = 0;
}
}
private:
State current_state, next_state;
}
class State
{
public:
State (StateMachine owner) { m_owner = owner; }
virtual ProcessMessage (Message message) = 0;
void *operator new (size_t size) // allocator
{
return memory from local memory pool
}
void operator delete (void *memory) // deallocator
{
put memory back into memory pool
}
protected:
StateMachine m_owner;
};
class StateA : State
{
public:
StateA (StateMachine owner) : State (owner) {}
ProcessMessage (Message message)
{
m_owner->SetState (new StateB (m_owner));
}
}
The memory pool could be an array of chunks of memory, each big enough to hold any State, with a pair of lists, one for the allocated blocks and one for the unallocated blocks. Allocating a block then becomes a process of removing a block from the unallocated list and adding it to the allocated list. Freeing is then the reverse process. I think the term 'free list' for this type of allocation strategy. It is very fast but has some wasted memory.
One approach which assumes that all state objects live along StateMachine could be like this one:
enum StateID
{
STATE_A,
STATE_B,
...
};
// state changes are triggered by events
enum EventID
{
EVENT_1,
EVENT_2,
...
};
// state manager (state machine)
class StateMachine
{
friend StateA;
friend StateB;
...
public:
StateMachine();
~StateMachine();
// state machine receives events from external environment
void Action(EventID eventID);
private:
// current state
State* m_pState;
// all states
StateA* m_pStateA;
StateB* m_pStateB;
...
void SetState(StateID stateID);
};
StateMachine::StateMachine()
{
// create all states
m_pStateA = new StateA(this, STATE_A);
m_pStateB = new StateB(this, STATE_B);
...
// set initial state
m_pState = m_pStateA;
}
StateMachine::~StateMachine()
{
delete m_pStateA;
delete m_pStateB;
...
}
void StateMachine::SetState(StateID stateID)
{
switch(stateID)
{
case STATE_A:
m_pState = m_pStateA;
break;
case STATE_B:
m_pState = m_pStateA;
break;
...
}
}
void StateMachine::Action(EventID eventID)
{
// received event is dispatched to current state for processing
m_pState->Action(eventID);
}
// abstract class
class State
{
public:
State(StateMachine* pStateMachine, StateID stateID);
virtual ~State();
virtual void Action(EventID eventID) = 0;
private:
StateMachine* m_pStateMachine;
StateID m_stateID;
};
class StateA : public State
{
public:
StateA(StateMachine* pStateMachine, StateID stateID);
void Action(EventID eventID);
};
StateA::StateA(StateMachine* pStateMachine, StateID stateID) :
State(pStateMachine, stateID) {...}
void StateA::Action(EventID eventID)
{
switch(eventID)
{
case EVENT_1:
m_pStateMachine->SetState(STATE_B);
break;
case EVENT_2:
m_pStateMachine->SetState(STATE_C);
break;
...
}
}
void StateB::Action(EventID eventID)
{
switch(eventID)
{
...
case EVENT_2:
m_pStateMachine->SetState(STATE_A);
break;
...
}
}
int main()
{
StateMachine sm;
// state machine is now in STATE_A
sm.Action(EVENT_1);
// state machine is now in STATE_B
sm.Action(EVENT_2);
// state machine is now in STATE_A
return 0;
}
In more complex solution StateMachine would have event queue and event loop which would wait for events from the queue and dispatch them to the current state. All time-consuming operations in StateX::Action(...) should run in separate (worker) thread in order to prevent blocking event loop.
A design approach I am considering is to create a state factory that is a singleton, so that more then one state machine can use the state objects produced by the factory.
But this thought has taken me to the idea of implementing my state factory with flyweight pattern and that's where I have stopped.
Basically, I need to research the advantages of implementing the state objects as flyweights and then the advantages of a flyweight design pattern.
I have heard of this state machines using this type of pattern, but not sure if it will work for my needs.
Anyway, I was doing some research and bumped into this post. Just thought I would share...

Game Objects Talking To Each Other [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
What is a good way of dealing with objects and having them talk to each other?
Up until now all my games hobby/student have been small so this problem was generally solved in a rather ugly way, which lead to tight integration and circular dependencies. Which was fine for the size of projects I was doing.
However my projects have been getting bigger in size and complexity and now I want to start re-using code, and making my head a simpler place.
The main problem I have is generally along the lines of Player needs to know about the Map and so does the Enemy, this has usually descended into setting lots of pointers and having lots of dependencies, and this becomes a mess quickly.
I have thought along the lines of a message style system. but I cant really see how this reduces the dependencies, as I would still be sending the pointers everywhere.
PS: I guess this has been discussed before, but I don't know what its called just the need I have.
EDIT: Below I describe a basic event messaging system I have used over and over. And it occurred to me that both school projects are open source and on the web. You can find the second version of this messaging system (and quite a bit more) at http://sourceforge.net/projects/bpfat/ .. Enjoy, and read below for a more thorough description of the system!
I've written a generic messaging system and introduced it into a handful of games that have been released on the PSP as well as some enterprise level application software. The point of the messaging system is to pass only the data around that is needed for processing a message or event, depending on the terminology you want to use, so that objects do not have to know about each other.
A quick rundown of the list of objects used to accomplish this is something along the lines of:
struct TEventMessage
{
int _iMessageID;
}
class IEventMessagingSystem
{
Post(int iMessageId);
Post(int iMessageId, float fData);
Post(int iMessageId, int iData);
// ...
Post(TMessageEvent * pMessage);
Post(int iMessageId, void * pData);
}
typedef float(*IEventMessagingSystem::Callback)(TEventMessage * pMessage);
class CEventMessagingSystem
{
Init ();
DNit ();
Exec (float fElapsedTime);
Post (TEventMessage * oMessage);
Register (int iMessageId, IEventMessagingSystem* pObject, FObjectCallback* fpMethod);
Unregister (int iMessageId, IEventMessagingSystem* pObject, FObjectCallback * fpMethod);
}
#define MSG_Startup (1)
#define MSG_Shutdown (2)
#define MSG_PlaySound (3)
#define MSG_HandlePlayerInput (4)
#define MSG_NetworkMessage (5)
#define MSG_PlayerDied (6)
#define MSG_BeginCombat (7)
#define MSG_EndCombat (8)
And now a bit of an explanation. The first object, TEventMessage, is the base object to represent data sent by the messaging system. By default it will always have the Id of the message being sent so if you want to make sure you have received a message you were expecting you can (Generally I only do that in debug).
Next up is the Interface class that gives a generic object for the messaging system to use for casting while doing callbacks. Additionally this also provides an 'easy to use' interface for Post()ing different data types to the messaging system.
After that we have our Callback typedef, Simply put it expects an object of the type of the interface class and will pass along a TEventMessage pointer... Optionally you can make the parameter const but I've used trickle up processing before for things like stack debugging and such of the messaging system.
Last and at the core is the CEventMessagingSystem object. This object contains an array of callback object stacks (or linked lists or queues or however you want to store the data). The callback objects, not shown above, need to maintain (and are uniquely defined by) a pointer to the object as well as the method to call on that object. When you Register() you add an entry on the object stack under the message id's array position. When you Unregister() you remove that entry.
That is basically it. Now this does have the stipulation that everything needs to know about the IEventMessagingSystem and the TEventMessage object... but this object should Not be changing that often and only passes the parts of information that are vital to the logic dictated by the event being called. This way a player doesn't need to know about the map or the enemy directly for sending events off to it. A managed object can call an API to a larger system also, without needing to know anything about it.
For example: When an enemy dies you want it to play a sound effect. Assuming you have a sound manager that inherits the IEventMessagingSystem interface, you would set up a callback for the messaging system that would accept a TEventMessagePlaySoundEffect or something of that ilk. The Sound Manager would then register this callback when sound effects are enabled (or unregister the callback when you want to mute all sound effects for easy on/off abilities). Next, you would have the enemy object also inherit from the IEventMessagingSystem, put together a TEventMessagePlaySoundEffect object (would need the MSG_PlaySound for its Message ID and then the ID of the sound effect to play, be it an int ID or the name of the sound effect) and simply call Post(&oEventMessagePlaySoundEffect).
Now this is just a very simple design with no implementation. If you have immediate execution then you have no need to buffer the TEventMessage objects (What I used mostly in console games). If you are in a multi-threaded environment then this is a very well defined way for objects and systems running in separate threads to talk to each other, but you will want to preserve the TEventMessage objects so the data is available when processing.
Another alteration is for objects that only ever need to Post() data, you can create a static set of methods in the IEventMessagingSystem so they do not have to inherit from them (That is used for ease of access and callback abilities, not -directly- needed for Post() calls).
For all the people who mention MVC, it is a very good pattern, but you can implement it in so many different manners and at different levels. The current project I am working on professionally is an MVC setup about 3 times over, there is the global MVC of the entire application and then design wise each M V and C also is a self-contained MVC pattern. So what I have tried to do here is explain how to make a C that is generic enough to handle just about any type of M without the need to get into a View...
For example, an object when it 'dies' might want to play a sound effect.. You would make a struct for the Sound System like TEventMessageSoundEffect that inherits from the TEventMessage and adds in a sound effect ID (Be it a preloaded Int, or the name of the sfx file, however they are tracked in your system). Then all the object just needs to put together a TEventMessageSoundEffect object with the appropriate Death noise and call Post(&oEventMessageSoundEffect); object.. Assuming the sound is not muted (what you would want to Unregister the Sound Managers.
EDIT: To clarify this a bit in regards to the comment below:
Any object to send or receive a message just needs to know about the IEventMessagingSystem interface, and this is the only object the EventMessagingSystem needs to know of all the other objects. This is what gives you the detachment. Any object who wants to receive a message simply Register(MSG, Object, Callback)s for it. Then when an object calls Post(MSG,Data) it sends that to the EventMessagingSystem via the interface it knows about, the EMS will then notify each registered object of the event. You could do a MSG_PlayerDied that other systems handle, or the player can call MSG_PlaySound, MSG_Respawn, etc to let things listening for those messages to act upon them. Think of the Post(MSG,Data) as an abstracted API to the different systems within a game engine.
Oh! One other thing that was pointed out to me. The system I describe above fits the Observer pattern in the other answer given. So if you want a more general description to make mine make a bit more sense, that is a short article that gives it a good description.
Hope this helps and Enjoy!
the generic solutions for communication between objects avoiding tight coupling:
Mediator pattern
Observer pattern
Here is a neat event system written for C++11 you can use. It uses templates and smart pointers as well as lambdas for the delegates. It's very flexible. Below you will also find an example. Email me at info#fortmax.se if you have questions about this.
What these classes gives you is a way to send events with arbitrary data attached to them and an easy way to directly bind functions that accept already converted argument types that the system casts and checks for correct conversion prior to calling your delegate.
Basically, every event is derived from IEventData class (you can call it IEvent if you want). Each "frame" you call ProcessEvents() at which point the event system loops through all the delegates and calls the delegates that have been supplied by other systems that have subscribed to each event type. Anyone can pick which events they would like to subscribe to, as each event type has a unique ID. You can also use lambdas to subscribe to events like this: AddListener(MyEvent::ID(), [&](shared_ptr ev){
do your thing }..
Anyway, here is the class with all the implementation:
#pragma once
#include <list>
#include <memory>
#include <map>
#include <vector>
#include <functional>
class IEventData {
public:
typedef size_t id_t;
virtual id_t GetID() = 0;
};
typedef std::shared_ptr<IEventData> IEventDataPtr;
typedef std::function<void(IEventDataPtr&)> EventDelegate;
class IEventManager {
public:
virtual bool AddListener(IEventData::id_t id, EventDelegate proc) = 0;
virtual bool RemoveListener(IEventData::id_t id, EventDelegate proc) = 0;
virtual void QueueEvent(IEventDataPtr ev) = 0;
virtual void ProcessEvents() = 0;
};
#define DECLARE_EVENT(type) \
static IEventData::id_t ID(){ \
return reinterpret_cast<IEventData::id_t>(&ID); \
} \
IEventData::id_t GetID() override { \
return ID(); \
}\
class EventManager : public IEventManager {
public:
typedef std::list<EventDelegate> EventDelegateList;
~EventManager(){
}
//! Adds a listener to the event. The listener should invalidate itself when it needs to be removed.
virtual bool AddListener(IEventData::id_t id, EventDelegate proc) override;
//! Removes the specified delegate from the list
virtual bool RemoveListener(IEventData::id_t id, EventDelegate proc) override;
//! Queues an event to be processed during the next update
virtual void QueueEvent(IEventDataPtr ev) override;
//! Processes all events
virtual void ProcessEvents() override;
private:
std::list<std::shared_ptr<IEventData>> mEventQueue;
std::map<IEventData::id_t, EventDelegateList> mEventListeners;
};
//! Helper class that automatically handles removal of individual event listeners registered using OnEvent() member function upon destruction of an object derived from this class.
class EventListener {
public:
//! Template function that also converts the event into the right data type before calling the event listener.
template<class T>
bool OnEvent(std::function<void(std::shared_ptr<T>)> proc){
return OnEvent(T::ID(), [&, proc](IEventDataPtr data){
auto ev = std::dynamic_pointer_cast<T>(data);
if(ev) proc(ev);
});
}
protected:
typedef std::pair<IEventData::id_t, EventDelegate> _EvPair;
EventListener(std::weak_ptr<IEventManager> mgr):_els_mEventManager(mgr){
}
virtual ~EventListener(){
if(_els_mEventManager.expired()) return;
auto em = _els_mEventManager.lock();
for(auto i : _els_mLocalEvents){
em->RemoveListener(i.first, i.second);
}
}
bool OnEvent(IEventData::id_t id, EventDelegate proc){
if(_els_mEventManager.expired()) return false;
auto em = _els_mEventManager.lock();
if(em->AddListener(id, proc)){
_els_mLocalEvents.push_back(_EvPair(id, proc));
}
}
private:
std::weak_ptr<IEventManager> _els_mEventManager;
std::vector<_EvPair> _els_mLocalEvents;
//std::vector<_DynEvPair> mDynamicLocalEvents;
};
And the Cpp file:
#include "Events.hpp"
using namespace std;
bool EventManager::AddListener(IEventData::id_t id, EventDelegate proc){
auto i = mEventListeners.find(id);
if(i == mEventListeners.end()){
mEventListeners[id] = list<EventDelegate>();
}
auto &list = mEventListeners[id];
for(auto i = list.begin(); i != list.end(); i++){
EventDelegate &func = *i;
if(func.target<EventDelegate>() == proc.target<EventDelegate>())
return false;
}
list.push_back(proc);
}
bool EventManager::RemoveListener(IEventData::id_t id, EventDelegate proc){
auto j = mEventListeners.find(id);
if(j == mEventListeners.end()) return false;
auto &list = j->second;
for(auto i = list.begin(); i != list.end(); ++i){
EventDelegate &func = *i;
if(func.target<EventDelegate>() == proc.target<EventDelegate>()) {
list.erase(i);
return true;
}
}
return false;
}
void EventManager::QueueEvent(IEventDataPtr ev) {
mEventQueue.push_back(ev);
}
void EventManager::ProcessEvents(){
size_t count = mEventQueue.size();
for(auto it = mEventQueue.begin(); it != mEventQueue.end(); ++it){
printf("Processing event..\n");
if(!count) break;
auto &i = *it;
auto listeners = mEventListeners.find(i->GetID());
if(listeners != mEventListeners.end()){
// Call listeners
for(auto l : listeners->second){
l(i);
}
}
// remove event
it = mEventQueue.erase(it);
count--;
}
}
I use an EventListener class for the sake of convenience as base class for any class that would like to listen to events. If you derive your listening class from this class and supply it with your event manager, you can use the very convenient function OnEvent(..) to register your events. And the base class will automatically unsubscribe your derived class from all events when it is destroyed. This is very convenient since forgetting to remove a delegate from event manager when your class is destroyed will almost certainly cause your program to crash.
A neat way to get a unique type id for an event by simply declaring a static function in the class and then casting it's address into an int. Since every class will have this method on different addresses, it can be used for unique identification of class events. You can also cast typename() to an int to get a unique id if you want. There are different ways to do this.
So here is an example on how to use this:
#include <functional>
#include <memory>
#include <stdio.h>
#include <list>
#include <map>
#include "Events.hpp"
#include "Events.cpp"
using namespace std;
class DisplayTextEvent : public IEventData {
public:
DECLARE_EVENT(DisplayTextEvent);
DisplayTextEvent(const string &text){
mStr = text;
}
~DisplayTextEvent(){
printf("Deleted event data\n");
}
const string &GetText(){
return mStr;
}
private:
string mStr;
};
class Emitter {
public:
Emitter(shared_ptr<IEventManager> em){
mEmgr = em;
}
void EmitEvent(){
mEmgr->QueueEvent(shared_ptr<IEventData>(
new DisplayTextEvent("Hello World!")));
}
private:
shared_ptr<IEventManager> mEmgr;
};
class Receiver : public EventListener{
public:
Receiver(shared_ptr<IEventManager> em) : EventListener(em){
mEmgr = em;
OnEvent<DisplayTextEvent>([&](shared_ptr<DisplayTextEvent> data){
printf("It's working: %s\n", data->GetText().c_str());
});
}
~Receiver(){
mEmgr->RemoveListener(DisplayTextEvent::ID(), std::bind(&Receiver::OnExampleEvent, this, placeholders::_1));
}
void OnExampleEvent(IEventDataPtr &data){
auto ev = dynamic_pointer_cast<DisplayTextEvent>(data);
if(!ev) return;
printf("Received event: %s\n", ev->GetText().c_str());
}
private:
shared_ptr<IEventManager> mEmgr;
};
int main(){
auto emgr = shared_ptr<IEventManager>(new EventManager());
Emitter emit(emgr);
{
Receiver receive(emgr);
emit.EmitEvent();
emgr->ProcessEvents();
}
emit.EmitEvent();
emgr->ProcessEvents();
emgr = 0;
return 0;
}
This probably does not only apply to game classes but to classes in the general sense. the MVC (model-view-controller) pattern together with your suggested message pump is all you need.
"Enemy" and "Player" will probably fit into the Model part of MVC, it does not matter much, but the rule of thumb is have all models and views interact via the controller. So, you would want to keep references (better than pointers) to (almost) all other class instances from this 'controller' class, let's name it ControlDispatcher. Add a message pump to it (varies depending on what platform you are coding for), instantiate it firstly (before any other classes and have the other objects part of it) or lastly (and have the other objects stored as references in ControlDispatcher).
Of course, the ControlDispatcher class will probably have to be split down further into more specialized controllers just to keep the code per file at around 700-800 lines (this is the limit for me at least) and it may even have more threads pumping and processing messages depending on your needs.
Cheers
Be careful with "a message style system", it probably depends on implementation, but usually you would loose static type checking, and can then make some errors very difficult to debug. Note that calling object's methods it is already a message-like system.
Probably you are simply missing some levels of abstraction, for example for navigation a Player could use a Navigator instead of knowing all about the Map itself. You also say that this has usually descended into setting lots of pointers, what are those pointers? Probably, you are giving them to a wrong abstraction?.. Making objects know about others directly, without going through interfaces and intermediates, is a straight way to getting a tightly coupled design.
Messaging is definitely a great way to go, but messaging systems can have a lot of differences. If you want to keep your classes nice and clean, write them to be ignorant of a messaging system and instead have them take dependencies on something simple like a 'ILocationService' which can then be implemented to publish/request information from things like the Map class. While you'll end up with more classes, they'll be small, simple and encourage clean design.
Messaging is about more than just decoupling, it also lets you move towards a more asynchronous, concurrent and reactive architecture. Patterns of Enterprise Integration by Gregor Hophe is a great book that talks about good messaging patterns. Erlang OTP or Scala's implementation of the Actor Pattern have provided me with a lot of guidance.
#kellogs suggestion of MVC is valid, and used in a few games, though its much more common in web apps and frameworks. It might be overkill and too much for this.
I would rethink your design, why does the Player need to talk to Enemies? Couldn't they both inherit from an Actor class? Why do Actors need to talk to the Map?
As I read what I wrote it starts to fit into an MVC framework...I have obviously done too much rails work lately. However, I would be willing to bet, they only need to know things like, they are colliding with another Actor, and they have a position, which should be relative to the Map anyhow.
Here is an implementation of Asteroids that I worked on. You're game may be, and probably is, complex.