Background_Application.php 3.8 KB

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