加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 状态机实现

发布时间:2020-12-16 10:16:18 所属栏目:百科 来源:网络整理
导读:我有一个如下所述的状态机. 我们可以从两种起始状态中的一种开始,但我们必须触及握手的所有4种状态.从那里,我们可以传输数据的有效载荷或接收数据的有效载荷.然后,我们回到原来的起始状态. 握手: – StartingState1 – FinalState1 – StartingState2 – Fi
我有一个如下所述的状态机.

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

解决方法

你所拥有的并不完全代表你系统的可能状态,但它很容易转换它.您需要其他状态来表示处于状态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并覆盖转换函数以进入正确状态.

(为所有州的首字母缩略词道歉).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读