php__phplib/OSInet/Finite_State_Machine/BackgroundApplication.php
Frederic G. MARAND 7d0f0d44ea Restructured file layout to incorporate a PSR0 version of Class_Grapher.
- new OSInet/Class_Grapher directory
- moved misc.php and other miscellaneous PHP files to misc/
- split the PSR0 autoloader from misc.php to psr0.php
- moved BackgroundApplication to FSM directory
- moved FSM samples and docs to FSM help directory
- new "apps" directory for the demo source
- new Class_Grapher demo app
- moved the files of the FSM FTP demo app to "apps". Likely broken.
2012-05-02 23:29:47 +02:00

136 lines
3.7 KiB
PHP

<?php
/**
*
* Base application class for an application able to perform background work
* based on an OSInet Finite_State_Machine (fsm).
*
* This version relies on OSInet FSM >= 1.6
*
* @copyright (c) 2007-2012 OSI
* @license Licensed under the CeCILL 2.0
* @link http://wiki.audean.com/fsm/fsm
*/
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 BackgroundApplication {
/**
* Trace operation to stdout
*
* @var boolean
*/
public $backgroundTrace = FALSE ;
/**
* This is the FSM sequencing the background operation
* @var 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->getState() != $this->backgroundGoals[$event])
{
$msg .= "state " . $this->finiteStateMachine->getState() . "($event)";
$result = $this->finiteStateMachine->applyEvent($event);
$msg .= "[$result->fsmReturn] => $result->fsmState";
if (!empty($result->fsmAction))
$msg .= " / $result->fsmAction";
}
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;
}
}