Shadowrun: Awakened 29 September 2011 - Build 871
TimedEventManager.cpp
Go to the documentation of this file.
00001 #include "TimedEventManager.h"
00002 
00003 namespace Support
00004 {
00008     TimedEventManager::TimerTracker::TimerTracker(double periodInSeconds, ThreadTaskBase* task) : 
00009         _timer(periodInSeconds),
00010         _task(task), 
00011         _recurring(false)
00012     {
00013     }
00014 
00018     TimedEventManager::TimerTracker::TimerTracker() : 
00019         _timer(0),
00020         _task(NULL), 
00021         _recurring(false)
00022     {
00023     }
00024 
00028     bool TimedEventManager::TimerTracker::operator==(const TimerTracker& rhs)
00029     {
00030         if((_task == rhs._task) && (_timer == rhs._timer) && (_recurring == rhs._recurring))
00031             return true;
00032         else
00033             return false;
00034     }
00035 
00039     TimedEventManager::TimedTask::TimedTask()
00040     {
00041         //since we're managed by a pool, we don't want to be deleted
00042         setDelete(false);
00043     }
00044 
00048     void TimedEventManager::TimedTask::execute()
00049     {
00050         _tracker.execute();
00051         _manager->_taskPool.recycle(this);
00052     }
00053 
00057     TimedEventManager::TimerManager::TimerManager(TimedEventManager* manager) : _manager(manager)
00058     {
00059         _timerGrain.sec = TimedEventManagerGranularityInSeconds;
00060     }
00061 
00066     void TimedEventManager::TimerManager::execute()
00067     {
00068         while(true)
00069         {
00070             _manager->checkTimers();
00071             boost::thread::sleep(_timerGrain);
00072         }
00073     }
00074 
00078     void TimedEventManager::checkTimers()
00079     {
00080         //perform this check while locking on the timer mutex
00081         boost::lock_guard<boost::mutex> guard(_timerMutex);
00082         //iterate through the list of timers, checking if they have elapsed
00083         std::list<TimerTracker>::iterator it=_timers.begin();
00084         while(it != _timers.end())
00085         {
00086             //act on the current item only, save the next item in the loop iter
00087             std::list<TimerTracker>::iterator currentItem = it++;
00088             //only act if this is elapsed
00089             if(currentItem->isTimerElapsed())
00090             {
00091                 //get a task from the pool, set it, and queue it
00092                 TimedTask* task = _taskPool.getInstance();
00093                 task->_tracker = *currentItem;
00094                 task->_manager = this;
00095                 queueTask(task);
00096                 //the queued item will carry things out, from here we either renew it or let it go
00097                 if(currentItem->isRecurring())
00098                     currentItem->reset();
00099                 else
00100                     _timers.remove(*currentItem);
00101             }
00102         }
00103     }
00104 
00108     TimedEventManager::TimedEventManager(size_t threadCount) : ThreadPool(threadCount), _taskPool((unsigned int)threadCount)
00109     {
00110         //we reserve one worker to carry out timer management
00111         createWorkerThread();
00112         queueTask(new TimerManager(this));
00113     }
00114 
00118     TimedEventManager::~TimedEventManager()
00119     {
00120         stop();
00121     }
00122 
00126     void TimedEventManager::addTimedEvent(double periodInSeconds, ThreadTaskBase* task, bool recurring)
00127     {
00128         TimerTracker tracker(periodInSeconds, task);
00129         tracker.setRecurring(recurring);
00130 
00131         //lock when adding timer
00132         boost::lock_guard<boost::mutex> guard(_timerMutex);
00133         _timers.push_back(tracker);
00134     }
00135 }

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net