LCOV - code coverage report
Current view: top level - source/network - FSM.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 0 17 0.0 %
Date: 2023-01-19 00:18:29 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /* Copyright (C) 2023 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             : #include <limits>
      22             : #include <map>
      23             : #include <set>
      24             : #include <vector>
      25             : 
      26             : 
      27             : constexpr unsigned int FSM_INVALID_STATE{std::numeric_limits<unsigned int>::max()};
      28             : 
      29             : class CFsmEvent;
      30             : class CFsmTransition;
      31             : class CFsm;
      32             : 
      33             : using Condition = bool(void* pContext);
      34             : using Action = bool(void* pContext, const CFsmEvent* pEvent);
      35             : 
      36             : struct CallbackFunction
      37             : {
      38             :     void* pFunction;
      39             :     void* pContext;
      40             : };
      41             : 
      42             : using StateSet = std::set<unsigned int>;
      43             : using EventMap = std::map<unsigned int, CFsmEvent*>;
      44             : using TransitionList = std::vector<CFsmTransition*>;
      45             : using CallbackList = std::vector<CallbackFunction>;
      46             : 
      47             : /**
      48             :  * Represents a signal in the state machine that a change has occurred.
      49             :  * The CFsmEvent objects are under the control of CFsm so
      50             :  * they are created and deleted via CFsm.
      51             :  */
      52             : class CFsmEvent
      53             : {
      54             :     NONCOPYABLE(CFsmEvent);
      55             : public:
      56             : 
      57             :     CFsmEvent(unsigned int type);
      58             :     ~CFsmEvent();
      59             : 
      60           0 :     unsigned int GetType() const
      61             :     {
      62           0 :         return m_Type;
      63             :     }
      64             : 
      65           0 :     void* GetParamRef()
      66             :     {
      67           0 :         return m_Param;
      68             :     }
      69             : 
      70             :     void SetParamRef(void* pParam);
      71             : 
      72             : private:
      73             :     unsigned int m_Type; // Event type
      74             :     void* m_Param; // Event paramater
      75             : };
      76             : 
      77             : 
      78             : /**
      79             :  * An association of event, condition, action and next state.
      80             :  */
      81             : class CFsmTransition
      82             : {
      83             :     NONCOPYABLE(CFsmTransition);
      84             : public:
      85             : 
      86             :     CFsmTransition(unsigned int state);
      87             :     ~CFsmTransition();
      88             : 
      89             :     /**
      90             :      * Registers an action that will be executed when the transition occurs.
      91             :      * @param pAction the function which will be executed.
      92             :      * @param pContext data passed to the function.
      93             :      */
      94             :     void RegisterAction(void* pAction, void* pContext);
      95             : 
      96             :     /**
      97             :      * Registers a condition which will be evaluated when the transition occurs.
      98             :      * @param pCondition the predicate which will be executed.
      99             :      * @param pContext data passed to the predicate.
     100             :      */
     101             :     void RegisterCondition(void* pCondition, void* pContext);
     102             : 
     103             :     /**
     104             :      * Set event for which transition will occur.
     105             :      */
     106             :     void SetEvent(CFsmEvent* pEvent);
     107           0 :     CFsmEvent* GetEvent() const
     108             :     {
     109           0 :         return m_Event;
     110             :     }
     111             : 
     112             :     /**
     113             :      * Set next state the transition will switch the system to.
     114             :      */
     115             :     void SetNextState(unsigned int nextState);
     116           0 :     unsigned int GetNextState() const
     117             :     {
     118           0 :         return m_NextState;
     119             :     }
     120             : 
     121           0 :     unsigned int GetCurrState() const
     122             :     {
     123           0 :         return m_CurrState;
     124             :     }
     125             : 
     126             :     const CallbackList& GetActions() const
     127             :     {
     128             :         return m_Actions;
     129             :     }
     130             : 
     131             :     const CallbackList& GetConditions() const
     132             :     {
     133             :         return m_Conditions;
     134             :     }
     135             : 
     136             :     /**
     137             :      * Evaluates conditions for the transition.
     138             :      * @return whether all the conditions are true.
     139             :      */
     140             :     bool ApplyConditions() const;
     141             : 
     142             :     /**
     143             :      * Executes actions for the transition.
     144             :      * @note If there are no actions, assume true.
     145             :      * @return whether all the actions returned true.
     146             :      */
     147             :     bool RunActions() const;
     148             : 
     149             : private:
     150             :     unsigned int m_CurrState;
     151             :     unsigned int m_NextState;
     152             :     CFsmEvent* m_Event;
     153             :     CallbackList m_Actions;
     154             :     CallbackList m_Conditions;
     155             : };
     156             : 
     157             : /**
     158             :  * Manages states, events, actions and transitions
     159             :  * between states. It provides an interface for advertising
     160             :  * events and track the current state. The implementation is
     161             :  * a Mealy state machine, so the system respond to events
     162             :  * and execute some action.
     163             :  *
     164             :  * A Mealy state machine has behaviour associated with state
     165             :  * transitions; Mealy machines are event driven where an
     166             :  * event triggers a state transition.
     167             :  */
     168             : class CFsm
     169             : {
     170             :     NONCOPYABLE(CFsm);
     171             : public:
     172             : 
     173             :     CFsm();
     174             :     virtual ~CFsm();
     175             : 
     176             :     /**
     177             :      * Constructs the state machine. This method must be overriden so that
     178             :      * connections are constructed for the particular state machine implemented.
     179             :      */
     180             :     virtual void Setup();
     181             : 
     182             :     /**
     183             :      * Clear event, action and condition lists and reset state machine.
     184             :      */
     185             :     void Shutdown();
     186             : 
     187             :     /**
     188             :      * Adds the specified state to the internal list of states.
     189             :      * @note If a state with the specified ID exists, the state is not added.
     190             :      */
     191             :     void AddState(unsigned int state);
     192             : 
     193             :     /**
     194             :      * Adds the specified event to the internal list of events.
     195             :      * @note If an eveny with the specified ID exists, the event is not added.
     196             :      * @return a pointer to the new event.
     197             :      */
     198             :     CFsmEvent* AddEvent(unsigned int eventType);
     199             : 
     200             :     /**
     201             :      * Adds a new transistion to the state machine.
     202             :      * @return a pointer to the new transition.
     203             :      */
     204             :     CFsmTransition* AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState );
     205             : 
     206             :     /**
     207             :      * Adds a new transition to the state machine.
     208             :      * @return a pointer to the new transition.
     209             :      */
     210             :     CFsmTransition* AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState,
     211             :          void* pAction, void* pContext);
     212             : 
     213             :     /**
     214             :      * Looks up the transition given the state, event and next state to transition to.
     215             :      */
     216             :     CFsmTransition* GetTransition(unsigned int state, unsigned int eventType) const;
     217             :     CFsmTransition* GetEventTransition (unsigned int eventType) const;
     218             : 
     219             :     /**
     220             :      * Sets the initial state for FSM.
     221             :      */
     222             :     void SetFirstState(unsigned int firstState);
     223             : 
     224             :     /**
     225             :      * Sets the current state and update the last state to the current state.
     226             :      */
     227             :     void SetCurrState(unsigned int state);
     228           0 :     unsigned int GetCurrState() const
     229             :     {
     230           0 :         return m_CurrState;
     231             :     }
     232             : 
     233           0 :     void SetNextState(unsigned int nextState)
     234             :     {
     235           0 :         m_NextState = nextState;
     236           0 :     }
     237             : 
     238           0 :     unsigned int GetNextState() const
     239             :     {
     240           0 :         return m_NextState;
     241             :     }
     242             : 
     243             :     const StateSet& GetStates() const
     244             :     {
     245             :         return m_States;
     246             :     }
     247             : 
     248             :     const EventMap& GetEvents() const
     249             :     {
     250             :         return m_Events;
     251             :     }
     252             : 
     253             :     const TransitionList& GetTransitions() const
     254             :     {
     255             :         return m_Transitions;
     256             :     }
     257             : 
     258             :     /**
     259             :      * Updates the FSM and retrieves next state.
     260             :      * @return whether the state was changed.
     261             :      */
     262             :     bool Update(unsigned int eventType, void* pEventData);
     263             : 
     264             :     /**
     265             :      * Verifies whether the specified state is managed by the FSM.
     266             :      */
     267             :     bool IsValidState(unsigned int state) const;
     268             : 
     269             :     /**
     270             :      * Verifies whether the specified event is managed by the FSM.
     271             :      */
     272             :     bool IsValidEvent(unsigned int eventType) const;
     273             : 
     274             :     /**
     275             :      * Tests whether the state machine has finished its work.
     276             :      * @note This is state machine specific.
     277             :      */
     278             :     virtual bool IsDone() const;
     279             : 
     280             : private:
     281             :     /**
     282             :      * Verifies whether state machine has already been updated.
     283             :      */
     284             :     bool IsFirstTime() const;
     285             : 
     286             :     bool m_Done;
     287             :     unsigned int m_FirstState;
     288             :     unsigned int m_CurrState;
     289             :     unsigned int m_NextState;
     290             :     StateSet m_States;
     291             :     EventMap m_Events;
     292             :     TransitionList m_Transitions;
     293             : };
     294             : 
     295             : #endif // FSM_H

Generated by: LCOV version 1.13