]> git.mxchange.org Git - simgear.git/blob - simgear/structure/event_mgr.hxx
Merge branch 'timoore/clipgroup'
[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     double pri(int n) { return _table[n].pri; }
46     void swap(int a, int b) {
47         HeapEntry tmp = _table[a];
48         _table[a] = _table[b];
49         _table[b] = tmp;
50     }
51     void siftDown(int n);
52     void siftUp(int n);
53     void growArray();
54
55     // gcc complains there is no function specification anywhere.
56     // void check();
57
58     double _now;
59     HeapEntry *_table;
60     int _numEntries;
61     int _tableSize;
62 };
63
64 class SGEventMgr : public SGSubsystem
65 {
66 public:
67     SGEventMgr() { _rtProp = 0; }
68     ~SGEventMgr() { _rtProp = 0; }
69
70     virtual void init() {}
71     virtual void update(double delta_time_sec);
72
73     void setRealtimeProperty(SGPropertyNode* node) { _rtProp = node; }
74
75     /**
76      * Add a single function callback event as a repeating task.
77      * ex: addTask("foo", &Function ... )
78      */
79     template<typename FUNC>
80     inline void addTask(const char* name, const FUNC& f,
81                         double interval, double delay=0, bool sim=false)
82     { add(make_callback(f), interval, delay, true, sim); }
83
84     /**
85      * Add a single function callback event as a one-shot event.
86      * ex: addEvent("foo", &Function ... )
87      */
88     template<typename FUNC>
89     inline void addEvent(const char* name, const FUNC& f,
90                          double delay, bool sim=false)
91     { add(make_callback(f), 0, delay, false, sim); }
92
93     /**
94      * Add a object/method pair as a repeating task.
95      * ex: addTask("foo", &object, &ClassName::Method, ...)
96      */
97     template<class OBJ, typename METHOD>
98     inline void addTask(const char* name,
99                         const OBJ& o, METHOD m,
100                         double interval, double delay=0, bool sim=false)
101     { add(make_callback(o,m), interval, delay, true, sim); }
102
103     /**
104      * Add a object/method pair as a repeating task.
105      * ex: addEvent("foo", &object, &ClassName::Method, ...)
106      */
107     template<class OBJ, typename METHOD>
108     inline void addEvent(const char* name,
109                          const OBJ& o, METHOD m,
110                          double delay, bool sim=false)
111     { add(make_callback(o,m), 0, delay, false, sim); }
112
113 private:
114     friend struct SGTimer;
115
116     void add(SGCallback* cb,
117              double interval, double delay,
118              bool repeat, bool simtime);
119
120     SGPropertyNode_ptr _freezeProp;
121     SGPropertyNode_ptr _rtProp;
122     SGTimerQueue _rtQueue; 
123     SGTimerQueue _simQueue;
124 };
125
126 #endif // _SG_EVENT_MGR_HXX