Background_Application.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. /**
  3. *
  4. * Base application class for an application able to perform background work
  5. * based on an OSInet Finite_State_Machine (fsm).
  6. *
  7. * This version relies on OSInet FSM >= 1.6
  8. *
  9. * @copyright (c) 2007 OSI
  10. * @license Licensed under the CeCILL 2.0
  11. * @version CVS: $Id: Background_Application.php,v 1.4 2007-06-10 19:39:54 marand Exp $
  12. * @link http://wiki.audean.com/fsm/fsm
  13. * @since Not applicable yet
  14. * @package fsm
  15. * @subpackage fsm.ui
  16. */
  17. error_reporting(E_ALL|E_STRICT);
  18. /**
  19. * Base application class for an application able to perform background work
  20. * based on an OSInet FSM (finite state machine).
  21. * Concrete implementations should include a constructor defining the
  22. * backgroundGoals array along the FSM graph.
  23. * @package fsm
  24. * @subpackage fsm.ui
  25. */
  26. abstract class Background_Application
  27. {
  28. /**
  29. * Trace operation to stdout
  30. *
  31. * @var boolean
  32. */
  33. public $backgroundTrace = FALSE ;
  34. /**
  35. * This is the FSM sequencing the background operation
  36. * @var Finite_State_Machine
  37. */
  38. public $finiteStateMachine;
  39. /**
  40. * event name for background work along the FSM
  41. * @var string
  42. */
  43. public $backgroundPath = NULL;
  44. /**
  45. * gtk::idle_add/idle_remove id
  46. * @var int
  47. */
  48. protected $_backgroundId;
  49. /**
  50. * path/state pairs
  51. *
  52. * These define the various background trajectories available for background
  53. * work within the FSM graph. In each pair, the "path" is the constant event
  54. * string applying until a goal is reached, and the "goal" is the terminating
  55. * state for the background work.
  56. * Sample:
  57. * $backgroundGoals = array('up' => 'live', 'down' => 'final');
  58. *
  59. * @var array
  60. */
  61. public $backgroundGoals = NULL;
  62. /**
  63. * Perform background work. Must return TRUE to be invoked again.
  64. * Do NOT loop inside: this freezes the event loop. Return instead, the
  65. * function will be invoked again anyway.
  66. *
  67. * It has to be public, otherwise gtk can't invoke it after idle_add.
  68. *
  69. * Returning false disables background work without removing it.
  70. *
  71. * @throws Exception [if background work is requested without a goals array]
  72. * @return boolean
  73. */
  74. public function backgroundDo()
  75. {
  76. $ret = TRUE;
  77. while(Gtk::events_pending())
  78. Gtk::main_iteration();
  79. if (!is_array($this->backgroundGoals))
  80. throw new Exception('Background_Application needs an array of goals to be set before background work can run.');
  81. $msg = "background work: ";
  82. $event = $this->backgroundPath;
  83. if (!array_key_exists($event, $this->backgroundGoals))
  84. {
  85. $msg = "Nothing to do for now. Stop idling";
  86. $ret = FALSE;
  87. }
  88. elseif ($this->finiteStateMachine->get_state() != $this->backgroundGoals[$event])
  89. {
  90. $msg .= "state " . $this->finiteStateMachine->get_state() . "($event)";
  91. $result = $this->finiteStateMachine->apply_event($event);
  92. $msg .= "[$result->fsm_return] => $result->fsm_state";
  93. if (!empty($result->fsm_action))
  94. $msg .= " / $result->fsm_action";
  95. }
  96. else
  97. {
  98. $msg .= "End of scheduled work";
  99. $this->backgroundStop();
  100. $ret = FALSE;
  101. }
  102. if ($this->backgroundTrace)
  103. echo $msg . PHP_EOL;
  104. return $ret;
  105. }
  106. /**
  107. * Activate background processing along an event path
  108. *
  109. * @throws Exception [if background work is requested without a goals array]
  110. * @param string $path
  111. * @return void
  112. */
  113. function backgroundStart($path = NULL)
  114. {
  115. if (!is_array($this->backgroundGoals))
  116. throw new Exception('Background_Application needs an array of goals to be set before background work can be started.');
  117. $this->backgroundPath = $path;
  118. $this->_backgroundId = Gtk::idle_add(array($this, 'backgroundDo'));
  119. }
  120. /**
  121. * Stop idle processing and remove idle processor
  122. * @return void
  123. */
  124. function backgroundStop()
  125. {
  126. Gtk::idle_remove($this->_backgroundId);
  127. $this->_backgroundId = NULL;
  128. }
  129. }