Finite State Machine generic programming of Finite State Machine
Finite State Machine: I don't want to talk about advanced theories. Is programming possible if the theory is too high? I think it is easy to understand that an object has multiple States (note that the "object" and "state" here are both generalized and abstract) the trigger of enables the transition between States, which can be used to define the operations (OP) attached during state switching ). The Finite State Machine (FSM) We want to implement is the code for maintaining and managing this mechanism. Because real-time graphics programs with high performance and efficiency requirements (such as 3D online games) cannot use commercial program frameworks such as MFC, FSM can be the core part of the entire real-time program, in the end, game programs are nothing more than switching between different States, such as the logon interface, the role interface, the main game interface, the single-host game, and a dedicated copyright page. some games use the state mode in the design mode as the management and scheduling core of the game, but as a large game, using a design mode is obviously difficult to meet the complex requirements of the application core, this requires a mature mechanism to complete this task. Today we will discuss FSM. the importance and superiority of generic programming: Generic programming, templates, and design patterns are well known. I just want to say that from a macro perspective, their purpose and function is to use C ++ to express some ideas, and these ideas are still actual code! This can bring many benefits, such as high code reuse rate, flexibility and scalability, interface uniformity, and so on. the popular FSM-related materials are the second article in chapter 3 of the first volume of game programming gems, which is also published on the Internet. the author discusses and implements a simple FSM implementation. he uses the state design mode and uses an fsmclass class to manage many instances of the fsmstate class. If you are interested, you can refer to it, now we want to discuss a FSM implementation that is closer to the actual product code. We do not need to introduce too much theory and look at the Code directly. code: // template class, passed in status type and event type template <typename state_type, typename event_type> class fsmachine // general basic Finite State Machine class {public: typedef fsmachine machine_type; fsmachine () {} // constructor virtual ~ Fsmachine () {}// void addstate (const state_type & State) of the virtual destructor // Add status {typename state_map: iterator it = m_statemap.find (State ); // STL iteration sub-If (IT = m_statemap.end () // If the status ing table does not exist in this status {m_statemap.insert (typename state_map: value_type (State, state_e ())); // insert return ;}} void setstate (const state_type & DEST) // set the current state {const typename state_map: const_iterator it = m_statemap.find (DEST); If (IT = m_sta Temap. end () // if this status cannot be found {// return for error handling;} m_currstate = DEST; // set to current status} const state_type & currentstate () const {return m_currstate; // returns the current state} size_t numstates () const {return m_statemap.size (); // returns the number of State ing tables} void clearstates () // clear the status ing table {m_currstate = state_type (); // call the default constructor m_statemap.clear (); // clear} void addtransition (const state_type & SRC, const event_type & EVT, const state_type & DEST) // Add SRC Status event status transition record {If (src = DEST) // The Source status is the same as the target status, meaningless {// return for error handling;} typename state_map :: iterator it = m_statemap.find (SRC); If (IT = m_statemap.end () // The Source status cannot be found {// return for error handling;} {const typename state_map :: const_iterator itdest = m_statemap.find (DEST); If (itdest = m_statemap.end () // The target status is not in the status ing table and is invalid {// return for error handling ;}} event_state_map & evt2state = it-> second. transitions; evt2state. insert (ty Pename event_state_map: value_type (EVT, DEST); // Add transition record} size_t numtransitions (const state_type & SRC) const // return the number of transition records in a certain state {const typename state_map: const_iterator it = m_statemap.find (SRC); Return (IT = m_statemap.end ())? 0: it-> second. transitions. size ();} template <typename enter_state_op_t, typename region> void processevent (const event_type & EVT, Region & enterop, Region & exitop) // state transition function {const typename state_map:: const_iterator it = m_statemap.find (m_currstate); If (IT = m_statemap.end () // The Source status does not exist {// return for error handling ;} const event_state_map & evt2state = it-> second. transitions; const typename event_state_map: const_iterator itfindtransition = evt2state. find (EVT); If (itfindtransition = evt2state. end () // trigger event does not exist {// return for error handling;} exitop (* This, m_currstate); // call the function that exits the old state m_currstate = itfindtransition-> second; // The new state is the current State enterop (* This, m_currstate); // function call that enters the new State} PRIVATE: // for each State, corresponding to such an event state transition ing table typedef STD: Map <event_type, state_type> event_state_map; // This struct is used to save the event state transition ing table for each State, and user-defined data struct state_e {event_state_map transitions; void * userdata ;}; // defines the FSM status ing table typedef STD: Map <state_type, state_e> state_map; // status ing table member variable state_map m_statemap of the fsmachine class; // The current state_type m_currstate ;};