【发布时间】:2010-09-01 21:03:16
【问题描述】:
我有一个需要支持播放的状态机设计。我们有执行动作的状态,有时需要生成随机数。如果程序在 FSM 执行过程中关闭,程序需要使用与之前相同的随机数播放整个 FSM。
举个基本的例子,假设我有三个状态:A、B 和 C。FSM 将调用一个状态的 Execute() 函数。在函数结束时,状态将发布一个事件,FSM 将确定接下来要进入哪个状态。在状态 A 中,它将调用 rand()。如果数字是偶数,它会发布一个事件去状态 B,否则状态 C 应该是下一个状态。
void StateA::Execute(IEventQueue& rQueue)
{
int num = rand();
if( num % 2 == 0 )
{
rQueue.PostEvent("GoToStateB");
}
else
{
rQueue.PostEvent("GoToStateC");
}
}
如果随机数是 69,那么它应该进入状态 C。当处于状态 C 时,程序可能会退出。当程序再次启动时,它应该播放状态机。显然,要让它正常工作,它不能生成一个全新的随机数,它需要再次使用 69 才能准确播放。
我有一个文件流接口,可以用来将数据保存到文件中,但是代码有点难看:
void StateA::Execute(IEventQueue& rQueue, IFileStream& rStream)
{
int num = 0;
// fails if there's no more data to read
bool bSuccess = rStream.ReadInt(num);
if (!bSucess)
{
num = rand();
rStream.WriteInt(num);
}
// same code as before
}
我对这个解决方案的唯一问题是我不关心必须先检查流中的数据,然后有条件地写入同一个流。
我想过这样隐藏它:
void StateA::Execute(IEventQueue& rQueue, IStream& rStream)
{
int num = 0;
num = rand();
rStream & num;
// same code as before
}
在 IStream 内部,operator&(可能不是重载的最佳用途)实际上会尝试从流中读取一个 int。如果该流是空的,它将改为写入它。和以前一样,行为是:先读取直到流结束,然后开始追加。
所以我想我的问题是:对于这种类型的播放是否有一个我可能会忽略的常见习语?有没有人有其他建议?我觉得我的设计有点过于复杂了。
谢谢!
【问题讨论】:
-
你说得对,重载真的不是很好用。不要那样做!
-
另外,使用固定随机种子是不可能的吗?
-
种子是不可能的。我们实际上使用了一个不同的 RNG 系统,它有点复杂。另外,我只以RNG为例。理想情况下,我希望能够将任何数据写入流并使其可用于播放。
标签: c++ stream state-machine