Make sure all classes have sensible copy semantics
[libs/core.git] / source / time / timer.h
1 #ifndef MSP_TIME_TIMER_H_
2 #define MSP_TIME_TIMER_H_
3
4 #include <vector>
5 #include <sigc++/sigc++.h>
6 #include <msp/core/mutex.h>
7 #include <msp/core/noncopyable.h>
8 #include <msp/core/semaphore.h>
9 #include "timedelta.h"
10 #include "timestamp.h"
11
12 namespace Msp {
13 namespace Time {
14
15 /**
16 A class for executing functions in a deferred or periodical fashion.  The add a
17 timer, use one of the add functions and connect a functor to the timeout signal
18 of the returned slot.
19
20 This class is thread-safe, to allow running timers in a separate thread.
21 */
22 class Timer: private NonCopyable
23 {
24 public:
25         class Slot
26         {
27         public:
28                 sigc::signal<bool> signal_timeout;
29         
30         private:
31                 TimeDelta interval;
32                 TimeStamp timeout;
33         
34         public:
35                 Slot(const TimeDelta &);
36                 Slot(const TimeStamp &);
37                 const TimeStamp &get_timeout() const { return timeout; }
38                 bool increment();
39         };
40
41 private:
42         struct SlotProxy
43         {
44                 Slot *slot;
45
46                 SlotProxy(Slot *);
47                 bool operator<(const SlotProxy &) const;
48         };
49
50         std::vector<SlotProxy> slots;
51         Semaphore sem;
52         Mutex mutex;
53         bool blocking;
54
55 public:
56         Timer();
57         ~Timer();
58
59         /** Adds a timer that will be executed periodically as long as the timeout
60         signal hander returns true. */
61         Slot &add(const TimeDelta &);
62
63         /** Adds a timer that will be executed once at a specific time.  The return
64         value of the timeout signal handler is ignored. */
65         Slot &add(const TimeStamp &);
66
67         /** Cancels a previously added timer. */
68         void cancel(Slot &);
69
70         /** Deprecated.  Use one of the other overloads. */
71         void tick(bool block);
72
73         /** Waits until a timer expires, then executes it.  If no timers have been
74         set, blocks until one is added from another thread. */
75         void tick();
76
77         /** Waits until a timer expires but at most the specified amount of time.
78         If a timer did expire before the timeout, it is executed. */
79         void tick(const TimeDelta &);
80
81 private:
82         void do_tick(const TimeDelta &);
83
84 public:
85         TimeStamp get_next_timeout() const;
86 };
87
88 } // namespace Time
89 } // namespace Msp
90
91 #endif