我正在使用C#的无状态状态机,但我过去曾经遇到过其他状态机实现这个问题。问题主要是理论上的问题,但如果要求我可以添加一些虚拟代码。
我有一种情况,我很不确定如何解决。假设你有两种状态(步行和跑步),它们都可以转换到第三种状态(跳跃)。一旦第三个状态完成,我希望回到调用者状态。在某种程度上,我必须能够影响被调用者触发器,但这只会传递给OnEntry
和喜欢的人,而不是状态本身。
使用EntryFrom
似乎不起作用,因为没有办法影响"跳跃"陈述自己,只有OnEntry
函数。
使用PermitDynamic
似乎也不起作用,因为一旦进入"跳跃"国家,我不知道我来自哪里。
我可以使用单个OnEntry
函数获得2个跳转状态(jumpfromrun,jumpfromwalk),以最小化一些重复的代码。这就是我目前使用的。
我可以将先前的状态保存在外部变量中并将其传递给我的状态更新。我不想这样做(根本)。
是否有已知的技术或方法来处理此类问题?有一个共享状态,应该转换回调用者? 谢谢!
答案 0 :(得分:1)
通过阅读文档,对于子状态来说,这似乎是一个非常好的用例。
你可以有一个跳跃状态:
stateMachine.Configure(State.Jumping)
.OnEntry(() => StartJump())
.OnExit(() => EndJump());
和两个跳跃子状态。一个用于步行,一个用于跑步:
stateMachine.Configure(State.WalkJumping)
.SubstateOf(State.Jumping)
.Permit(Trigger.DoneJumping, State.Walking);
stateMachine.Configure(State.RunJumping)
.SubstateOf(State.Jumping)
.Permit(Trigger.DoneJumping, State.Running);
然后你分别走路和跑步路线到WalkJumping和RunJumping。
stateMachine.Configure(State.Walking)
.OnEntry(() => StartWalking())
.OnExit(() => EndWalking());
.Permit(Trigger.Jump, State.WalkJumping);
stateMachine.Configure(State.Running)
.OnEntry(() => StartRunning())
.OnExit(() => EndRunning());
.Permit(Trigger.Jump, State.RunJumping);
使用这样的基板,而不仅仅是常规状态,还有一个额外的好处,即State.Jumping
可以定义OnEntry
和OnExit
,它们将由{{1}继承}和WalkJumping
。
此外,它还为您提供了一种更简单的方法来检查您是否处于跳跃状态。而不是:
EndJumping
您可以这样做:
var state = stateMachine.state;
var isJumping = state == State.WalkJumping || state == RunJumping;
将适当考虑当前var isJumping = stateMachine.IsInState(State.Jumping);
和WalkJumping
的所有子状态。但是如果你将来添加一个新的跳跃子状态,例如RunJumping
,DoubleJumping
谓词也将自动覆盖该案例,无需记住修复。