Line data Source code
1 : /* Copyright (C) 2015 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef FSM_H
19 : #define FSM_H
20 :
21 : // INCLUDES
22 : #include <vector>
23 : #include <set>
24 : #include <map>
25 :
26 : // DECLARATIONS
27 : #define FSM_INVALID_STATE ( unsigned int )( ~0 )
28 :
29 : class CFsmEvent;
30 : class CFsmTransition;
31 : class CFsm;
32 :
33 : typedef bool ( *CONDITION ) ( void* pContext );
34 : typedef bool ( *ACTION ) ( void* pContext, const CFsmEvent* pEvent );
35 :
36 : typedef struct
37 : {
38 : void* pFunction;
39 : void* pContext;
40 :
41 : } CallbackFunction;
42 :
43 : typedef std::set< unsigned int > StateSet;
44 : typedef std::map< unsigned int, CFsmEvent* > EventMap;
45 : typedef std::vector< CFsmTransition* > TransitionList;
46 : typedef std::vector< CallbackFunction > CallbackList;
47 :
48 : /**
49 : * Represents a signal in the state machine that a change has occurred.
50 : * The CFsmEvent objects are under the control of CFsm so
51 : * they are created and deleted via CFsm.
52 : */
53 : class CFsmEvent
54 : {
55 : NONCOPYABLE(CFsmEvent);
56 : public:
57 :
58 : CFsmEvent( unsigned int type );
59 : ~CFsmEvent( void );
60 :
61 0 : unsigned int GetType ( void ) const { return m_Type; }
62 0 : void* GetParamRef ( void ) { return m_Param; }
63 : void SetParamRef ( void* pParam );
64 :
65 : private:
66 : unsigned int m_Type; // Event type
67 : void* m_Param; // Event paramater
68 : };
69 :
70 :
71 : /**
72 : * An association of event, condition, action and next state.
73 : */
74 : class CFsmTransition
75 : {
76 : NONCOPYABLE(CFsmTransition);
77 : public:
78 :
79 : CFsmTransition( unsigned int state );
80 : ~CFsmTransition( void );
81 :
82 : void RegisterAction (
83 : void* pAction,
84 : void* pContext );
85 : void RegisterCondition (
86 : void* pCondition,
87 : void* pContext );
88 : void SetEvent ( CFsmEvent* pEvent );
89 0 : CFsmEvent* GetEvent ( void ) const { return m_Event; }
90 : void SetNextState ( unsigned int nextState );
91 0 : unsigned int GetNextState ( void ) const { return m_NextState; }
92 0 : unsigned int GetCurrState ( void ) const { return m_CurrState; }
93 : const CallbackList& GetActions ( void ) const { return m_Actions; }
94 : const CallbackList& GetConditions ( void ) const { return m_Conditions; }
95 : bool ApplyConditions ( void ) const;
96 : bool RunActions ( void ) const;
97 :
98 : private:
99 : unsigned int m_CurrState; // Current state
100 : unsigned int m_NextState; // Next state
101 : CFsmEvent* m_Event; // Transition event
102 : CallbackList m_Actions; // List of actions for transition
103 : CallbackList m_Conditions; // List of conditions for transition
104 : };
105 :
106 : /**
107 : * Manages states, events, actions and transitions
108 : * between states. It provides an interface for advertising
109 : * events and track the current state. The implementation is
110 : * a Mealy state machine, so the system respond to events
111 : * and execute some action.
112 : *
113 : * A Mealy state machine has behaviour associated with state
114 : * transitions; Mealy machines are event driven where an
115 : * event triggers a state transition
116 : */
117 : class CFsm
118 : {
119 : NONCOPYABLE(CFsm);
120 : public:
121 :
122 : CFsm( void );
123 : virtual ~CFsm( void );
124 :
125 : /**
126 : * Constructs the state machine. This method must be overriden so that
127 : * connections are constructed for the particular state machine implemented
128 : */
129 : virtual void Setup( void );
130 :
131 : /**
132 : * Clear event, action and condition lists and reset state machine
133 : */
134 : void Shutdown( void );
135 :
136 : void AddState ( unsigned int state );
137 : CFsmEvent* AddEvent ( unsigned int eventType );
138 : CFsmTransition* AddTransition (
139 : unsigned int state,
140 : unsigned int eventType,
141 : unsigned int nextState );
142 : CFsmTransition* AddTransition (
143 : unsigned int state,
144 : unsigned int eventType,
145 : unsigned int nextState,
146 : void* pAction,
147 : void* pContext );
148 : CFsmTransition* GetTransition (
149 : unsigned int state,
150 : unsigned int eventType ) const;
151 : CFsmTransition* GetEventTransition ( unsigned int eventType ) const;
152 : void SetFirstState ( unsigned int firstState );
153 : void SetCurrState ( unsigned int state );
154 0 : unsigned int GetCurrState ( void ) const { return m_CurrState; }
155 0 : void SetNextState ( unsigned int nextState ) { m_NextState = nextState; }
156 0 : unsigned int GetNextState ( void ) const { return m_NextState; }
157 : const StateSet& GetStates ( void ) const { return m_States; }
158 : const EventMap& GetEvents ( void ) const { return m_Events; }
159 : const TransitionList& GetTransitions ( void ) const { return m_Transitions; }
160 : bool Update ( unsigned int eventType, void* pEventData );
161 : bool IsValidState ( unsigned int state ) const;
162 : bool IsValidEvent ( unsigned int eventType ) const;
163 : virtual bool IsDone ( void ) const;
164 :
165 : private:
166 : bool IsFirstTime ( void ) const;
167 :
168 : bool m_Done; // FSM work is done
169 : unsigned int m_FirstState; // Initial state
170 : unsigned int m_CurrState; // Current state
171 : unsigned int m_NextState; // Next state
172 : StateSet m_States; // List of states
173 : EventMap m_Events; // List of events
174 : TransitionList m_Transitions; // State transitions
175 : };
176 :
177 : #endif // FSM_H
178 :
|