【发布时间】:2010-02-01 21:57:40
【问题描述】:
我有一个如下所述的状态机。
我们可以从两个起始状态之一开始,但我们必须达到握手的所有 4 个状态。从那里,我们可以传输数据负载或接收数据负载。然后,我们回到原来的起始状态。
握手:
-> StartingState1 -> FinalState1 -> StartingState2 -> FinalState2
-> StartingState2 -> FinalState2 -> StartingState1 -> FinalState1
有效载荷转移:
-> SendPayload -> SendEnd -> StartingState?
-> ReceivePayload -> ReceiveEnd -> StartingState?
下面的代码代表了我当前的架构。不幸的是,在每个过程结束时,我没有足够的来自状态的信息来知道我应该达到的下一个状态。
有人对如何根据我的要求改进此架构有任何建议吗?
谢谢, 保罗H
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 设计问题,而不是代码问题。
-
@Hamish - 那么你对改进的 FSM 设计有什么建议吗?
-
我建议你研究一下状态机语言和编译器。我的直觉表明,有些工具可以根据状态机描述生成框架或模板。
-
qfsm.sourceforge.net 是用于设计和测试有限状态机的有用工具,它可以将构建的 fsm 导出为各种输出格式,包括 c++ 代码。即使您只是将输出的代码用作提示并手动编辑它,它也应该对设计有很大帮助。
标签: c++ state-machine