]> git.mxchange.org Git - simgear.git/blob - simgear/structure/event_mgr.cxx
Yank the MSVC special handling. It turns out it was becuase "strlen"
[simgear.git] / simgear / structure / event_mgr.cxx
1 #include "event_mgr.hxx"
2
3 void SGEventMgr::add(SGCallback* cb,
4                      double interval, double delay,
5                      bool repeat, bool simtime)
6 {
7     SGTimer* t = new SGTimer;
8     t->interval = interval;
9     t->callback = cb;
10     t->mgr = this;
11     t->repeat = repeat;
12     t->simtime = simtime;
13
14     SGTimerQueue* q = simtime ? &_simQueue : &_rtQueue;
15
16     q->insert(t, delay);
17 }
18
19 void SGTimer::run()
20 {
21     (*callback)();
22
23     if(repeat) {
24         SGTimerQueue* q = simtime ? &mgr->_simQueue : &mgr->_rtQueue;
25         q->insert(this, interval);
26     } else {
27         delete callback;
28         delete this;
29     }
30 }
31
32 void SGEventMgr::update(double delta_time_sec)
33 {
34     _rtQueue.update(delta_time_sec);
35     if(!_freezeProp || _freezeProp->getBoolValue() == false)
36         _simQueue.update(delta_time_sec);
37 }
38
39 ////////////////////////////////////////////////////////////////////////
40 // SGTimerQueue
41 // This is the priority queue implementation:
42 ////////////////////////////////////////////////////////////////////////
43
44 SGTimerQueue::SGTimerQueue(int size)
45 {
46     _now = 0;
47     _numEntries = 0;
48     _tableSize = 1;
49     while(size > _tableSize)
50         _tableSize = ((_tableSize + 1)<<1) - 1;
51
52     _table = new HeapEntry[_tableSize];
53     for(int i=0; i<_tableSize; i++) {
54         _table[i].pri = 0;
55         _table[i].timer = 0;
56     }
57 }
58
59
60 SGTimerQueue::~SGTimerQueue()
61 {
62     delete[] _table;
63 }
64
65 void SGTimerQueue::update(double deltaSecs)
66 {
67     _now += deltaSecs;
68     while(_numEntries && nextTime() <= _now) {
69         SGTimer* t = remove();
70         t->run();
71     }
72 }
73
74 void SGTimerQueue::insert(SGTimer* timer, double time)
75 {
76     if(_numEntries >= _tableSize)
77         growArray();
78
79     _numEntries++;
80     _table[_numEntries-1].pri = -(_now + time);
81     _table[_numEntries-1].timer = timer;
82
83     siftUp(_numEntries-1);
84 }
85
86 SGTimer* SGTimerQueue::remove(SGTimer* t)
87 {
88     int entry;
89     for(entry=0; entry<_numEntries; entry++)
90         if(_table[entry].timer == t)
91             break;
92     if(entry == _numEntries)
93         return 0;
94
95     // Swap in the last item in the table, and sift down
96     swap(entry, _numEntries-1);
97     _numEntries--;
98     siftDown(entry);
99
100     return t;
101 }
102
103 SGTimer* SGTimerQueue::remove()
104 {
105     if(_numEntries == 0) {
106         return 0;
107     } else if(_numEntries == 1) {
108         _numEntries = 0;
109         return _table[0].timer;
110     }
111
112     SGTimer *result = _table[0].timer;
113     _table[0] = _table[_numEntries - 1];
114     _numEntries--;
115     siftDown(0);
116     return result;
117 }
118
119 void SGTimerQueue::siftDown(int n)
120 {
121     // While we have children bigger than us, swap us with the biggest
122     // child.
123     while(lchild(n) < _numEntries) {
124         int bigc = lchild(n);
125         if(rchild(n) < _numEntries && pri(rchild(n)) > pri(bigc))
126             bigc = rchild(n);
127         if(pri(bigc) <= pri(n))
128             break;
129         swap(n, bigc);
130         n = bigc;
131     }
132 }
133
134 void SGTimerQueue::siftUp(int n)
135 {
136     while((n != 0) && (_table[n].pri > _table[parent(n)].pri)) {
137         swap(n, parent(n));
138         n = parent(n);
139     }
140     siftDown(n);
141 }
142
143 void SGTimerQueue::growArray()
144 {
145     _tableSize = ((_tableSize+1)<<1) - 1;
146     HeapEntry *newTable = new HeapEntry[_tableSize];
147     for(int i=0; i<_numEntries; i++) {
148         newTable[i].pri  = _table[i].pri;
149         newTable[i].timer = _table[i].timer;
150     }
151     delete[] _table;
152     _table = newTable;
153 }