mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Timer: First release
git-svn-id: svn://ultimatepp.org/upp/trunk@2099 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
5e292586a5
commit
abaf765ca0
4 changed files with 228 additions and 0 deletions
153
bazaar/Timer/Timer.cpp
Normal file
153
bazaar/Timer/Timer.cpp
Normal 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
63
bazaar/Timer/Timer.h
Normal 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
8
bazaar/Timer/Timer.upp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
Timer.h,
|
||||
Timer.cpp;
|
||||
|
||||
|
||||
4
bazaar/Timer/init
Normal file
4
bazaar/Timer/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _Timer_icpp_init_stub
|
||||
#define _Timer_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue