]> git.mxchange.org Git - flightgear.git/blob - src/Time/FGEventMgr.cxx
MSVC fix from Frederic Bouvier
[flightgear.git] / src / Time / FGEventMgr.cxx
1 //
2 // FGEventMgr.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 <config.h>
26 #endif
27
28 #include <simgear/compiler.h>
29 #include <simgear/debug/logstream.hxx>
30
31 #include "FGEventMgr.hxx"
32
33 FGEventMgr::FGEvent::FGEvent()
34     : name_(""),
35       callback_(0),
36       repeat_value_(0),
37       initial_value_(0),
38       ms_to_go_(0),
39       cum_time(0),
40       min_time(100000),
41       max_time(0),
42       count(0)
43 {
44 }
45
46 FGEventMgr::FGEvent::FGEvent( const char* name,
47                               fgCallback* cb,
48                               interval_type repeat_value,
49                               interval_type initial_value )
50     : name_(name),
51       callback_(cb),
52       repeat_value_(repeat_value),
53       initial_value_(initial_value),
54       //ms_to_go_(repeat_value_),
55       cum_time(0),
56       min_time(100000),
57       max_time(0),
58       count(0)
59 {
60     if (initial_value_ < 0)
61     {
62         this->run();
63         ms_to_go_ = repeat_value_;
64     }
65     else
66     {
67         ms_to_go_ = initial_value_;
68     }
69 }
70
71
72 FGEventMgr::FGEvent::~FGEvent()
73 {
74     //delete callback_;
75 }
76
77 void
78 FGEventMgr::FGEvent::run()
79 {
80     SGTimeStamp start_time;
81     SGTimeStamp finish_time;
82
83     start_time.stamp();
84
85     // run the event
86     (*callback_)();
87
88     finish_time.stamp();
89
90     ++count;
91
92     unsigned long duration = finish_time - start_time;
93
94     cum_time += duration;
95
96     if ( duration < min_time ) {
97         min_time = duration;
98     }
99
100     if ( duration > max_time ) {
101         max_time = duration;
102     }
103 }
104
105 void
106 FGEventMgr::FGEvent::print_stats() const
107 {
108     SG_LOG( SG_EVENT, SG_INFO, 
109             "  " << name_
110             << " int=" << repeat_value_ / 1000.0
111             << " cum=" << cum_time
112             << " min=" << min_time
113             << " max=" <<  max_time
114             << " count=" << count
115             << " ave=" << cum_time / (double)count );
116 }
117
118 FGEventMgr::FGEventMgr()
119 {
120 }
121
122 FGEventMgr::~FGEventMgr()
123 {
124 }
125
126 void
127 FGEventMgr::init()
128 {
129     SG_LOG( SG_EVENT, SG_INFO, "Initializing event manager" );
130
131     event_table.clear();
132 }
133
134 void
135 FGEventMgr::bind()
136 {
137 }
138
139 void
140 FGEventMgr::unbind()
141 {
142 }
143
144 void
145 FGEventMgr::update( double dt )
146 {
147     int dt_ms = int(dt * 1000);
148
149     if (dt_ms < 0)
150     {
151         SG_LOG( SG_GENERAL, SG_ALERT,
152                 "FGEventMgr::update() called with negative delta T" );
153         return;
154     }
155
156     int min_value = 0;
157     event_container_type::iterator first = event_table.begin();
158     event_container_type::iterator last = event_table.end();
159     event_container_type::iterator event = event_table.end();
160
161     // Scan all events.  Run one whose interval has expired.
162     while (first != last)
163     {
164         if (first->update( dt_ms ))
165         {
166             if (first->value() < min_value)
167             {
168                 // Select event with largest negative value.
169                 // Its been waiting longest.
170                 min_value = first->value();
171                 event = first;
172             }
173         }
174         ++first;
175     }
176
177     if (event != last)
178     {
179         event->run();
180
181         if (event->repeat_value() > 0)
182         {
183             event->reset();
184         }
185         else
186         {
187             SG_LOG( SG_GENERAL, SG_DEBUG, "Deleting event " << event->name() );
188             event_table.erase( event );
189         }
190     }
191 }
192
193 void
194 FGEventMgr::Register( const FGEvent& event )
195 {
196     event_table.push_back( event );
197
198     SG_LOG( SG_EVENT, SG_INFO, "Registered event " << event.name()
199             << " to run every " << event.repeat_value() << "ms" );
200 }
201
202 void
203 FGEventMgr::print_stats() const
204 {
205     SG_LOG( SG_EVENT, SG_INFO, "" );
206     SG_LOG( SG_EVENT, SG_INFO, "Event Stats" );
207     SG_LOG( SG_EVENT, SG_INFO, "-----------" );
208
209     event_container_type::const_iterator first = event_table.begin();
210     event_container_type::const_iterator last = event_table.end();
211     for (; first != last; ++first)
212     {
213         first->print_stats();
214     }
215
216     SG_LOG( SG_EVENT, SG_INFO, "" );
217 }