diff --git a/bazaar/Timer/Timer.cpp b/bazaar/Timer/Timer.cpp index ebc0f710c..fd52ce23f 100644 --- a/bazaar/Timer/Timer.cpp +++ b/bazaar/Timer/Timer.cpp @@ -22,12 +22,13 @@ Timer::~Timer() void Timer::sTimeCallback(dword time, int delay, Callback cb, void *id) { TimeEvent *list = elist.GetPtr(); TimeEvent *e; - for(e = list->GetNext(); e != list && time >= e->time; e = e->GetNext()); + for(e = list->GetNext(); e != list && ((int)(time - e->time) >= 0); e = e->GetNext()); TimeEvent *ne = e->InsertPrev(); ne->time = time; ne->cb = cb; ne->delay = delay; ne->id = id; + ne->rep = false; } void Timer::SetTimeCallback(int delay_ms, Callback cb, void *id) { @@ -73,7 +74,8 @@ void Timer::KillTimeCallback(void *id) { KillTimeCallbacks(id); } -void Timer::TimerProc(dword time, int & leftsleep) +#if 0 +void Timer::TimerProc(dword time, int& leftsleep) { if(IsPanicMode()) return; @@ -90,16 +92,63 @@ void Timer::TimerProc(dword time, int & leftsleep) while(list->GetNext() != list && ((leftsleep = (list->GetNext()->time - time)) <= 0)) { TimeEvent *e = list->GetNext(); e->Unlink(); - if(e->delay < 0) - sTimeCallback(time - e->delay, e->delay, e->cb, e->id); sTimerLock.Leave(); e->cb(); sTimerLock.Enter(); + if(e->delay < 0) { + dword t = GetTickCount(); + sTimeCallback(t + (t == time) - e->delay, e->delay, e->cb, e->id); + } delete e; } sTimerLock.Leave(); if(leftsleep < 0) leftsleep = granularity; //if last done has been processed and no more in queue, ensure good sleep } +#else +void Timer::TimerProc(dword time, int& leftsleep) +{ + if(IsPanicMode()) + return; + sTimerLock.Enter(); + TimeEvent *list = elist.GetPtr();; + sTClick = time; + +// sTimerLock.Leave(); +// //*** +// sTimerLock.Enter(); + + TimeEvent *e = list->GetNext(); + while(e != list && ((leftsleep = (e->time - (int)time)) <= 0) && !e->rep) { +// while(e != list && ((int)(time - e->time)) >= 0 && !e->rep) { + TimeEvent *w = e; + e = e->GetNext(); + w->Unlink(); + //eventid++; + Callback cb = w->cb; + if(w->delay < 0) { + w->rep = true; + w->LinkBefore(elist.GetPtr()); + } + else + delete w; + sTimerLock.Leave(); + cb(); + sTimerLock.Enter(); + } + time = GetTickCount(); + e = list->GetPrev(); + while(e != list && e->rep) { + TimeEvent *w = e; + e = e->GetPrev(); + w->Unlink(); + sTimeCallback(time - w->delay, w->delay, w->cb, w->id); + if((-w->delay) < leftsleep) leftsleep = -w->delay; + delete w; + } + sTimerLock.Leave(); + if(leftsleep < 0) leftsleep = granularity; //if last done has been processed and no more in queue, ensure good sleep +} +#endif //SAME API AS IN Ctrl void Timer::SetTimeCallback(int delay_ms, Callback cb, int id) { diff --git a/bazaar/Timer/Timer.h b/bazaar/Timer/Timer.h index 30d8935ca..3c946c810 100644 --- a/bazaar/Timer/Timer.h +++ b/bazaar/Timer/Timer.h @@ -30,6 +30,7 @@ private: int delay; Callback cb; void *id; + bool rep; unsigned GetHashValue() const { return GetPtrHashValue(id); } }; diff --git a/bazaar/TimerTest/main.cpp b/bazaar/TimerTest/main.cpp index be4c336c4..186cfbd65 100644 --- a/bazaar/TimerTest/main.cpp +++ b/bazaar/TimerTest/main.cpp @@ -1,6 +1,7 @@ #include "TimerTest.h" #define REPEAT_TEST +#define TIMEOUT 1000 TimerTest::TimerTest() : demo(0) @@ -11,7 +12,7 @@ TimerTest::TimerTest() ASSERT(a==1); //preload, 1 means running demo mode, 2 means a cb is executing #ifdef REPEAT_TEST - t.SetTimeCallback(-100, THISBACK(Test), (int)this); + t.SetTimeCallback(-TIMEOUT, THISBACK(Test), (int)this); #else t.SetTimeCallback(0, THISBACK(Test), (int)this); #endif @@ -38,7 +39,7 @@ void TimerTest::Test() #ifdef REPEAT_TEST #else - t.SetTimeCallback(100, THISBACK(Test), (int)this); + t.SetTimeCallback(TIMEOUT, THISBACK(Test), (int)this); #endif }