/** * Backtracking Runner * * Similar to SequenceRunner but takes a backtracking approach to guarantee finding * a correct path if one exists with the given input sequence. * * Note: * * The first solution encountered is returned, additional solutions may exist but no attempt will be made * to find them. * * As we need to backtrack consider how you're context object changes during transitions, you may need * a customised __clone(). * * This isn't efficient :) If your FSM is large or very recursive then you're going to run out of memory quickly... * * @param State $initialState * @param Stateful $context */ public function __construct(State $initialState, Stateful $context = null) { $this->context = $context ?: new Context(); $this->context->setCurrentState($initialState); $this->graph = new GraphBuilder($initialState); }
/** * Apply Transition * * @param mixed $input * @param Stateful $context * @param Runner $runner * * @return mixed */ public function apply($input, Stateful $context, Runner $runner) { $context->setCurrentState($this->to); if ($this->action !== null && is_callable($this->action)) { return call_user_func($this->action, $input, $context, $runner, $this); } if ($input instanceof InputSequence) { $input->pop(); } return $this->action ?: $this->to; }