Background_Application.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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.3 2007-06-10 16:30:30 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. */
  24. abstract class Background_Application
  25. {
  26. /**
  27. * Trace operation to stdout
  28. *
  29. * @var boolean
  30. */
  31. public $backgroundTrace = FALSE ;
  32. /**
  33. * This is the FSM sequencing the background operation
  34. * @var Finite_State_Machine
  35. */
  36. public $finiteStateMachine;
  37. /**
  38. * event name for background work along the FSM
  39. * @var string
  40. */
  41. public $backgroundPath = NULL;
  42. /**
  43. * gtk::idle_add/idle_remove id
  44. * @var int
  45. */
  46. protected $_backgroundId;
  47. /**
  48. * path/state pairs
  49. *
  50. * These define the various background trajectories available for background
  51. * work within the FSM graph. In each pair, the "path" is the constant event
  52. * string applying until a goal is reached, and the "goal" is the terminating
  53. * state for the background work.
  54. * Sample:
  55. * $backgroundGoals = array('up' => 'live', 'down' => 'final');
  56. *
  57. * @var array
  58. */
  59. public $backgroundGoals = NULL;
  60. /**
  61. * Perform background work. Must return TRUE to be invoked again.
  62. * Do NOT loop inside: this freezes the event loop. Return instead, the
  63. * function will be invoked again anyway.
  64. *
  65. * It has to be public, otherwise gtk can't invoke it after idle_add.
  66. *
  67. * Returning false disables background work without removing it.
  68. *
  69. * @throws Exception [if background work is requested without a goals array]
  70. * @return boolean
  71. */
  72. public function backgroundDo()
  73. {
  74. $ret = TRUE;
  75. while(Gtk::events_pending())
  76. Gtk::main_iteration();
  77. if (!is_array($this->backgroundGoals))
  78. throw new Exception('Background_Application needs an array of goals to be set before background work can run.');
  79. $msg = "background work: ";
  80. $event = $this->backgroundPath;
  81. if (!array_key_exists($event, $this->backgroundGoals))
  82. {
  83. $msg = "Nothing to do for now. Stop idling";
  84. $ret = FALSE;
  85. }
  86. elseif ($this->finiteStateMachine->get_state() != $this->backgroundGoals[$event])
  87. {
  88. $msg .= "state " . $this->finiteStateMachine->get_state() . "($event)";
  89. $result = $this->finiteStateMachine->apply_event($event);
  90. $msg .= "[$result->fsm_return] => $result->fsm_state";
  91. if (!empty($result->fsm_action))
  92. $msg .= " / $result->fsm_action";
  93. }
  94. else
  95. {
  96. $msg .= "End of scheduled work";
  97. $this->backgroundStop();
  98. $ret = FALSE;
  99. }
  100. if ($this->backgroundTrace)
  101. echo $msg . PHP_EOL;
  102. return $ret;
  103. }
  104. /**
  105. * Activate background processing along an event path
  106. *
  107. * @throws Exception [if background work is requested without a goals array]
  108. * @param string $path
  109. * @return void
  110. */
  111. function backgroundStart($path = NULL)
  112. {
  113. if (!is_array($this->backgroundGoals))
  114. throw new Exception('Background_Application needs an array of goals to be set before background work can be started.');
  115. $this->backgroundPath = $path;
  116. $this->_backgroundId = Gtk::idle_add(array($this, 'backgroundDo'));
  117. }
  118. /**
  119. * Stop idle processing and remove idle processor
  120. * @return void
  121. */
  122. function backgroundStop()
  123. {
  124. Gtk::idle_remove($this->_backgroundId);
  125. $this->_backgroundId = NULL;
  126. }
  127. }