该代码取自DDJ文章state machine design in c
class EventData
{
public:
virtual ~EventData() {};
};
struct StateStruct;
class CStateMachine : public CObject
{
DECLARE_DYNAMIC(CStateMachine)
public:
CStateMachine(int nMaxStates);
virtual ~CStateMachine() {};
unsigned char GetCurrentState() { return currentState;};
protected:
enum { EVENT_IGNORED = 0xFE, CANNOT_HAPPEN };
unsigned char currentState;
void ExternalEvent(unsigned char, EventData* = NULL);
void InternalEvent(unsigned char, EventData* = NULL);
virtual const StateStruct* GetStateMap() = 0;
private:
const int _maxStates;
bool _eventGenerated;
EventData* _pEventData;
void StateEngine(void);
};
typedef void (CStateMachine::*StateFunc)(EventData *);
struct StateStruct
{
StateFunc pStateFunc;
};
#define BEGIN_STATE_MAP \
public:\
const StateStruct* GetStateMap() {\
static const StateStruct StateMap[] = {
#define STATE_MAP_ENTRY(entry)\
{ reinterpret_cast<StateFunc>(entry) }, //IT COMPLAINS ABOUT THE CAST HERE...
#define END_STATE_MAP \
{ reinterpret_cast<StateFunc>(NULL) }\
}; \
return &StateMap[0]; }
#define BEGIN_TRANSITION_MAP \
static const unsigned char TRANSITIONS[] = {\
#define TRANSITION_MAP_ENTRY(entry)\
entry,
#define END_TRANSITION_MAP(data) \
0 };\
ExternalEvent(TRANSITIONS[currentState], data);}
实现如下,除了多重继承之外,还有DDJ文章......
// structure to hold event data passed into state machine
struct MotorData : public EventData
{
int speed;
};
class CMotor :
public CStateMachine,
public CSimulationObject //THIS IS NEW, NOT FROM THE ARTICLE IT CONTAINS A VIRTUAL FUNCTION void _step( double dt);
{
private:
double dSetpoint;
public:
CMotor(void): CStateMachine( ST_MAX_STATES), dSetpoint(0.0){};
// external events taken by this state machine
void Stop();
void SetSpeed(MotorData*);
private:
void _step( double dt);
// state machine state functions
void ST_Idle(MotorData*);
void ST_Stop(MotorData*);
void ST_Start(MotorData*);
void ST_ChangeSpeed(MotorData*);
// state map to define state function order
BEGIN_STATE_MAP
STATE_MAP_ENTRY( ST_Idle ) //ERRORS ON THESE LINES
STATE_MAP_ENTRY( ST_Stop ) //
STATE_MAP_ENTRY( ST_Start ) //
STATE_MAP_ENTRY( ST_ChangeSpeed ) //
END_STATE_MAP
// state enumeration order must match the order of state
// method entries in the state map
enum E_States {
ST_IDLE = 0,
ST_STOP,
ST_START,
ST_CHANGE_SPEED,
ST_MAX_STATES
};
};
非常感谢任何有关正在发生的事情的解释或暗示......
答案 0 :(得分:1)
我找到了各种答案。我不得不重写一些代码。定义。
class CStateMachine;
typedef void (CStateMachine::*StateFunc)(void *);
class CStateMachine : public CObject
{
DECLARE_DYNAMIC(CStateMachine)
public:
CStateMachine(int nMaxStates);
virtual ~CStateMachine() {};
unsigned char GetCurrentState() { return currentState;};
protected:
enum { EVENT_IGNORED = 0xFE, CANNOT_HAPPEN };
unsigned char currentState;
void ExternalEvent(unsigned char, EventData* = NULL);
void InternalEvent(unsigned char, EventData* = NULL);
virtual const StateFunc* GetStateMap() const = 0;
private:
const int _maxStates;
bool _eventGenerated;
EventData* _pEventData;
void StateEngine(void);
};
/*struct StateStruct
{
StateFunc pStateFunc;
};*/
#define BEGIN_STATE_MAP(TheClass, TheData) \
private:\
typedef TheClass ThisClass;\
typedef void (ThisClass::*ThisStateFunc)(void *);\
public:\
const StateFunc* GetStateMap() const {\
static const StateFunc StateMap[] = {
#define STATE_MAP_ENTRY(entry)\
{ static_cast<StateFunc>(static_cast<ThisStateFunc>((entry))) },
#define END_STATE_MAP \
{ static_cast<StateFunc>(NULL) }\
}; \
return &StateMap[0]; }
#define BEGIN_TRANSITION_MAP \
static const unsigned char TRANSITIONS[] = {\
#define TRANSITION_MAP_ENTRY(entry)\
entry,
#define END_TRANSITION_MAP(data) \
0 };\
ExternalEvent(TRANSITIONS[currentState], data);