Вернуться в состояние звонящего?
Я использую конечный автомат без состояний C#, но у меня была эта проблема в прошлом с другой реализацией конечного автомата. Вопрос в основном теоретический, хотя я могу добавить несколько фиктивных кодов, если потребуется.
У меня есть ситуация, которую я совершенно не знаю, как ее решить. Допустим, у вас есть 2 состояния (ходьба и бег), и они оба могут перейти в третье состояние (прыжок). Как только третье состояние закончено, я хочу вернуться в состояние вызывающего. В некотором смысле, я должен иметь возможность влиять на триггер вызываемого абонента, но это только передается OnEntry
и любит, а не само государство.
С помощью EntryFrom
кажется, не работает, потому что нет никакого способа повлиять на само состояние "прыжка", только OnEntry
функция. С помощью PermitDynamic
похоже, тоже не работает, потому что, оказавшись в состоянии "прыжка", я понятия не имею, откуда я.
Я мог бы иметь 2 состояния прыжка (jumpfromrun, jumpfromwalk) с одним OnEntry
функция, чтобы минимизировать дубликаты кода. Это то, что я сейчас использую.
Я мог бы сохранить предыдущее состояние во внешней переменной и передать его в мое обновление состояния. Я не хочу делать это (вообще).
Есть ли известная техника или способ решения этой проблемы? Имея общее состояние, что должно перейти обратно к вызывающей стороне? Спасибо!
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
это будет наследоваться обоими WalkJumping
а также EndJumping
,
Кроме того, это дает вам более простой способ проверить, находитесь ли вы в середине прыжка. Вместо:
var state = stateMachine.state;
var isJumping = state == State.WalkJumping || state == RunJumping;
Вы можете просто сделать:
var isJumping = stateMachine.IsInState(State.Jumping);
Который будет правильно учитывать все подсостояния, которые в настоящее время WalkJumping
а также RunJumping
, Но если вы добавите новое подсостояние перехода в будущем, например, DoubleJumping
тогда isJumping
Предикат также автоматически охватит этот случай, не забывая исправлять его.