= 0. * * @var int */ public $debug = NULL; /** * A hash of state name to GraphViz name. * * @var array */ public $states = array(); /** * @param Machine $m */ public function __construct(Machine $m, $values = array()) { $this->m = $m; $default_values = array( 'debug' => 0, ); $values = array_intersect_key($values, $default_values); $values += $default_values; foreach ($values as $key => $value) { $this->$key = $value; } // PEAR is not currently PSR-0 compliant. // As a consequence, strict PSR-0 autoloading will not work for it. require 'Image/GraphViz.php'; $this->g = new \Image_Graphviz(); } public function render() { $i = 0; $g = &$this->g; // First make sure all states have labeled nodes, so that forward // declarations of states occurring in transitions find the proper state id. foreach ($this->m->fTransitions as $state => $events) { $label = $state; $state .= "_$i"; $this->states[$label] = $state; $g->addNode($state, array( 'label' => $label, 'shape' => self::STATE_SHAPE, )); $i++; } foreach ($this->m->fTransitions as $state => $events) { $state_id = $this->states[$state]; foreach ($events as $event => $outcomes) { if ($this->debug) { echo "State $state Event $event " . count($outcomes) . " outcomes\n"; print_r($outcomes); } if (0 && count($outcomes) == 1) { $outcome = reset($outcomes); // Only one outcome: we do not care for the result. echo "State $state event $event, outcome:"; print_r($outcome); echo "\n"; $edge = array($state_id => $this->states[$outcome[0]]); $edge_label = "\n:" . $outcome[1]; $edge_attributes = empty($outcome[1]) ? array() : array('label' => $edge_label); $g->addEdge($edge, $edge_attributes); } else { $event_label = $event; $event_id = "{$state_id}_$event"; $g->addNode($event_id, array( 'label' => $event_label, 'shape' => self::EVENT_SHAPE, )); $g->addEdge(array($state_id => $event_id)); foreach ($outcomes as $result => $next) { list($next_state, $next_action) = $next; $edge = array($event_id => $this->states[$next_state]) ; $edge_label_parts = array(); if (!empty($result)) { $edge_label_parts[] = "[$result]"; } if (!empty($next_action)) { $edge_label_parts[] = ":$next_action"; } if (empty($edge_label_parts)) { echo "No label!\n"; $g->addEdge($edge); } else { $edge_label = implode("\n", $edge_label_parts); $edge_attributes = array( 'label' => $edge_label, ); $g->addEdge($edge, $edge_attributes); } } } } } return $g->parse(); } }