]> git.mxchange.org Git - simgear.git/blob - simgear/structure/event_mgr.cxx
Fix a problem where the compiler would mix up two function declarations because the...
[simgear.git] / simgear / structure / event_mgr.cxx
1 //
2 // SGEventMgr.cxx -- Event Manager
3 //
4 // Written by Bernie Bright, started April 2002.
5 //
6 // Copyright (C) 2002  Curtis L. Olson  - curt@me.umn.edu
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 //
22 // $Id$
23
24 #ifdef HAVE_CONFIG_H
25 #  include <simgear_config.h>
26 #endif
27
28 #include <simgear/compiler.h>
29
30 #include <simgear/debug/logstream.hxx>
31
32 #include "event_mgr.hxx"
33
34 SGEvent::SGEvent()
35     : _name(""),
36       _callback(0),
37       _subsystem(0),
38       _repeat_value(0),
39       _initial_value(0),
40       _ms_to_go(0),
41       _cum_time(0),
42       _min_time(100000),
43       _max_time(0),
44       _count(0)
45 {
46 }
47
48 SGEvent::SGEvent( const char* name,
49                   SGCallback* cb,
50                   interval_type repeat_value,
51                   interval_type initial_value )
52     : _name(name),
53       _callback(cb),
54       _subsystem(NULL),
55       _repeat_value(repeat_value),
56       _initial_value(initial_value),
57       _cum_time(0),
58       _min_time(100000),
59       _max_time(0),
60       _count(0)
61 {
62     if (_initial_value < 0)
63     {
64         this->run();
65         _ms_to_go = _repeat_value;
66     }
67     else
68     {
69         _ms_to_go = _initial_value;
70     }
71 }
72
73 SGEvent::SGEvent( const char* name,
74                   SGSubsystem* subsystem,
75                   interval_type repeat_value,
76                   interval_type initial_value )
77     : _name(name),
78       _callback(NULL),
79       _subsystem(subsystem),
80       _repeat_value(repeat_value),
81       _initial_value(initial_value),
82       _cum_time(0),
83       _min_time(100000),
84       _max_time(0),
85       _count(0)
86 {
87     if (_initial_value < 0)
88     {
89         this->run();
90         _ms_to_go = _repeat_value;
91     }
92     else
93     {
94         _ms_to_go = _initial_value;
95     }
96 }
97
98
99 SGEvent::~SGEvent()
100 {
101     //delete callback_;
102 }
103
104 void
105 SGEvent::run()
106 {
107     SGTimeStamp start_time;
108     SGTimeStamp finish_time;
109
110     start_time.stamp();
111
112     // run the event
113     if (_callback)
114     {
115         (*_callback)();
116     } else if (_subsystem)
117     {
118         _subsystem->update(_repeat_value);
119     }
120
121     finish_time.stamp();
122
123     ++_count;
124
125     unsigned long duration = finish_time - start_time;
126
127     _cum_time += duration;
128
129     if ( duration < _min_time ) {
130         _min_time = duration;
131     }
132
133     if ( duration > _max_time ) {
134         _max_time = duration;
135     }
136 }
137
138 void
139 SGEvent::print_stats() const
140 {
141     SG_LOG( SG_EVENT, SG_INFO, 
142             "  " << _name
143             << " int=" << _repeat_value / 1000.0
144             << " cum=" << _cum_time
145             << " min=" << _min_time
146             << " max=" <<  _max_time
147             << " count=" << _count
148             << " ave=" << _cum_time / (double)_count );
149 }
150
151
152
153 SGEventMgr::SGEventMgr()
154 {
155 }
156
157 SGEventMgr::~SGEventMgr()
158 {
159 }
160
161 void
162 SGEventMgr::init()
163 {
164     SG_LOG( SG_EVENT, SG_INFO, "Initializing event manager" );
165
166     event_table.clear();
167 }
168
169 void
170 SGEventMgr::reinit()
171 {
172 }
173
174
175 void
176 SGEventMgr::bind()
177 {
178 }
179
180 void
181 SGEventMgr::unbind()
182 {
183 }
184
185 void
186 SGEventMgr::update( double dt )
187 {
188     int dt_ms = int(dt * 1000);
189
190     if (dt_ms < 0)
191     {
192         SG_LOG( SG_GENERAL, SG_ALERT,
193                 "SGEventMgr::update() called with negative delta T" );
194         return;
195     }
196
197     int min_value = 0;
198     event_container_type::iterator first = event_table.begin();
199     event_container_type::iterator last = event_table.end();
200     event_container_type::iterator event = event_table.end();
201
202     // Scan all events.  Run one whose interval has expired.
203     while (first != last)
204     {
205         if (first->update( dt_ms ))
206         {
207             if (first->value() < min_value)
208             {
209                 // Select event with largest negative value.
210                 // Its been waiting longest.
211                 min_value = first->value();
212                 event = first;
213             }
214         }
215         ++first;
216     }
217
218     if (event != last)
219     {
220         event->run();
221
222         if (event->repeat_value() > 0)
223         {
224             event->reset();
225         }
226         else
227         {
228             SG_LOG( SG_GENERAL, SG_DEBUG, "Deleting event " << event->name() );
229             event_table.erase( event );
230         }
231     }
232 }
233
234 void
235 SGEventMgr::add( const SGEvent& event )
236 {
237     event_table.push_back( event );
238
239     SG_LOG( SG_EVENT, SG_INFO, "registered event " << event.name()
240             << " to run every " << event.repeat_value() << "ms" );
241 }
242
243 void
244 SGEventMgr::print_stats() const
245 {
246     SG_LOG( SG_EVENT, SG_INFO, "" );
247     SG_LOG( SG_EVENT, SG_INFO, "Event Stats" );
248     SG_LOG( SG_EVENT, SG_INFO, "-----------" );
249
250     event_container_type::const_iterator first = event_table.begin();
251     event_container_type::const_iterator last = event_table.end();
252     for (; first != last; ++first)
253     {
254         first->print_stats();
255     }
256
257     SG_LOG( SG_EVENT, SG_INFO, "" );
258 }