C++ 狀態機接口


 

最近的狀態極差,甚至代碼也寫不下去了。給自己手臂上的兩刀沒有任何的作用,看來早已經是麻痹了。

一直想弄一個勉強能用的狀態機,用於在各種涉及到狀態轉換的時候用到,然而腦子並不是太清醒。

先放在這里一個接口,以后會用到的。

 

狀態機主要由3部分組成: 狀態,輸入,轉換。可以在Input中實現狀態機的轉換藍圖;“狀態”可以用枚舉來表示。每當存在一個新的狀態,那么就需要繼承一次下面的接口。

其中的StateStack可以用來做下推自動機,這樣可以在狀態更新之后,用來還原之前的狀態。

如果一個對象擁有多個狀態,那么就要用到並發狀態機。這個原理大概是,這個對象的成員中存在兩個StateBase的子類對象。兩者既不相互干擾還能做到同時更新。

UpdateBegin 和 UpdateEnd用來定義狀態進出時的行為。但我總覺得,將它放在Input函數中而不是Update函數中更為合適。

 

C++14的代碼,VS2017。

 1 #pragma once
 2 #include <chrono>
 3 #include <stack>
 4 
 5 #define GetTimeNowMicroSec \
 6     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()
 7 
 8 template<typename TState, typename TIn, typename TTarget>
 9 class StateBase
10 {
11 private:
12     StateBase();
13 
14 public:
15     typename std::stack<StateBase<TState, TIn, TTarget>*> StateStack;    //Pushdown Automation
16 
17     StateBase(TState st);
18     virtual ~StateBase();
19 
20 public:
21     const TState& GetStateType() const;
22 
23 public:
24     virtual void Input(TTarget& tag, TIn& input) = 0;
25     virtual void Updating(TTarget& tag) = 0;
26 
27     virtual void UpdateBegin(TTarget& tag);
28     virtual void UpdateEnd(TTarget& tag);
29     virtual void Update(TTarget& tag);
30     
31     template<class ST,
32         typename  std::enable_if <
33         std::is_base_of<StateBase, ST>::value, ST
34     > ::type * = nullptr >>
35     virtual bool operator==(const ST& left, const ST& right) const
36     {
37         return left._st == right._st;
38     }
39 
40 private:
41     TState _st;
42     time_t _time;    //micro
43 };
44 
45 template<typename TState, typename TIn, typename TTarget>
46 inline StateBase<TState, TIn, TTarget>::~StateBase()
47 {
48     _time = 0;
49 }
50 
51 template<typename TState, typename TIn, typename TTarget>
52 inline StateBase<TState, TIn, TTarget>::StateBase(TState st):
53     _st(st)
54 {
55 }
56 
57 template<typename TState, typename TIn, typename TTarget>
58 inline const TState & StateBase<TState, TIn, TTarget>::GetStateType() const
59 {
60     return _st;
61 }
62 
63 template<typename TState, typename TIn, typename TTarget>
64 inline void StateBase<TState, TIn, TTarget>::UpdateBegin(TTarget & tag)
65 {
66     _time = GetTimeNowMicroSec;
67 }
68 
69 template<typename TState, typename TIn, typename TTarget>
70 inline void StateBase<TState, TIn, TTarget>::UpdateEnd(TTarget & tag)
71 {
72     _time = GetTimeNowMicroSec - _time;
73 }
74 
75 template<typename TState, typename TIn, typename TTarget>
76 inline void StateBase<TState, TIn, TTarget>::Update(TTarget & tag)
77 {
78     UpdateBegin(tag);
79     Updating(tag);
80     UpdateEnd(tag);
81 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM