BackgroundApplication.php 3.7 KB

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