00001 #include "pgtimerobject.h"
00002
00003 Uint32 PG_TimerObject::objectcount = 0;
00004 PG_TimerObject::ID PG_TimerObject::globalTimerID = 0;
00005 std::map<PG_TimerObject::ID, PG_TimerObject*> PG_TimerObject::timermap;
00006 PG_TimerObject* PG_TimerObject::objSingleTimer = NULL;
00007
00008 PG_TimerObject::PG_TimerObject() {
00009 if(objectcount == 0) {
00010 SDL_InitSubSystem(SDL_INIT_TIMER);
00011 }
00012
00013 objectcount++;
00014 my_lock = SDL_CreateMutex();
00015 }
00016
00017 PG_TimerObject::~PG_TimerObject() {
00018
00019
00020 StopTimer();
00021
00022
00023 std::map<PG_TimerObject::ID, SDL_TimerID>::iterator i;
00024
00025 for(i = my_timermap.begin(); i != my_timermap.end(); ) {
00026 RemoveTimer((*i).first);
00027 i = my_timermap.begin();
00028 }
00029
00030 objectcount--;
00031
00032 if(objectcount == 0) {
00033 SDL_QuitSubSystem(SDL_INIT_TIMER);
00034 }
00035
00036 SDL_DestroyMutex(my_lock);
00037 }
00038
00039 PG_TimerObject::ID PG_TimerObject::AddTimer(Uint32 interval) {
00040 SDL_mutexP(my_lock);
00041 SDL_TimerID id = SDL_AddTimer(interval, &PG_TimerObject::callbackTimer, (void*)(globalTimerID+1));
00042
00043 if(id == 0) {
00044 SDL_mutexV(my_lock);
00045 return 0;
00046 }
00047
00048 PG_TimerObject::ID pgid = ++globalTimerID;
00049 my_timermap[pgid] = id;
00050 timermap[pgid] = this;
00051 SDL_mutexV(my_lock);
00052
00053 return pgid;
00054 }
00055
00056 bool PG_TimerObject::RemoveTimer(PG_TimerObject::ID id) {
00057 SDL_mutexP(my_lock);
00058 SDL_TimerID sid = my_timermap[id];
00059 my_timermap.erase(id);
00060 timermap.erase(id);
00061
00062 bool rc = (SDL_RemoveTimer(sid) != 0);
00063 SDL_mutexV(my_lock);
00064 return rc;
00065 }
00066
00067 Uint32 PG_TimerObject::eventTimer(PG_TimerObject::ID id, Uint32 interval) {
00068 return interval;
00069 }
00070
00071 Uint32 PG_TimerObject::eventTimer(Uint32 interval) {
00072 return interval;
00073 }
00074
00075 Uint32 PG_TimerObject::callbackTimer(Uint32 interval, void* data) {
00076 PG_TimerObject::ID id = reinterpret_cast<PG_TimerObject::ID>(data);
00077 PG_TimerObject* o = timermap[id];
00078
00079
00080 if(o == NULL) {
00081 return 0;
00082 }
00083 SDL_mutexP(o->my_lock);
00084
00085 o->sigTimer(timermap[id], id);
00086 Uint32 r = o->eventTimer(id, interval);
00087 SDL_mutexV(o->my_lock);
00088
00089 return r;
00090 }
00091
00092 Uint32 PG_TimerObject::callbackSingleTimer(Uint32 interval) {
00093 Uint32 r = 0;
00094 if(objSingleTimer != NULL) {
00095 SDL_mutexP(objSingleTimer->my_lock);
00096 objSingleTimer->sigTimer(objSingleTimer, (PG_TimerObject::ID)0);
00097 r = objSingleTimer->eventTimer(interval);
00098 SDL_mutexV(objSingleTimer->my_lock);
00099 }
00100
00101 return r;
00102 }
00103
00104 int PG_TimerObject::SetTimer(Uint32 interval) {
00105 SDL_mutexP(my_lock);
00106 StopTimer();
00107 objSingleTimer = this;
00108 int r = SDL_SetTimer(interval, &PG_TimerObject::callbackSingleTimer);
00109 SDL_mutexV(my_lock);
00110
00111 return r;
00112 }
00113
00114 void PG_TimerObject::StopTimer() {
00115 SDL_mutexP(my_lock);
00116 if(objSingleTimer != NULL) {
00117 objSingleTimer = NULL;
00118 SDL_SetTimer(0, NULL);
00119 }
00120 SDL_mutexV(my_lock);
00121 }