|
// Class HBActor comprises a base class for an Actor Programming Model object.
// This class contains support code to manage a thread for this object and perform
// message processing, termination and other related 'Actor' tasks.
//
// To be used, a derived class must be defined which implements the Process() method.
// This method must detect a termination message and shutdown the actor; otherwise
// act on the messages sent to the object through the message queue.
//
// Messages are defined in class BaseMessage or a class derived from it.
#include <concurrent_queue.h>
#pragma warning(disable: 4251) // class '...' needs to have dll-interface...
#ifdef HBACTOR_EXPORTS
#define HBACTOR_API __declspec(dllexport)
#else
#define HBACTOR_API //__declspec(dllimport)
#endif
/// Base class for message processing. Derive your message object from this class.
class HBACTOR_API BaseMessage
{
public:
/// Constructor/destructor for the class
BaseMessage(){}
virtual ~BaseMessage() = 0 {}
private:
/// Disabled APIs for this class
BaseMessage(const BaseMessage& rhs); // no implementation
BaseMessage& operator= (const BaseMessage & rhs); // no implementation
};
/// Base class for the Actor. Derive your actor object from this class.
class HBACTOR_API HBActor
{
public:
/// Constructor/destructor for the class
HBActor();
virtual ~HBActor();
/// Definition of actor states
typedef enum {AS_CREATED, AS_RUNNING, AS_STOPPED} ActorState_t;
private:
/// Disabled APIs for this class
HBActor(const HBActor& rhs); // no implementation
HBActor& operator= (const HBActor & rhs); // no implementation
public:
/// API to send a message to the Actor; This is normally used by calling code.
virtual void Send(BaseMessage* message);
/// Start the actor; This is normally called by the actor creator after initial
/// state is defined.
virtual void Start();
/// Wait until the actor has completed processing.
virtual bool Join();
/// Get current actor state
HBActor::ActorState_t GetState() const
{ return m_state; }
protected:
/// Get Thread Handle
HANDLE GetThreadHandle() const
{ return m_hThread; }
/// Get message count indicator
unsigned int GetMessageCount() const
{ return m_messages.unsafe_size(); }
protected:
/// Method implemented in derived class to perform message processing.
virtual void Process(BaseMessage* /* msg */) = 0;
/// Terminate processing on the Actor. [The object is not destructed here.]
virtual void Exit();
private:
/// Static method to run each thread
static unsigned int __stdcall ThreadProc(void* pHandler);
private:
enum {StopperIndex, ProcessIndex}; // indexes for semaphore handles
volatile ActorState_t m_state; // current object state
Concurrency::concurrent_queue<BaseMessage*> m_messages; // message queue
HANDLE m_handles[2]; // semaphore handles
HANDLE m_hThread; // Thread handle
};
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I have been writing software since 1969 and having fun doing it. I have The Knack. I have cooked bacon naked. I have worked in academia and the energy business for a little over 30 years. They have retired me now but I still enjoy writing code and trying to keep up to date. I have programmed in close to 100 languages. My current favorite is C++. My current platforms are Windows and linux. My favorite color is blue. I have never owned an umbrella. My sneezes are a registered avalanche hazard with the Colorado Ski Patrol. Women have swooned at my ability to recite digits of Pi.