diff --git a/application/core/Callbacks/TimerListening.php b/application/core/Callbacks/TimerListening.php new file mode 100644 index 00000000..0e5c55ff --- /dev/null +++ b/application/core/Callbacks/TimerListening.php @@ -0,0 +1,77 @@ + + * @copyright 2014 ManiaControl Team + * @license http://www.gnu.org/licenses/ GNU General Public License, Version 3 + */ +class TimerListening { + /* + * Public Properties + */ + public $listener = null; + public $method = null; + public $deltaTime = null; + public $oneTime = null; + public $lastTrigger = null; + + /** + * Construct a new Timer Listening + * + * @param TimerListener $listener + * @param string $method + * @param float $deltaTime + */ + public function __construct(TimerListener $listener, $method, $deltaTime, $oneTime = false) { + $this->listener = $listener; + $this->method = $method; + $this->deltaTime = $deltaTime / 1000.; + $this->lastTrigger = microtime(true); + $this->oneTime = (bool)$oneTime; + } + + /** + * Increase last Trigger Time + */ + public function tick() { + $this->lastTrigger += $this->deltaTime; + } + + /** + * Trigger the Listener's Method + * + * @param float $time + */ + public function triggerCallback($time) { + call_user_func($this->getUserFunction(), $time); + } + + /** + * Get the Callable User Function + * + * @return callable + */ + public function getUserFunction() { + if (is_callable($this->method)) { + return $this->method; + } + return array($this->listener, $this->method); + } + + /** + * Check if the desired Time is reached + * + * @param float $time + * @return bool + */ + public function isTimeReached($time = null) { + if (!$time) { + $time = microtime(true); + } + return ($this->lastTrigger + $this->deltaTime > $time); + } +} diff --git a/application/core/Callbacks/TimerManager.php b/application/core/Callbacks/TimerManager.php index 78cc6fc2..ee69a9f0 100644 --- a/application/core/Callbacks/TimerManager.php +++ b/application/core/Callbacks/TimerManager.php @@ -5,7 +5,7 @@ namespace ManiaControl\Callbacks; use ManiaControl\ManiaControl; /** - * Class for managing Timers + * Class for managing Timed Callbacks * * @author ManiaControl Team * @copyright 2014 ManiaControl Team @@ -49,22 +49,12 @@ class TimerManager { */ public function registerTimerListening(TimerListener $listener, $method, $time, $oneTime = false) { if ((!is_string($method) || !method_exists($listener, $method)) && !is_callable($method)) { - trigger_error("Given listener (" . get_class($listener) . ") can't handle timer (no method '{$method}')!"); + trigger_error("Given Listener (" . get_class($listener) . ") can't handle Timer Callback (No Method '{$method}')!"); return false; } - //Init the Timer Listening - // TODO: extra model class - $listening = new \stdClass(); - $listening->listener = $listener; - $listening->method = $method; - $listening->deltaTime = $time / 1000; - $listening->oneTime = $oneTime; - if ($oneTime) { - $listening->lastTrigger = microtime(true); - } else { - $listening->lastTrigger = -1; - } + // Build Timer Listening + $listening = new TimerListening($listener, $method, $time, $oneTime); array_push($this->timerListenings, $listening); return true; @@ -78,17 +68,18 @@ class TimerManager { * @return bool */ public function unregisterTimerListening(TimerListener $listener, $method) { - foreach ($this->timerListenings as $key => $listening) { - if ($listening->listener == $listener && $listening->method == $method) { + $removed = false; + foreach ($this->timerListenings as $key => &$listening) { + if ($listening->listener === $listener && $listening->method == $method) { unset($this->timerListenings[$key]); - return true; + $removed = true; } } - return false; + return $removed; } /** - * Remove a Timer Listener + * Unregister a Timer Listener * * @param TimerListener $listener * @return bool @@ -96,11 +87,10 @@ class TimerManager { public function unregisterTimerListenings(TimerListener $listener) { $removed = false; foreach ($this->timerListenings as $key => &$listening) { - if ($listening->listener != $listener) { - continue; + if ($listening->listener === $listener) { + unset($this->timerListenings[$key]); + $removed = true; } - unset($this->timerListenings[$key]); - $removed = true; } return $removed; } @@ -110,29 +100,23 @@ class TimerManager { */ public function manageTimings() { $time = microtime(true); - foreach ($this->timerListenings as $key => &$listening) { - if (($listening->lastTrigger + $listening->deltaTime) <= $time) { - //Increase the lastTrigger time manually (to improve accuracy) - if ($listening->lastTrigger != -1) { - $listening->lastTrigger += $listening->deltaTime; - } else { - //Initialize Timer - $listening->lastTrigger = $time; - } + foreach ($this->timerListenings as $key => $listening) { + /** @var TimerListening $listening */ - //Unregister one time Listening - if ($listening->oneTime == true) { - unset($this->timerListenings[$key]); - } - - //Call the User func (at the end to avoid endless loops) - if (is_callable($listening->method)) { - call_user_func($listening->method, $time); - } else { - call_user_func(array($listening->listener, $listening->method), $time); - } + if (!$listening->isTimeReached($time)) { + continue; } + + if ($listening->oneTime) { + // Unregister one time Listening + unset($this->timerListenings[$key]); + } + + $listening->tick(); + + // Call the User Function + $listening->triggerCallback($time); } } }