123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- <?php
- require_once('misc.php');
- abstract class fsm
- {
-
- protected $f_state;
-
- protected $f_transitions = null;
-
- public function __construct()
- {
- $this->_check_transitions();
- reset($this->f_transitions);
- $x = each($this->f_transitions);
- $x = $x[0];
- $this->f_state = $x;
- }
-
- private function _check_transitions()
- {
- if (!isset($this->f_transitions))
- throw new Exception('No FSM processing is allowed without a transitions table');
- }
-
- public function get_state()
- {
- return $this->f_state;
- }
-
- public function get_accepted_events()
- {
- $this->_check_transitions();
- $events = array_keys($this->f_transitions[$this->f_state]);
-
- return $events;
- }
-
- public function get_accepted_outcomes($event_name)
- {
-
- $this->_check_transitions();
- if (!$this->is_event_allowed($event_name))
- throw new Exception(func_name() . ": event \"$event_name\" not allowed in state \"$this->f_state\"\n");
- $outcomes = array_keys($this->f_transitions[$this->f_state][$event_name]);
-
- return $outcomes;
- }
-
- public function is_event_allowed($event_name)
- {
-
- $this->_check_transitions();
- $ret = in_array($event_name, $this->get_accepted_events());
-
- return $ret;
- }
-
- public function is_outcome_allowed($event_name, $outcome)
- {
- $this->_check_transitions();
- if (!$this->is_event_allowed($event_name))
- return false;
- $ret = array_key_exists($outcome, $this->get_accepted_outcomes($event_name));
- return $ret;
- }
-
- public function apply_event($event_name)
- {
-
- if (! $this->is_event_allowed($event_name))
- throw new Exception(func_name()
- . ": Event \"$event_name\" not accepted in current state \"$this->f_state\"");
- $method_name = "f_$event_name";
- $outcomes = $this->get_accepted_outcomes($event_name);
- $result = $this->$method_name();
- if (!in_array($result, $outcomes))
- throw new Exception(func_name()
- . ": event guard. Transition on \"$event_name\" return invalid result: "
- . var_dump($result)
- . "\n");
- $this->f_state = $this->f_transitions[$this->f_state][$event_name][$result];
-
- return $result;
- }
- }
|