]> git.mxchange.org Git - flightgear.git/blob - Time/event.cxx
54f077cd13f35a7297f1b2e0a3ac3381fb6e4ebd
[flightgear.git] / Time / event.cxx
1 // event.cxx -- Flight Gear periodic event scheduler
2 //
3 // Written by Curtis Olson, started December 1997.
4 //
5 // Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22 // (Log is kept at end of this file)
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #ifdef HAVE_STDLIB_H
33 #include <stdlib.h>
34 #endif
35
36 #if defined( HAVE_WINDOWS_H ) && defined(__MWERKS__)
37 #  include <windows.h>   // For Metrowerks environment
38 #  include <winbase.h>   // There is no ANSI/MSL time function that
39                          // contains milliseconds
40 #endif
41
42 #include "Include/fg_stl_config.h"
43 #include STL_ALGORITHM
44 #include STL_FUNCTIONAL
45
46 #include <Debug/fg_debug.h>
47
48 #include "event.hxx"
49
50
51 fgEVENT_MGR global_events;
52
53
54 fgEVENT::fgEVENT( const string& desc,
55                   const fgCallback& cb,
56                   EventState _status,
57                   int _interval )
58     : description(desc),
59       event_cb(cb.clone()),
60       status(_status),
61       interval(_interval),
62       cum_time(0),
63       min_time(100000),
64       max_time(0),
65       count(0)
66 {
67 }
68
69 fgEVENT::fgEVENT( const fgEVENT& evt )
70     : description(evt.description),
71 #ifdef _FG_NEED_AUTO_PTR
72       // Ugly - cast away const until proper auto_ptr implementation.
73       event_cb((auto_ptr<fgCallback>&)(evt.event_cb)),
74 #else
75       event_cb(evt.event_cb),
76 #endif
77       status(evt.status),
78       interval(evt.interval),
79       last_run(evt.last_run),
80       current(evt.current),
81       next_run(evt.next_run),
82       cum_time(evt.cum_time),
83       min_time(evt.min_time),
84       max_time(evt.max_time),
85       count(evt.count)
86 {
87 }
88
89 fgEVENT::~fgEVENT()
90 {
91 //     cout << "fgEVENT::~fgEVENT" << endl;
92 }
93
94 void
95 fgEVENT::run()
96 {
97     printf("Running %s\n", description.c_str() );
98
99     // record starting time
100     timestamp( &last_run );
101
102     // run the event
103     event_cb->call( (void**)NULL );
104
105     // increment the counter for this event
106     count++;
107
108     // update the event status
109     status = FG_EVENT_READY;
110
111     // calculate duration and stats
112     timestamp( &current );
113     long duration = timediff( &last_run, &current );
114
115     cum_time += duration;
116
117     if ( duration < min_time ) {
118         min_time = duration;
119     }
120
121     if ( duration > max_time ) {
122         max_time = duration;
123     }
124
125     // determine the next absolute run time
126     timesum( &next_run, &last_run, interval );
127 }
128
129
130 // Dump scheduling stats
131 int
132 fgEVENT::PrintStats() const
133 {
134     printf("  %-30s int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n",
135            description.c_str(), 
136            interval / 1000.0,
137            cum_time, min_time, max_time, count, 
138            cum_time / (double)count);
139     return 0;
140 }
141
142 // Constructor
143 fgEVENT_MGR::fgEVENT_MGR( void ) {
144 }
145
146
147 // Initialize the scheduling subsystem
148 void fgEVENT_MGR::Init( void ) {
149     printf("Initializing event manager\n");
150
151     run_queue.erase( run_queue.begin(), run_queue.end() );
152     event_table.erase( event_table.begin(), event_table.end() );
153 }
154
155
156 // Register an event with the scheduler.
157 void
158 fgEVENT_MGR::Register( const string& desc,
159                        const fgCallback& cb,
160                        fgEVENT::EventState status, 
161                        int interval )
162 {
163     fgEVENT e( desc, cb, status, interval );
164
165     printf("Registering event: %s\n", desc.c_str() );
166
167     // Actually run the event
168     e.run();
169
170     // Now add to event_table
171     event_table.push_back(e);
172 }
173
174
175 // Update the scheduling parameters for an event
176 void fgEVENT_MGR::Update( void ) {
177 }
178
179
180 // Delete a scheduled event
181 void fgEVENT_MGR::Delete( void ) {
182 }
183
184
185 // Temporarily suspend scheduling of an event
186 void fgEVENT_MGR::Suspend( void ) {
187 }
188
189
190 // Resume scheduling and event
191 void fgEVENT_MGR::Resume( void ) {
192 }
193
194 // Dump scheduling stats
195 void
196 fgEVENT_MGR::PrintStats()
197 {
198     printf("\n");
199     printf("Event Stats\n");
200     printf("-----------\n");
201
202     for_each( event_table.begin(),
203               event_table.end(),
204               mem_fun_ref( &fgEVENT::PrintStats ));
205
206     printf("\n");
207 }
208
209
210 // Add pending jobs to the run queue and run the job at the front of
211 // the queue
212 void fgEVENT_MGR::Process( void ) {
213     fgEVENT *e_ptr;
214     fg_timestamp cur_time;
215     unsigned int i, size;
216
217     fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n");
218     
219     // get the current time
220     timestamp(&cur_time);
221
222     fgPrintf( FG_EVENT, FG_DEBUG, 
223               "  Current timestamp = %ld\n", cur_time.seconds);
224
225     // printf("Checking if anything is ready to move to the run queue\n");
226
227     // see if anything else is ready to be placed on the run queue
228     size = event_table.size();
229     // while ( current != last ) {
230     for ( i = 0; i < size; i++ ) {
231         // e = *current++;
232         e_ptr = &event_table[i];
233         if ( e_ptr->status == fgEVENT::FG_EVENT_READY ) {
234             fgPrintf(FG_EVENT, FG_DEBUG, 
235                      "  Item %d, current %d, next run @ %ld\n", 
236                      i, cur_time.seconds, e_ptr->next_run.seconds);
237             if ( timediff(&cur_time, &(e_ptr->next_run)) <= 0) {
238                 run_queue.push_back(e_ptr);
239                 e_ptr->status = fgEVENT::FG_EVENT_QUEUED;
240             }
241         }
242     }
243
244     // Checking to see if there is anything on the run queue
245     // printf("Checking to see if there is anything on the run queue\n");
246     if ( run_queue.size() ) {
247         // printf("Yep, running it\n");
248         e_ptr = run_queue.front();
249         run_queue.pop_front();
250         e_ptr->run();
251     }
252 }
253
254
255 // Destructor
256 fgEVENT_MGR::~fgEVENT_MGR( void ) {
257 }
258
259
260 // $Log$
261 // Revision 1.8  1998/09/15 02:09:29  curt
262 // Include/fg_callback.hxx
263 //   Moved code inline to stop g++ 2.7 from complaining.
264 //
265 // Simulator/Time/event.[ch]xx
266 //   Changed return type of fgEVENT::printStat().  void caused g++ 2.7 to
267 //   complain bitterly.
268 //
269 // Minor bugfix and changes.
270 //
271 // Simulator/Main/GLUTmain.cxx
272 //   Added missing type to idle_state definition - eliminates a warning.
273 //
274 // Simulator/Main/fg_init.cxx
275 //   Changes to airport lookup.
276 //
277 // Simulator/Main/options.cxx
278 //   Uses fg_gzifstream when loading config file.
279 //
280 // Revision 1.7  1998/08/29 13:11:31  curt
281 // Bernie Bright writes:
282 //   I've created some new classes to enable pointers-to-functions and
283 //   pointers-to-class-methods to be treated like objects.  These objects
284 //   can be registered with fgEVENT_MGR.
285 //
286 //   File "Include/fg_callback.hxx" contains the callback class defns.
287 //
288 //   Modified fgEVENT and fgEVENT_MGR to use the callback classes.  Also
289 //   some minor tweaks to STL usage.
290 //
291 //   Added file "Include/fg_stl_config.h" to deal with STL portability
292 //   issues.  I've added an initial config for egcs (and probably gcc-2.8.x).
293 //   I don't have access to Visual C++ so I've left that for someone else.
294 //   This file is influenced by the stl_config.h file delivered with egcs.
295 //
296 //   Added "Include/auto_ptr.hxx" which contains an implementation of the
297 //   STL auto_ptr class which is not provided in all STL implementations
298 //   and is needed to use the callback classes.
299 //
300 //   Deleted fgLightUpdate() which was just a wrapper to call
301 //   fgLIGHT::Update().
302 //
303 //   Modified fg_init.cxx to register two method callbacks in place of the
304 //   old wrapper functions.
305 //
306 // Revision 1.6  1998/08/20 15:12:26  curt
307 // Tweak ...
308 //
309 // Revision 1.5  1998/06/12 00:59:52  curt
310 // Build only static libraries.
311 // Declare memmove/memset for Sloaris.
312 // Rewrote fg_time.c routine to get LST start seconds to better handle
313 //   Solaris, and be easier to port, and understand the GMT vs. local
314 //   timezone issues.
315 //
316 // Revision 1.4  1998/06/05 18:18:12  curt
317 // Incorporated some automake conditionals to try to support mktime() correctly
318 // on a wider variety of platforms.
319 // Added the declaration of memmove needed by the stl which apparently
320 // solaris only defines for cc compilations and not for c++ (__STDC__)
321 //
322 // Revision 1.3  1998/05/22 21:14:53  curt
323 // Rewrote event.cxx in C++ as a class using STL for the internal event list
324 // and run queue this removes the arbitrary list sizes and makes things much
325 // more dynamic.  Because this is C++-classified we can now have multiple
326 // event_tables if we'd ever want them.
327 //
328 // Revision 1.2  1998/04/25 22:06:33  curt
329 // Edited cvs log messages in source files ... bad bad bad!
330 //
331 // Revision 1.1  1998/04/24 00:52:26  curt
332 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
333 // Fog color fixes.
334 // Separated out lighting calcs into their own file.
335 //
336 // Revision 1.13  1998/04/18 04:14:08  curt
337 // Moved fg_debug.c to it's own library.
338 //
339 // Revision 1.12  1998/04/09 18:40:13  curt
340 // We had unified some of the platform disparate time handling code, and
341 // there was a bug in timesum() which calculated a new time stamp based on
342 // the current time stamp + offset.  This hosed the periodic event processing
343 // logic because you'd never arrive at the time the event was scheduled for.
344 // Sky updates and lighting changes are handled via this event mechanism so
345 // they never changed ... it is fixed now.
346 //
347 // Revision 1.11  1998/04/03 22:12:55  curt
348 // Converting to Gnu autoconf system.
349 // Centralized time handling differences.
350 //
351 // Revision 1.10  1998/03/14 00:28:34  curt
352 // replaced a printf() with an fgPrintf().
353 //
354 // Revision 1.9  1998/01/31 00:43:44  curt
355 // Added MetroWorks patches from Carmen Volpe.
356 //
357 // Revision 1.8  1998/01/27 00:48:05  curt
358 // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
359 // system and commandline/config file processing code.
360 //
361 // Revision 1.7  1998/01/19 19:27:19  curt
362 // Merged in make system changes from Bob Kuehne <rpk@sgi.com>
363 // This should simplify things tremendously.
364 //
365 // Revision 1.6  1998/01/19 18:40:39  curt
366 // Tons of little changes to clean up the code and to remove fatal errors
367 // when building with the c++ compiler.
368 //
369 // Revision 1.5  1998/01/06 01:20:27  curt
370 // Tweaks to help building with MSVC++
371 //
372 // Revision 1.4  1997/12/31 17:46:50  curt
373 // Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
374 //
375 // Revision 1.3  1997/12/30 22:22:42  curt
376 // Further integration of event manager.
377 //
378 // Revision 1.2  1997/12/30 20:47:58  curt
379 // Integrated new event manager with subsystem initializations.
380 //
381 // Revision 1.1  1997/12/30 04:19:22  curt
382 // Initial revision.