Merge branch 'release-2.140.101'
[feisty_meow.git] / nucleus / library / timely / timer_driver.h
1 #ifndef TIMER_DRIVER_CLASS
2 #define TIMER_DRIVER_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : timer_driver                                                      *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 2003-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 #include <basis/astring.h>
19 #include <basis/definitions.h>
20 #include <basis/mutex.h>
21
22 namespace timely {
23
24 // forward.
25 class driven_objects_list;
26 class signalling_thread;
27
28 //////////////
29
30 //! timeable is the base for objects that can be hooked into timer events.
31
32 class timeable : public virtual basis::root_object
33 {
34 public:
35 ////  virtual ~timeable() {}
36   virtual void handle_timer_callback() = 0;
37     //!< this method is invoked when the timer period elapses for this object.
38 };
39
40 //////////////
41
42 //! Provides platform-independent timer support.
43 /*!
44   Multiple objects can be hooked to the timer to be called when their interval
45   elapses.  The driver allows new timeables to be added as needed.
46
47   NOTE: Only one of the timer_driver objects is allowed per program.
48 */
49
50 class timer_driver : public virtual basis::root_object
51 {
52 public:
53   timer_driver();
54   virtual ~timer_driver();
55
56   DEFINE_CLASS_NAME("timer_driver");
57
58   // main methods for controlling timeables.
59
60   bool set_timer(int duration, timeable *to_invoke);
61     //!< sets a timer to call "to_invoke" every "duration" milliseconds.
62     /*!< if the object "to_invoke" already exists, then its duration is
63     changed. */
64
65   bool zap_timer(timeable *to_drop);
66     //!< removes the timer that was established for "to_drop".
67     /*!< do not zap a timer from its own callback!  that could cause
68     synchronization problems. */
69
70   // internal methods.
71
72 #if defined(_MSC_VER)
73   basis::un_int *real_timer_id();
74     //!< provides the timer id for comparison on windows platforms.
75 #endif
76
77   void handle_system_timer();
78     //!< invoked by the OS timer support and must be called by main thread.
79
80   static timer_driver &global_timer_driver();
81     //!< the first time this is invoked, it creates a program-wide timer driver.
82
83 private:
84   driven_objects_list *_timers;  //!< timer hooked objects.
85   basis::mutex *_lock;  //!< protects list of timers.
86 #if defined(__UNIX__) || defined(__GNU_WINDOWS__)
87   signalling_thread *_prompter;  //!< drives our timers.
88 #else
89   basis::un_int *_real_timer_id;  //!< used for storing window timer handle.
90 #endif
91   bool _in_timer;  //!< true if we're handling the timer right now.
92
93   // these do the low-level system magic required to get a function hooked
94   // to a timer.
95   void hookup_OS_timer(int duration);
96     //!< hooks us into the timer events at the "duration" specified.
97   void reset_OS_timer(int next_hit);
98     //!< changes the root interval to "next_hit".
99     /*!< only that many milliseconds will elapse before the next timer hit. */
100   void unhook_OS_timer();
101     //!< disconnects us from the timer events.
102 };
103
104 //////////////
105
106 #define program_wide_timer() timer_driver::global_timer_driver()
107   //!< provides access to the singleton timer_driver.
108   /*!< no other timer_driver objects should ever be created, since this
109   single one will service all timer needs within the program. */
110
111 } //namespace.
112
113 #endif
114