event_mgr.hxx

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     // The "priority" is stored as a negative time.  This allows the
00038     // implemenetation to treat the "top" of the heap as the largest
00039     // value and avoids developer mindbugs. ;)
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     // gcc complains there is no function specification anywhere.
00056     // void check();
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

Generated on Mon Dec 17 09:30:54 2007 for SimGear by  doxygen 1.5.1