]> git.tdb.fi Git - libs/core.git/blobdiff - source/time/timer.h
Move non-oneliner functions out of RefPtr class declaration
[libs/core.git] / source / time / timer.h
index 369a78c96e089a1e1413fe2a360b241b43b5f2b7..62f248d23a722078472c461b9f04186c6cdd827d 100644 (file)
@@ -1,16 +1,12 @@
-/*
-This file is part of libmspcore     
-Copyright © 2006  Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
 #ifndef MSP_TIME_TIMER_H_
 #define MSP_TIME_TIMER_H_
 
-#include <set>
+#include <vector>
 #include <sigc++/sigc++.h>
-#include "../core/mutex.h"
-#include "../core/semaphore.h"
-#include "../core/thread.h"
+#include <msp/core/attributes.h>
+#include <msp/core/mutex.h>
+#include <msp/core/noncopyable.h>
+#include <msp/core/semaphore.h>
 #include "timedelta.h"
 #include "timestamp.h"
 
@@ -18,58 +14,76 @@ namespace Msp {
 namespace Time {
 
 /**
-A class for executing functions periodically.  Every time the timeout is
-reached, signal_timeout will be emitted.  If the functor connected to this
-signal returns true, the timer is rescheduled by incrementing the timeout
-by the interval.  Otherwise the timer is canceled.
+A class for executing functions in a deferred or periodical fashion.  The add a
+timer, use one of the add functions and connect a functor to the timeout signal
+of the returned slot.
 
-A separate thread is used for running the timers.  All signal emissions will
-happen in this thread - be careful with your variables.
+This class is thread-safe, to allow running timers in a separate thread.
 */
-class Timer
+class Timer: private NonCopyable
 {
 public:
-       sigc::signal<bool> signal_timeout;
-
-       Timer(const Time::TimeDelta &);
-       const Time::TimeStamp &get_timeout() const { return timeout; }
-       ~Timer();
-private:
-       /**
-       A thread to run the timers independently of the rest of the program.
-       */
-       class Thread: public Msp::Thread
+       class Slot
        {
        public:
-               Thread();
-               void nudge();
-               void finish();
+               sigc::signal<bool> signal_timeout;
+       
        private:
-               bool done;
-               Semaphore sem;
-
-               void main();
+               TimeDelta interval;
+               TimeStamp timeout;
+       
+       public:
+               Slot(const TimeDelta &);
+               Slot(const TimeStamp &);
+               const TimeStamp &get_timeout() const { return timeout; }
+               bool increment();
        };
 
-       /**
-       Proxy class to handle automatic starting and termination of the thread.
-       */
-       class ThreadProxy
+private:
+       struct SlotProxy
        {
-       public:
-               ThreadProxy(): thread(0) { }
-               void nudge();
-               ~ThreadProxy();
-       private:
-               Thread *thread;
+               Slot *slot;
+
+               SlotProxy(Slot *);
+               bool operator<(const SlotProxy &) const;
        };
 
-       Time::TimeDelta interval;
-       Time::TimeStamp timeout;
+       std::vector<SlotProxy> slots;
+       Semaphore sem;
+       Mutex mutex;
+       bool blocking;
+
+public:
+       Timer();
+       ~Timer();
+
+       /** Adds a timer that will be executed periodically as long as the timeout
+       signal hander returns true. */
+       Slot &add(const TimeDelta &);
+
+       /** Adds a timer that will be executed once at a specific time.  The return
+       value of the timeout signal handler is ignored. */
+       Slot &add(const TimeStamp &);
+
+       /** Cancels a previously added timer. */
+       void cancel(Slot &);
+
+       /** Deprecated.  Use one of the other overloads. */
+       DEPRECATED void tick(bool block);
 
-       static ThreadProxy thread;
-       static Mutex       set_mutex;
-       static std::set<Timer *> timers;
+       /** Waits until a timer expires, then executes it.  If no timers have been
+       set, blocks until one is added from another thread. */
+       void tick();
+
+       /** Waits until a timer expires but at most the specified amount of time.
+       If a timer did expire before the timeout, it is executed. */
+       void tick(const TimeDelta &);
+
+private:
+       void do_tick(const TimeDelta &);
+
+public:
+       TimeStamp get_next_timeout() const;
 };
 
 } // namespace Time