timers module | > Module written by Manick | > Module Version Number: 2.2.0 +--------------------------------------------------------------------------- | > This program is free software; you can redistribute it and/or | > modify it under the terms of the GNU General Public License | > as published by the Free Software Foundation; either version 2 | > of the License, or (at your option) any later version. | > | > This program is distributed in the hope that it will be useful, | > but WITHOUT ANY WARRANTY; without even the implied warranty of | > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | > GNU General Public License for more details. | > | > You should have received a copy of the GNU General Public License | > along with this program; if not, write to the Free Software | > Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +--------------------------------------------------------------------------- | Changes | =======------- | > If you wish to suggest or submit an update/change to the source | > code, email me at manick@manekian.com with the change, and I | > will look to adding it in as soon as I can. +--------------------------------------------------------------------------- */ /* * Redesigned 12/22/04... Yes... this file sucks. I basically am going to * do a few things here. I have been stuck on this file for the past 2 weeks, * trying to come up with some ideas to handle the hopeless situation which * faced me. With the new queue system, this timer class became very interesting * to handle. I had to decide how I would add proc queues to the queue class * to handle specific timers in this file. Say, for instance, that a timer * is added, and then another is added that has a shorter time than that one. * The first one will have a proc queue added into the queue class, but then * the second one will have to add another proc queue. But hold on a second, * the way this works right now, after a timer is done running, the next one * is added to the process queue. I handled this by keeping track of how * many processes were in the queue, and didn't add one if there were more than * one, and the call to setCurrentTimer was from handle(). This worked, unless * you have a timer that repeats. Then the problem comes in, as it will not be * added to the proc queue until the next timer is complete. To just handle * this problem, I'm just going to add a proc to the queue for every timer * that is added, and then every timer will have a queue in the procqueue. * that way, we don't have to worry about anything. * * Also, I added a "timerStack" so that I could have reserved names and what * not. Each timer gets a unique name or ID, and that is added to the stack, * as well as sorted into the timerList. * * Okay, way that timers are handled... has changed, if you want a timer to * repeat, you must return true from the timer, runOnce was removed. * * Ooohh oohh ohh! Idea. screw linked lists and shit. I'll just add each * timer to the proc queue, and then have them call handle() with the timer * referenced! This solves all problems, and is incredibly more efficient! * This officially takes the last linked list out of my bot. I have NO IDEA * why I even used them in the first place, as php already has associative arrays * which are a lot better! GEEZ! */ class timers { //Local variables private $timerStack = array(); //list of all timers indexed by name //External Classes private $procQueue; private $socketClass; private $ircClass; //Private list of reserved php-irc timer names (please do not //use these names) private $reserved = array( "listening_timer_[0-9]*", "check_nick_timer", "check_channels_timer", "check_ping_timeout_timer", ); public function __construct() { $this->time = time(); $this->timerStack = array(); } public function setSocketClass($class) { $this->socketClass = $class; } public function setIrcClass($class) { $this->ircClass = $class; } public function setProcQueue($class) { $this->procQueue = $class; } public static function getMicroTime() { return microtime(true); } public function getTimers() { return $this->timerStack; } public function handle($timer) { $microTime = self::getMicroTime(); if (!isset($this->timerStack[$timer->name])) { return false; } if ($this->timerStack[$timer->name] !== $timer) { return false; } $timer->lastTimeRun = $microTime; $timer->nextRunTime = $microTime + $timer->interval; if ($timer->class != null) { $theFunc = $timer->func; $status = $timer->class->$theFunc($timer->args); } else { $theFunc = $timer->func; $status = $theFunc($timer->args); } if ($status != true) { $this->removeTimer($timer->name); } else { $this->procQueue->addQueue($this->ircClass, $this, "handle", $timer, $timer->interval); } return false; } public function removeAllTimers() { foreach ($this->timerStack AS $timer) { $this->removeTimer($timer->name); } } public function addTimer($name, $class, $function, $args, $interval, $runRightAway = false) { if (trim($name) == "") { return false; } if (isset($this->timerStack[$name])) { return false; } $newTimer = new timer; $newTimer->name = $name; $newTimer->class = $class; $newTimer->func = $function; $newTimer->args = $args; $newTimer->interval = $interval; $newTimer->removed = false; if ($runRightAway == false) { $newTimer->lastTimeRun = $this->getMicroTime(); $newTimer->nextRunTime = $this->getMicroTime() + $interval; $tInterval = $interval; } else { $newTimer->lastTimeRun = 0; $newTimer->nextRunTime = $this->getMicroTime(); $tInterval = 0; } $this->procQueue->addQueue($this->ircClass, $this, "handle", $newTimer, $tInterval); $this->timerStack[$newTimer->name] = $newTimer; return $name; } /* Remove the current timer from both the list and stack, changed in 2.1.2, can only call by * timer name now. */ public function removeTimer($name) { if (!isset($this->timerStack[$name])) { return false; } //Set removed flag, $this->timerStack[$name]->removed = true; //Remove from stack unset($this->timerStack[$name]->args); unset($this->timerStack[$name]->class); unset($this->timerStack[$name]); return true; } } ?>