]> git.mxchange.org Git - simgear.git/blob - simgear/structure/event_mgr.hxx
07c65d5faa9a739869de487d6bc2895541de6d86
[simgear.git] / simgear / structure / event_mgr.hxx
1 #ifndef _SG_EVENT_MGR_HXX
2 #define _SG_EVENT_MGR_HXX
3
4 #include <simgear/props/props.hxx>
5 #include <simgear/structure/subsystem_mgr.hxx>
6
7 #include "callback.hxx"
8
9 class SGEventMgr;
10
11 struct SGTimer {
12     double interval;
13     SGCallback* callback;
14     SGEventMgr* mgr;
15     bool repeat;
16     bool simtime;
17     void run();
18 };
19
20 class SGTimerQueue {
21 public:
22     SGTimerQueue(int preSize=1);
23     ~SGTimerQueue();
24
25     void update(double deltaSecs);
26
27     double now() { return _now; }
28
29     void     insert(SGTimer* timer, double time);
30     SGTimer* remove(SGTimer* timer);
31     SGTimer* remove();
32
33     SGTimer* nextTimer() { return _numEntries ? _table[0].timer : 0; }
34     double   nextTime()  { return -_table[0].pri; }
35
36 private:
37     // The "priority" is stored as a negative time.  This allows the
38     // implemenetation to treat the "top" of the heap as the largest
39     // value and avoids developer mindbugs. ;)
40     struct HeapEntry { double pri; SGTimer* timer; };
41
42     int parent(int n) { return ((n+1)/2) - 1; }
43     int lchild(int n) { return ((n+1)*2) - 1; }
44     int rchild(int n) { return ((n+1)*2 + 1) - 1; }
45     void swap(int a, int b) {
46         HeapEntry tmp = _table[a];
47         _table[a] = _table[b];
48         _table[b] = tmp;
49     }
50     void siftDown(int n);
51     void siftUp(int n);
52     void growArray();
53     void check();
54
55     double _now;
56     HeapEntry *_table;
57     int _numEntries;
58     int _tableSize;
59 };
60
61 class SGEventMgr : public SGSubsystem
62 {
63 public:
64     SGEventMgr() { _freezeProp = 0; }
65
66     virtual void init() {}
67     virtual void update(double delta_time_sec);
68
69     void setFreezeProperty(SGPropertyNode* node) { _freezeProp = node; }
70
71     /**
72      * Add a single function callback event as a repeating task.
73      * ex: addTask("foo", &Function ... )
74      */
75     template<typename FUNC>
76     inline void addTask(const char* name, const FUNC& f,
77                         double interval, double delay=0, bool sim=false)
78     { add(make_callback(f), interval, delay, true, sim); }
79
80     /**
81      * Add a single function callback event as a one-shot event.
82      * ex: addEvent("foo", &Function ... )
83      */
84     template<typename FUNC>
85     inline void addEvent(const char* name, const FUNC& f,
86                          double delay, bool sim=false)
87     { add(make_callback(f), 0, delay, false, sim); }
88
89     /**
90      * Add a object/method pair as a repeating task.
91      * ex: addTask("foo", &object, &ClassName::Method, ...)
92      */
93     template<class OBJ, typename METHOD>
94     inline void addTask(const char* name,
95                         const OBJ& o, METHOD m,
96                         double interval, double delay=0, bool sim=false)
97     { add(make_callback(o,m), interval, delay, true, sim); }
98
99     /**
100      * Add a object/method pair as a repeating task.
101      * ex: addEvent("foo", &object, &ClassName::Method, ...)
102      */
103     template<class OBJ, typename METHOD>
104     inline void addEvent(const char* name,
105                          const OBJ& o, METHOD m,
106                          double delay, bool sim=false)
107     { add(make_callback(o,m), 0, delay, false, sim); }
108
109 private:
110     friend struct SGTimer;
111
112     void add(SGCallback* cb,
113              double interval, double delay,
114              bool repeat, bool simtime);
115
116     SGPropertyNode* _freezeProp;
117     SGTimerQueue _rtQueue; 
118     SGTimerQueue _simQueue;
119 };
120
121 #endif // _SG_EVENT_MGR_HXX