]> git.mxchange.org Git - simgear.git/blob - simgear/structure/event_mgr.hxx
A real MSVC fix this time
[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     void check();
55
56     double _now;
57     HeapEntry *_table;
58     int _numEntries;
59     int _tableSize;
60 };
61
62 class SGEventMgr : public SGSubsystem
63 {
64 public:
65     SGEventMgr() { _freezeProp = 0; }
66
67     virtual void init() {}
68     virtual void update(double delta_time_sec);
69
70     void setFreezeProperty(SGPropertyNode* node) { _freezeProp = node; }
71
72     /**
73      * Add a single function callback event as a repeating task.
74      * ex: addTask("foo", &Function ... )
75      */
76     template<typename FUNC>
77     inline void addTask(const char* name, const FUNC& f,
78                         double interval, double delay=0, bool sim=false)
79     { add(make_callback(f), interval, delay, true, sim); }
80
81     /**
82      * Add a single function callback event as a one-shot event.
83      * ex: addEvent("foo", &Function ... )
84      */
85     template<typename FUNC>
86     inline void addEvent(const char* name, const FUNC& f,
87                          double delay, bool sim=false)
88     { add(make_callback(f), 0, delay, false, sim); }
89
90     /**
91      * Add a object/method pair as a repeating task.
92      * ex: addTask("foo", &object, &ClassName::Method, ...)
93      */
94     template<class OBJ, typename METHOD>
95     inline void addTask(const char* name,
96                         const OBJ& o, METHOD m,
97                         double interval, double delay=0, bool sim=false)
98     { add(make_callback(o,m), interval, delay, true, sim); }
99
100     /**
101      * Add a object/method pair as a repeating task.
102      * ex: addEvent("foo", &object, &ClassName::Method, ...)
103      */
104     template<class OBJ, typename METHOD>
105     inline void addEvent(const char* name,
106                          const OBJ& o, METHOD m,
107                          double delay, bool sim=false)
108     { add(make_callback(o,m), 0, delay, false, sim); }
109
110 private:
111     friend struct SGTimer;
112
113     void add(SGCallback* cb,
114              double interval, double delay,
115              bool repeat, bool simtime);
116
117     SGPropertyNode* _freezeProp;
118     SGTimerQueue _rtQueue; 
119     SGTimerQueue _simQueue;
120 };
121
122 #endif // _SG_EVENT_MGR_HXX