状态机实现(State machine implementation)

编程入门 行业动态 更新时间:2024-10-08 13:29:29
状态机实现(State machine implementation)

我有一个状态机,如下所述。

我们可以从两种起始状态中的一种开始,但我们必须击中握手的所有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() ); } }

I have a state machine as described below.

We can start in one of two starting states, but we must hit all 4 states of the handshake. From there, we can either transfer a payload of data or receive a payload of data. Then, we return to our original starting state.

Handshake:

-> StartingState1 -> FinalState1 -> StartingState2 -> FinalState2

-> StartingState2 -> FinalState2 -> StartingState1 -> FinalState1

Payload Transfer:

-> SendPayload -> SendEnd -> StartingState?

-> ReceivePayload -> ReceiveEnd -> StartingState?

The code below represents my current architecture. Unfortunately, at the end of each process, I don't have enough information from within the states to know what the next state is I should hit.

Does anybody have any suggestions on how to improve this architecture based on my requirements?

Thanks, 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() ); } }

最满意答案

你所拥有的并不完全代表你的系统的可能状态,但是很容易对它进行转换,这样它就可以实现。 您需要额外的状态来表示处于状态1而未处于状态2和处于状态1,处于状态2(而状态2相同)状态之间的差异。 所以你需要:

S1 S2 F1 F2 S12 F12 S21 F21 SP SE RP RE

与过渡

S1 --> F1 F1 --> S12 S12 --> F12 F12 --> SP or F12 --> RP S2 --> F2 F2 --> S21 S21 --> F21 F21 --> SP or F21 --> RP SP --> SE RP --> RE SE --> S1 or SE --> S2 RE --> S1 or RE --> S2

关键的区别是引入了新的状态S12 , F12 , S21和F21 。 在实现方面,您几乎可以肯定只从S2推导出S12,从F2推导出F12,从S1推导S21和从F2推导出F21,并覆盖转换函数以进入正确状态。

(对所有状态进行首字母缩写的道歉)。

What you have doesn't represent the possible states of your system completely, but it's easy to transform it so that it does. You need additional states to represent the difference between being in state 1 and not having been in state 2, and being in state 1, whilst having been in state 2 (and the same for state 2). So you need:

S1 S2 F1 F2 S12 F12 S21 F21 SP SE RP RE

with transitions

S1 --> F1 F1 --> S12 S12 --> F12 F12 --> SP or F12 --> RP S2 --> F2 F2 --> S21 S21 --> F21 F21 --> SP or F21 --> RP SP --> SE RP --> RE SE --> S1 or SE --> S2 RE --> S1 or RE --> S2

The key difference is the introduction of new states S12, F12, S21 and F21. In terms of implementation you could almost certainly just derive S12 from S2, F12 from F2, S21 from S1 and F21 from F2 and override the transition function to go to the correct state.

(Apologies for acronymising all your states).

更多推荐

本文发布于:2023-07-27 04:10:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1284915.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:状态机   State   implementation   machine

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!