我有一個狀態機,如下所述。狀態機執行
我們可以從兩種起始狀態中的一種開始,但我們必須擊中所有4個握手狀態。從那裏,我們可以傳輸數據的有效載荷或接收數據的有效載荷。然後,我們回到我們原來的起始狀態。
握手:
- > StartingState1 - > FinalState1 - > StartingState2 - > FinalState2
- > StartingState2 - > FinalState2 - > StartingState1 - > FinalState1
有效負載轉移:
- > SendPayload - > SendEnd - > StartingState?
- > ReceivePayload - > ReceiveEnd - > StartingState?
下面的代碼代表我目前的架構。不幸的是,在每個過程結束時,我沒有足夠的信息從各州內知道下一個狀態是什麼,我應該打。
根據我的要求,有沒有人有任何建議來改進這個架構?
感謝, PaulH
class MyMachine;
class Payload;
class IState
{
MyMachine* context_;
IState(MyMachine* context) : context_(context) {};
virtual void Consume(byte data);
void ChangeState(IState* state)
{
context_->SetState(state);
}
}
class FinalState1 : IState
{
void Consume(byte data)
{
// Either go to StartingState1, SendPayload, or ReceivePayload.
// How can I tell from within the context of this state where I
// should go?
}
}
class StartingState1 : IState
{
void Consume(byte data)
{
if (/*some condition*/)
{
ChangeState(new FinalState1(context_));
}
}
}
class MyMachine
{
IState* state_;
Payload* payload_;
void Start1(Mode mode)
{
state_ = new StartingState1(this);
}
void Start2(Mode mode)
{
state_ = new StartingState2(this);
}
void Consume(byte data)
{
state_->Consume(data);
}
void SetPayload(const Payload* payload)
{
payload_ = payload;
}
const Payload* GetPayload()
{
return payload_;
}
void SetState(State* state)
{
delete state_;
state_ = state;
}
}
// get a byte of data from some source
byte GetData();
void main()
{
MyMachine machine;
Payload payload;
machine.SetPayload(payload);
machine.Start1(Mode::SendPayload);
// could also call:
// machine.Start1(Mode::ReceivePayload);
// machine.Start2(Mode::SendPayload);
// machine.Start2(Mode::ReceivePayload);
for(;;)
{
machine.Consume(GetData());
}
}
這聽起來像是一個純粹的FSM設計問題,而不是代碼問題。 – 2010-02-01 22:03:19
@Hamish - 你對改進的FSM設計有什麼建議嗎? – PaulH 2010-02-01 22:40:55
我建議你研究狀態機語言和編譯器。我的直覺表明,有些工具會根據狀態機描述生成框架或模板。 – 2010-02-01 23:06:22