|
@@ -0,0 +1,136 @@
|
|
|
+<?php
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This version relies on OSInet FSM >= 1.5
|
|
|
+ *
|
|
|
+ * @copyright (c) 2007 OSI
|
|
|
+ * @license Licensed under the CeCILL 2.0
|
|
|
+ * @version CVS: $Id: Background_Application.php,v 1.1 2007-05-08 21:48:13 marand Exp $
|
|
|
+ * @link http://wiki.audean.com/
|
|
|
+ * @since Not applicable yet
|
|
|
+ */
|
|
|
+
|
|
|
+error_reporting(E_ALL|E_STRICT);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Base application class for an application able to perform background work
|
|
|
+ * based on an OSInet FSM (finite state machine).
|
|
|
+ * Concrete implementations should include a constructor defining the
|
|
|
+ * backgroundGoals array along the FSM graph.
|
|
|
+ */
|
|
|
+abstract class Background_Application
|
|
|
+ {
|
|
|
+ /**
|
|
|
+ * Trace operation to stdout
|
|
|
+ *
|
|
|
+ * @var boolean
|
|
|
+ */
|
|
|
+ public $backgroundTrace = FALSE ;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This is the FSM sequencing the background operation
|
|
|
+ * @var Finite_State_Machine
|
|
|
+ */
|
|
|
+ public $finiteStateMachine;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * event name for background work along the FSM
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ public $backgroundPath = NULL;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * gtk::idle_add/idle_remove id
|
|
|
+ * @var int
|
|
|
+ */
|
|
|
+ protected $_backgroundId;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * path/state pairs
|
|
|
+ *
|
|
|
+ * These define the various background trajectories available for background
|
|
|
+ * work within the FSM graph. In each pair, the "path" is the constant event
|
|
|
+ * string applying until a goal is reached, and the "goal" is the terminating
|
|
|
+ * state for the background work.
|
|
|
+ * Sample:
|
|
|
+ * $backgroundGoals = array('up' => 'live', 'down' => 'final');
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ public $backgroundGoals = NULL;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Perform background work. Must return TRUE to be invoked again.
|
|
|
+ * Do NOT loop inside: this freezes the event loop. Return instead, the
|
|
|
+ * function will be invoked again anyway.
|
|
|
+ *
|
|
|
+ * It has to be public, otherwise gtk can't invoke it after idle_add.
|
|
|
+ *
|
|
|
+ * Returning false disables background work without removing it.
|
|
|
+ *
|
|
|
+ * @throws Exception [if background work is requested without a goals array]
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ public function backgroundDo()
|
|
|
+ {
|
|
|
+ $ret = TRUE;
|
|
|
+ while(Gtk::events_pending())
|
|
|
+ Gtk::main_iteration();
|
|
|
+
|
|
|
+ if (!is_array($this->backgroundGoals))
|
|
|
+ throw new Exception('Background_Application needs an array of goals to be set before background work can run.');
|
|
|
+
|
|
|
+ $msg = "background work: ";
|
|
|
+ $event = $this->backgroundPath;
|
|
|
+ if (!array_key_exists($event, $this->backgroundGoals))
|
|
|
+ {
|
|
|
+ $msg = "Nothing to do for now. Stop idling";
|
|
|
+ $ret = FALSE;
|
|
|
+ }
|
|
|
+ elseif ($this->finiteStateMachine->get_state() != $this->backgroundGoals[$event])
|
|
|
+ {
|
|
|
+ $msg .= "state " . $this->finiteStateMachine->get_state() . "($event)";
|
|
|
+ $result = $this->finiteStateMachine->apply_event($event);
|
|
|
+ $msg .= "[$result->fsm_return] => $result->fsm_state";
|
|
|
+ if (!empty($result->fsm_action))
|
|
|
+ $msg .= " / $result->fsm_action";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ $msg .= "End of scheduled work";
|
|
|
+ $this->backgroundStop();
|
|
|
+ $ret = FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($this->backgroundTrace)
|
|
|
+ echo $msg . PHP_EOL;
|
|
|
+
|
|
|
+ return $ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Activate background processing along an event path
|
|
|
+ *
|
|
|
+ * @throws Exception [if background work is requested without a goals array]
|
|
|
+ * @param string $path
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ function backgroundStart($path = NULL)
|
|
|
+ {
|
|
|
+ if (!is_array($this->backgroundGoals))
|
|
|
+ throw new Exception('Background_Application needs an array of goals to be set before background work can be started.');
|
|
|
+
|
|
|
+ $this->backgroundPath = $path;
|
|
|
+ $this->_backgroundId = Gtk::idle_add(array($this, 'backgroundDo'));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Stop idle processing and remove idle processor
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ function backgroundStop()
|
|
|
+ {
|
|
|
+ Gtk::idle_remove($this->_backgroundId);
|
|
|
+ $this->_backgroundId = NULL;
|
|
|
+ }
|
|
|
+ }
|