0

代码取自一篇 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
    };
};

非常感谢对正在发生的事情的任何解释或提示......

4

1 回答 1

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);
于 2012-12-07T18:12:15.173 回答