00001 #ifndef _SG_EVENT_MGR_HXX
00002 #define _SG_EVENT_MGR_HXX
00003
00004 #include <simgear/props/props.hxx>
00005 #include <simgear/structure/subsystem_mgr.hxx>
00006
00007 #include "callback.hxx"
00008
00009 class SGEventMgr;
00010
00011 struct SGTimer {
00012 double interval;
00013 SGCallback* callback;
00014 SGEventMgr* mgr;
00015 bool repeat;
00016 bool simtime;
00017 void run();
00018 };
00019
00020 class SGTimerQueue {
00021 public:
00022 SGTimerQueue(int preSize=1);
00023 ~SGTimerQueue();
00024
00025 void update(double deltaSecs);
00026
00027 double now() { return _now; }
00028
00029 void insert(SGTimer* timer, double time);
00030 SGTimer* remove(SGTimer* timer);
00031 SGTimer* remove();
00032
00033 SGTimer* nextTimer() { return _numEntries ? _table[0].timer : 0; }
00034 double nextTime() { return -_table[0].pri; }
00035
00036 private:
00037
00038
00039
00040 struct HeapEntry { double pri; SGTimer* timer; };
00041
00042 int parent(int n) { return ((n+1)/2) - 1; }
00043 int lchild(int n) { return ((n+1)*2) - 1; }
00044 int rchild(int n) { return ((n+1)*2 + 1) - 1; }
00045 double pri(int n) { return _table[n].pri; }
00046 void swap(int a, int b) {
00047 HeapEntry tmp = _table[a];
00048 _table[a] = _table[b];
00049 _table[b] = tmp;
00050 }
00051 void siftDown(int n);
00052 void siftUp(int n);
00053 void growArray();
00054
00055
00056
00057
00058 double _now;
00059 HeapEntry *_table;
00060 int _numEntries;
00061 int _tableSize;
00062 };
00063
00064 class SGEventMgr : public SGSubsystem
00065 {
00066 public:
00067 SGEventMgr() { _rtProp = 0; }
00068 ~SGEventMgr() { _rtProp = 0; }
00069
00070 virtual void init() {}
00071 virtual void update(double delta_time_sec);
00072
00073 void setRealtimeProperty(SGPropertyNode* node) { _rtProp = node; }
00074
00079 template<typename FUNC>
00080 inline void addTask(const char* name, const FUNC& f,
00081 double interval, double delay=0, bool sim=false)
00082 { add(make_callback(f), interval, delay, true, sim); }
00083
00088 template<typename FUNC>
00089 inline void addEvent(const char* name, const FUNC& f,
00090 double delay, bool sim=false)
00091 { add(make_callback(f), 0, delay, false, sim); }
00092
00097 template<class OBJ, typename METHOD>
00098 inline void addTask(const char* name,
00099 const OBJ& o, METHOD m,
00100 double interval, double delay=0, bool sim=false)
00101 { add(make_callback(o,m), interval, delay, true, sim); }
00102
00107 template<class OBJ, typename METHOD>
00108 inline void addEvent(const char* name,
00109 const OBJ& o, METHOD m,
00110 double delay, bool sim=false)
00111 { add(make_callback(o,m), 0, delay, false, sim); }
00112
00113 private:
00114 friend struct SGTimer;
00115
00116 void add(SGCallback* cb,
00117 double interval, double delay,
00118 bool repeat, bool simtime);
00119
00120 SGPropertyNode_ptr _freezeProp;
00121 SGPropertyNode_ptr _rtProp;
00122 SGTimerQueue _rtQueue;
00123 SGTimerQueue _simQueue;
00124 };
00125
00126 #endif // _SG_EVENT_MGR_HXX