123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- <?php
- namespace OSInet\Finite_State_Machine;
- class Grapher {
- const STATE_SHAPE = 'octagon';
- const EVENT_SHAPE = 'egg';
-
- public $m;
-
- public $g;
-
- public $debug = NULL;
-
- public $states = array();
-
- 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;
- }
-
-
- require 'Image/GraphViz.php';
- $this->g = new \Image_Graphviz();
- }
- public function render() {
- $i = 0;
- $g = &$this->g;
-
-
- 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);
-
- 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();
- }
- }
|