]> git.tdb.fi Git - libs/core.git/blob - source/time/timer.h
Rewrite Time::Timer to not force the use of a thread, so it's more useful.
[libs/core.git] / source / time / timer.h
1 /*
2 This file is part of libmspcore     
3 Copyright © 2006  Mikko Rasa, Mikkosoft Productions
4 Distributed under the LGPL
5 */
6
7 #ifndef MSP_TIME_TIMER_H_
8 #define MSP_TIME_TIMER_H_
9
10 #include <queue>
11 #include <sigc++/sigc++.h>
12 #include "../core/mutex.h"
13 #include "../core/semaphore.h"
14 #include "timedelta.h"
15 #include "timestamp.h"
16
17 namespace Msp {
18 namespace Time {
19
20 /**
21 A class for executing functions in a deferred or periodical fashion.  The add a
22 timer, use one of the add functions and connect a functor to the timeout signal
23 of the returned slot.
24
25 This class is thread-safe, to allow running timers in a separate thread.
26 */
27 class Timer
28 {
29 public:
30         class Slot
31         {
32         public:
33                 sigc::signal<bool> signal_timeout;
34         
35         private:
36                 TimeDelta interval;
37                 TimeStamp timeout;
38         
39         public:
40                 Slot(const TimeDelta &);
41                 Slot(const TimeStamp &);
42                 const TimeStamp &get_timeout() const { return timeout; }
43                 bool increment();
44                 bool operator<(const Slot &) const;
45         };
46
47 private:
48         typedef bool (*fSlotCompare)(Slot *, Slot *);
49
50         std::priority_queue<Slot *, std::vector<Slot *>, fSlotCompare> slots;
51         Semaphore sem;
52         Mutex mutex;
53
54 public:
55         Timer();
56         ~Timer();
57
58         /**
59         Adds a timer that will be executed periodically as long as the timeout
60         signal hander returns true.
61         */
62         Slot &add(const TimeDelta &);
63
64         /**
65         Adds a timer that will be executed once at a specific time.  The return
66         value of the timeout signal handler is ignored.
67         */
68         Slot &add(const TimeStamp &);
69
70         /**
71         Checks all timers, executing any that have timed out.  If block is true,
72         waits until one times out.
73
74         Note: If there are no active timers when a blocking tick is executed, it
75         won't return until a timer is added from another thread.
76         */
77         void tick(bool block=true);
78 private:
79         static bool slot_compare(Slot *, Slot *);
80 };
81
82 } // namespace Time
83 } // namespace Msp
84
85 #endif