Timer: First release

git-svn-id: svn://ultimatepp.org/upp/trunk@2099 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
koldo 2010-02-19 23:06:12 +00:00
parent 5e292586a5
commit abaf765ca0
4 changed files with 228 additions and 0 deletions

153
bazaar/Timer/Timer.cpp Normal file
View file

@ -0,0 +1,153 @@
#include "Timer.h"
//Timer
Timer::Timer()
{
granularity = 2;
run = true;
t.Run(THISBACK(TimerThread));
}
Timer::~Timer()
{
run = false;
t.Wait();
Mutex::Lock __(sTimerLock);
while(elist.GetNext() != elist.GetPtr())
delete elist.GetNext();
}
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());
TimeEvent *ne = e->InsertPrev();
ne->time = time;
ne->cb = cb;
ne->delay = delay;
ne->id = id;
}
void Timer::SetTimeCallback(int delay_ms, Callback cb, void *id) {
Mutex::Lock __(sTimerLock);
ASSERT(abs(delay_ms) < 0x40000000);
sTimeCallback(GetTickCount() + abs(delay_ms), delay_ms, cb, id);
}
void Timer::KillTimeCallbacks(void *id, void *idlim) {
Mutex::Lock __(sTimerLock);
TimeEvent *list = elist.GetPtr();
for(TimeEvent *e = list->GetNext(); e != list;)
if(e->id >= id && e->id < idlim) {
e = e->GetNext();
delete e->GetPrev();
}
else
e = e->GetNext();
}
void Timer::KillTimeCallbacks(void *id) {
Mutex::Lock __(sTimerLock);
TimeEvent *list = elist.GetPtr();
for(TimeEvent *e = list->GetNext(); e != list;)
if(e->id == id) {
e = e->GetNext();
delete e->GetPrev();
}
else
e = e->GetNext();
}
bool Timer::ExistsTimeCallback(void *id) {
Mutex::Lock __(sTimerLock);
TimeEvent *list = elist.GetPtr();
for(TimeEvent *e = list->GetNext(); e != list; e = e->GetNext())
if(e->id == id)
return true;
return false;
}
void Timer::KillTimeCallback(void *id) {
// KillTimeCallbacks(id, (byte *)id + 1);
KillTimeCallbacks(id);
}
void Timer::TimerProc(dword time)
{
if(IsPanicMode())
return;
sTimerLock.Enter();
TimeEvent *list = elist.GetPtr();
if(sTClick > time)
for(TimeEvent *e = list->GetNext(); e != list; e = e->GetNext())
if(e->time > 0x80000000)
e->time = 0;
sTClick = time;
// sTimerLock.Leave();
// //***
// sTimerLock.Enter();
while(list->GetNext() != list && list->GetNext()->time < time) {
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();
delete e;
}
sTimerLock.Leave();
}
//SAME API AS IN Ctrl
void Timer::SetTimeCallback(int delay_ms, Callback cb, int id) {
// ASSERT(id >= 0 && (size_t)id < (int)sizeof(Timer));
// SetTimeCallback(delay_ms, cb, (byte *)this + id);
SetTimeCallback(delay_ms, cb, (byte *)id);
}
void Timer::KillTimeCallback(int id) {
// ASSERT(id >= 0 && (size_t)id < sizeof(Timer));
// KillTimeCallback((byte *)this + id);
KillTimeCallback((byte *)id);
}
void Timer::KillSetTimeCallback(int delay_ms, Callback cb, int id)
{
KillTimeCallback(id);
SetTimeCallback(delay_ms, cb, id);
}
void Timer::PostCallback(Callback cb, int id)
{
SetTimeCallback(0, cb, id);
}
void Timer::KillPostCallback(Callback cb, int id)
{
KillSetTimeCallback(0, cb, id);
}
bool Timer::ExistsTimeCallback(int id) {
// ASSERT(id >= 0 && (size_t)id < sizeof(Timer));
// return ExistsTimeCallback((byte *)this + id);
return ExistsTimeCallback((byte *)id);
}
void Timer::SetTimerGranularity(int ms)
{
if(ms > 0)
granularity = ms;
}
///
void Timer::TimerThread()
{
while(run)
{
TimerProc(GetTickCount());
Sleep(granularity); //granularity
}
}

63
bazaar/Timer/Timer.h Normal file
View file

@ -0,0 +1,63 @@
#ifndef _Timer_Timer_h_
#define _Timer_Timer_h_
#include <Core/Core.h>
using namespace Upp;
//runs a chained list of TimerEvent stored Callbacks after sleeping
class Timer
{
public:
typedef Timer CLASSNAME;
Timer();
virtual ~Timer();
//API just as in Ctrl
public:
void SetTimeCallback(int delay_ms, Callback cb, int id = 0);
void KillTimeCallback(int id = 0);
void KillSetTimeCallback(int delay_ms, Callback cb, int id);
bool ExistsTimeCallback(int id = 0);
void PostCallback(Callback cb, int id = 0);
void KillPostCallback(Callback cb, int id);
void SetTimerGranularity(int ms);
private:
struct TimeEvent : public Link<TimeEvent> {
dword time;
int delay;
Callback cb;
void *id;
unsigned GetHashValue() const { return GetPtrHashValue(id); }
};
void sTimeCallback(dword time, int delay, Callback cb, void *id);
void SetTimeCallback(int delay_ms, Callback cb, void *id);
void KillTimeCallbacks(void *id, void *idlim);
bool ExistsTimeCallback(void *id);
void KillTimeCallback(void *id);
void TimerProc(dword time);
void KillTimeCallbacks(void *id);
void TimerThread();
//DATA
private:
Thread t;
bool run;
int granularity;
Mutex sTimerLock;
dword sTClick;
LinkOwner<TimeEvent> elist; //elements
//ArrayMap<unsigned, TimeEvent*> emap;
//LinkOwner<TimeEvent> flist; //unused elements for reuse
};
#endif

8
bazaar/Timer/Timer.upp Normal file
View file

@ -0,0 +1,8 @@
uses
Core;
file
Timer.h,
Timer.cpp;

4
bazaar/Timer/init Normal file
View file

@ -0,0 +1,4 @@
#ifndef _Timer_icpp_init_stub
#define _Timer_icpp_init_stub
#include "Core/init"
#endif