我有一个如下所述的状态机.
我们可以从两种起始状态中的一种开始,但我们必须触及握手的所有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() );
}
}
Run Code Online (Sandbox Code Playgroud)
你所拥有的并不完全代表你系统的可能状态,但它很容易转换它.您需要其他状态来表示处于状态1和未处于状态2之间的区别,并且处于状态1,同时处于状态2(对于状态2而言相同).所以你需要:
S1 S2 F1 F2 S12 F12 S21 F21
SP SE
RP RE
Run Code Online (Sandbox Code Playgroud)
与过渡
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
Run Code Online (Sandbox Code Playgroud)
关键的区别是引入新的状态S12
,F12
,S21
和F21
.在实现方面,您几乎可以肯定地从S2导出S12,从F2导出F12,从S1导出S21,从F2导出F21并覆盖转换函数以进入正确状态.
(为所有州的首字母缩略词道歉).
归档时间: |
|
查看次数: |
3280 次 |
最近记录: |