|
@@ -5,10 +5,43 @@
|
|
* (c) 2006 Ouest Systèmes Informatiques (OSI)
|
|
* (c) 2006 Ouest Systèmes Informatiques (OSI)
|
|
* Licensed under the CeCILL 2.0 license
|
|
* Licensed under the CeCILL 2.0 license
|
|
*
|
|
*
|
|
- * $Id: u_fsm.php,v 1.1 2006-12-03 23:20:08 marand Exp $
|
|
|
|
|
|
+ * $Id: u_fsm.php,v 1.2 2007-04-28 20:02:50 marand Exp $
|
|
*/
|
|
*/
|
|
require_once('misc.php'); // for func_name()
|
|
require_once('misc.php'); // for func_name()
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * This class defines a possible outcome for a given FSM transition
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+class fsm_result
|
|
|
|
+ {
|
|
|
|
+ /**
|
|
|
|
+ * The name of the state to which the FSM must change. If NULL, do not change
|
|
|
|
+ * the current state.
|
|
|
|
+ *
|
|
|
|
+ * @var string
|
|
|
|
+ */
|
|
|
|
+ public $fsm_state;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * The name of an event to be fired after the state change has been applied
|
|
|
|
+ *
|
|
|
|
+ * @var string
|
|
|
|
+ */
|
|
|
|
+ public $fsm_action;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @param string $state
|
|
|
|
+ * @param string $action
|
|
|
|
+ * @return void
|
|
|
|
+ */
|
|
|
|
+ public function __construct($state = NULL, $action = NULL)
|
|
|
|
+ {
|
|
|
|
+ $this->fsm_state = $state;
|
|
|
|
+ $this->fsm_action = $action;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
abstract class fsm
|
|
abstract class fsm
|
|
{
|
|
{
|
|
/**
|
|
/**
|
|
@@ -22,7 +55,7 @@ abstract class fsm
|
|
* state1
|
|
* state1
|
|
* event1
|
|
* event1
|
|
* result1
|
|
* result1
|
|
- * action1
|
|
|
|
|
|
+ * state_name|fsm_result
|
|
* event2
|
|
* event2
|
|
* ...
|
|
* ...
|
|
* ..
|
|
* ..
|
|
@@ -133,7 +166,7 @@ abstract class fsm
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * apply an event
|
|
|
|
|
|
+ * apply an event, and the resulting event chain if needed
|
|
*
|
|
*
|
|
* @param string $event_name
|
|
* @param string $event_name
|
|
* @param array $params the
|
|
* @param array $params the
|
|
@@ -143,6 +176,25 @@ abstract class fsm
|
|
{
|
|
{
|
|
//echo func_name() . "\n";
|
|
//echo func_name() . "\n";
|
|
|
|
|
|
|
|
+ do {
|
|
|
|
+ $result = $this->apply_simple_event($event_name);
|
|
|
|
+ $event_name = $result->fsm_action; // can be NULL
|
|
|
|
+ } while($event_name);
|
|
|
|
+
|
|
|
|
+ return $result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Helper for apply_event that does not implement the post-transition action
|
|
|
|
+ *
|
|
|
|
+ * @param string $event_name
|
|
|
|
+ * @return fsm_result
|
|
|
|
+ * @see apply_event()
|
|
|
|
+ */
|
|
|
|
+ private function apply_simple_event($event_name)
|
|
|
|
+ {
|
|
|
|
+ //echo func_name() . "\n";
|
|
|
|
+
|
|
if (! $this->is_event_allowed($event_name))
|
|
if (! $this->is_event_allowed($event_name))
|
|
throw new Exception(func_name()
|
|
throw new Exception(func_name()
|
|
. ": Event \"$event_name\" not accepted in current state \"$this->f_state\"");
|
|
. ": Event \"$event_name\" not accepted in current state \"$this->f_state\"");
|
|
@@ -151,17 +203,18 @@ abstract class fsm
|
|
$outcomes = $this->get_accepted_outcomes($event_name);
|
|
$outcomes = $this->get_accepted_outcomes($event_name);
|
|
|
|
|
|
$result = $this->$method_name();
|
|
$result = $this->$method_name();
|
|
-
|
|
|
|
- if (!in_array($result, $outcomes))
|
|
|
|
|
|
+ if (!is_object($result))
|
|
|
|
+ {
|
|
|
|
+ $result = new fsm_result($result, NULL);
|
|
|
|
+ }
|
|
|
|
+ if (!in_array($result->fsm_state, $outcomes))
|
|
throw new Exception(func_name()
|
|
throw new Exception(func_name()
|
|
. ": event guard. Transition on \"$event_name\" return invalid result: "
|
|
. ": event guard. Transition on \"$event_name\" return invalid result: "
|
|
. var_dump($result)
|
|
. var_dump($result)
|
|
. "\n");
|
|
. "\n");
|
|
|
|
|
|
- $this->f_state = $this->f_transitions[$this->f_state][$event_name][$result];
|
|
|
|
- // echo "new state: $this->f_state\n";
|
|
|
|
-
|
|
|
|
|
|
+ $this->f_state = $this->f_transitions[$this->f_state][$event_name][$result->fsm_state];
|
|
|
|
+ // echo func_name() . ", new state: $this->f_state, action: $result->fsm_action\n";
|
|
return $result;
|
|
return $result;
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|