2011-07-22 45 views
4

如果我做一個狀態機和要使用的界面是這樣的:當我在狀態1狀態機 - 結構來保持狀態,事件和pFuncs

AddState (state1, state2, Key_UP); 
AddEvent (Key_UP); 
AddEventFunction (Key_UP, &UP_Function); 
AddStateFunction (state1, &State1_In_Function, &State1_Out_Function); 
AddStateFunction (state2, &State2_In_Function, &State2_Out_Function); 

State1_In_Function (void) { printf ("In #1 \n"); } 
State1_Out_Function (void) { printf ("Out #1 \n"); } 
State2_In_Function (void) { printf ("In #2 \n"); } 
State2_Out_Function (void) { printf ("Out #2 \n"); } 
UP_Function   (void) { printf ("Goin UP \n"); } 

這樣和FSM接收KEY_UP程序打印:

Out #1 
Goin UP 
In #2 

的問題是如何以對國家和過渡信息存儲類內部而不程序員被要求改變的陣列大小。我想我可以使用二維數組,並像往常一樣將其設置爲狀態表,並使其更加便攜,我只需通過使用矢量類型來根據需要調整大小來處理事件和狀態的添加。矢量的問題是,並不是很多嵌入式設備都可以使用內存分配調用。我的第二個選擇是調用狀態機的構造函數,並將它傳遞給表所需的大小,但如果我添加任何新狀態或事件,我需要更改這些值以及...

那麼如何我應該存儲我的狀態,事件和函數指針嗎?!

+0

基於關我已經完成了,做一切我想它一個工作系統由馬蒂厄下面的例子!如果您有興趣查看完整程序[這裏](http://pastebin.com/RtPne3dC),只需執行一個「g ++ file.cpp」即可編譯而不會出現任何錯誤! – uMinded

回答

3

你可以簡單地將它們存儲在堆棧上,雖然這是一個有點難度:)

不過,這是一個有趣的解決方案,所以在這裏你去。根本原則是玩裝飾和可變性。代碼示例:

State state1, state2; // creates a state 
Event KEY_UP; 
Event KEY_DOWN; 

Transition t0(state1, KEY_UP, state2); 
Transition t1(state2, KEY_DOWN, state1); 

它是如何工作的?

而不是state1是一個「簡單」的對象時,它會稍微令人費解。喜歡的東西:

struct State; 

struct StateImpl { 
    StateImpl(char const* n): name(n) {} 
    char const* name; 
}; 

struct StateNode { 
    StateNode(Event e, State const& s, StateNode const* n): 
    event(e), state(s), next(n) {} 

    Event event; 
    State const& destination; 
    StateNode const* next; 
}; 

struct State { 
    State(char const* name): 
    me(0), impl(name) {} 

    StateNode const* me; 
    StateImpl impl; 
}; 

然後我們定義了一個Transition

struct Transition { 
    Transition(State& origin, Event e, State const& destination): 
    node(e, destination, origin.me) 
    { 
    origin.me = node; 
    } 
    StateNode node; 
}; 

通俗地說,我們正在建設一個單向鏈表,用頭坐在State。每次添加轉換時我們都會更新頭部。

當一個事件發生,需要直到遇到任一的情況下,並且從而適當調度,或達到空指針,指示事件不應被在此狀態下接收到步行此列表。

+0

嗯..這真的很有趣。通過這種做法,可以輕鬆地將輸入/輸出函數的指針添加到任何結構中! – uMinded

+0

我添加了一些調試,以遵循程序邏輯,你可以看到完整的程序[這裏](http://pastebin.com/uKxLAReT) – uMinded

+0

所以我走了你的代碼,並添加了一些例程走過桌子時我發現我不明白你的例子中的一些事情。 無論何時由於StateNode創建狀態,我都會得到遞歸包含。 state1.me-> destination.me-> destination.me - > ....等 過渡結構也沒有使我作爲origin.me通過StateNode而不是像我想象的是一個國家想要什麼。最重要的是,一般情況下,磨碎時的狀態會使每個狀態的默認狀態爲NULL。 您介意在您的代碼上進行一點點演練嗎? – uMinded

0

我建議你看看Boost.StateChart,如果需要,圍繞它建立一個薄層你想要的API。

這應該解決您的設計足夠的數據結構的需要。

+2

我不確定Boost.StateChart是否適用於嵌入式設備。 –

+0

爲什麼不呢? –

+1

OP明確提到了他所關心的平臺上缺少堆分配內存的可用性。這意味着他正在使用C++的子集,而不是完整的標準。我個人不太瞭解Boost.StateChart內在知識,以瞭解它是否會起作用......因此,評論。你知道他們嗎? –