]> git.tdb.fi Git - libs/core.git/blob - source/time/timer.cpp
Make sure all files have the correct header
[libs/core.git] / source / time / timer.cpp
1 /* $Id$
2
3 This file is part of libmspcore     
4 Copyright © 2006  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include "timer.h"
9 #include "utils.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace Time {
15
16 Timer::~Timer()
17 {
18         for(set<SlotProxy>::iterator i=slots.begin(); i!=slots.end(); ++i)
19                 delete i->slot;
20 }
21
22 Timer::Slot &Timer::add(const TimeDelta &td)
23 {
24         Slot *s=new Slot(td);
25         mutex.lock();
26         slots.insert(s);
27         mutex.unlock();
28         sem.signal();
29         return *s;
30 }
31
32 Timer::Slot &Timer::add(const TimeStamp &ts)
33 {
34         Slot *s=new Slot(ts);
35         {
36                 MutexLock l(mutex);
37                 slots.insert(s);
38         }
39         sem.signal();
40         return *s;
41 }
42
43 void Timer::cancel(Slot &slot)
44 {
45         MutexLock l(mutex);
46         if(slots.erase(&slot))
47                 delete &slot;
48 }
49
50 void Timer::tick(bool block)
51 {
52         if(slots.empty())
53         {
54                 if(block)
55                         sem.wait();
56                 else
57                         return;
58         }
59
60         Slot *next;
61         {
62                 MutexLock l(mutex);
63                 next=slots.begin()->slot;
64         }
65
66         const TimeStamp &stamp=next->get_timeout();
67         const TimeStamp t=now();
68         if(stamp<=t || (block && sem.wait(stamp-t)==1))
69         {
70                 slots.erase(slots.begin());
71                 if(next->signal_timeout.emit() && next->increment())
72                         slots.insert(next);
73                 else
74                         delete next;
75         }
76 }
77
78 TimeStamp Timer::get_next_timeout() const
79 {
80         if(slots.empty())
81                 return TimeStamp();
82         return slots.begin()->slot->get_timeout();
83 }
84
85
86 Timer::Slot::Slot(const TimeDelta &td):
87         interval(td),
88         timeout(now()+interval)
89 { }
90
91 Timer::Slot::Slot(const TimeStamp &ts):
92         timeout(ts)
93 { }
94
95 bool Timer::Slot::increment()
96 {
97         if(!interval)
98                 return false;
99         timeout+=interval;
100         return true;
101 }
102
103
104 Timer::SlotProxy::SlotProxy(Slot *s):
105         slot(s)
106 { }
107
108 bool Timer::SlotProxy::operator<(const SlotProxy &sp) const
109 {
110         return slot->get_timeout()<sp.slot->get_timeout();
111 }
112
113 } // namespace Time
114 } // namespace Msp