Fimbulwinter Project  Pre-Alpha
An Ragnarok Online Emulator
Common/timers.hpp
00001 #pragma once
00002 
00003 #include <boost/bind.hpp>
00004 #include <boost/asio.hpp>
00005 #include <map>
00006 
00007 class TimerManager
00008 {
00009         struct TimerData
00010         {
00011                 boost::asio::deadline_timer *timer;
00012                 boost::function<void (int)> callback;
00013 
00014                 int timeout;
00015                 bool repeat;
00016         };
00017 
00018         static std::map<int, struct TimerData> timers_;
00019         static int timer_nid;
00020         static boost::asio::io_service *ios; 
00021 
00022 public:
00023         static void Initialize(boost::asio::io_service *i)
00024         {
00025                 timer_nid = 1;
00026                 ios = i;
00027         }
00028         
00029         static int CreateTimer(int timeout, bool repeat, boost::function<void (int)> callback)
00030         {
00031                 int id = timer_nid++;
00032 
00033                 timers_[id].timeout = timeout;
00034                 timers_[id].repeat = repeat;
00035                 timers_[id].callback = callback;
00036                 timers_[id].timer = new boost::asio::deadline_timer(*ios);
00037 
00038                 return id;
00039         }
00040 
00041         static int CreateStartTimer(int timeout, bool repeat, boost::function<void (int)> callback)
00042         {
00043                 int id = CreateTimer(timeout, repeat, callback);
00044 
00045                 StartTimer(id);
00046 
00047                 return id;
00048         }
00049 
00050         static void StartTimer(int id)
00051         {
00052                 if (!timers_.count(id))
00053                         return;
00054 
00055                 timers_[id].timer->expires_from_now(boost::posix_time::milliseconds(timers_[id].timeout));
00056                 timers_[id].timer->async_wait(boost::bind(&TimerManager::HandleTimer, boost::asio::placeholders::error, id));
00057         }
00058 
00059         static void HandleTimer(const boost::system::error_code &err, int id)
00060         {
00061                 if (!timers_.count(id))
00062                         return;
00063                 
00064                 timers_[id].callback(id);
00065 
00066                 if (timers_[id].repeat)
00067                         StartTimer(id);
00068                 else
00069                         FreeTimer(id);
00070         }
00071 
00072         static void FreeTimer(int id)
00073         {
00074                 if (!timers_.count(id))
00075                         return;
00076 
00077                 delete timers_[id].timer;
00078                 timers_.erase(id);
00079         }
00080 
00081         static void SetTimeout(int id, int timeout)
00082         {
00083                 if (!timers_.count(id))
00084                         return;
00085 
00086                 timers_[id].timeout = timeout;
00087                 timers_[id].timer->expires_from_now(boost::posix_time::milliseconds(timers_[id].timeout));
00088         }
00089 
00090         static void AddTimeout(int id, int timeout)
00091         {
00092                 if (!timers_.count(id))
00093                         return;
00094 
00095                 timers_[id].timeout += timeout;
00096                 timers_[id].timer->expires_from_now(boost::posix_time::milliseconds(timers_[id].timeout));
00097         }
00098 };
00099 
 All Classes Functions