1 // event.cxx -- Flight Gear periodic event scheduler
3 // Written by Curtis Olson, started December 1997.
5 // Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
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.
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.
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.
22 // (Log is kept at end of this file)
31 #include "Include/compiler.h"
33 #include STL_ALGORITHM
34 #include STL_FUNCTIONAL
36 #ifdef FG_HAVE_STD_INCLUDES
48 #if defined( HAVE_WINDOWS_H ) && defined(__MWERKS__)
49 # include <windows.h> // For Metrowerks environment
50 # include <winbase.h> // There is no ANSI/MSL time function that
51 // contains milliseconds
54 #include <Debug/logstream.hxx>
58 FG_USING_STD(for_each);
59 FG_USING_STD(mem_fun);
61 fgEVENT_MGR global_events;
64 fgEVENT::fgEVENT( const string& desc,
66 EventState evt_status,
71 interval(evt_interval),
80 fgEVENT::fgEVENT( const fgEVENT& evt )
81 : description(evt.description),
82 event_cb(evt.event_cb),
84 interval(evt.interval),
85 last_run(evt.last_run),
87 next_run(evt.next_run),
88 cum_time(evt.cum_time),
89 min_time(evt.min_time),
90 max_time(evt.max_time),
96 fgEVENT::operator= ( const fgEVENT& evt )
100 description = evt.description;
101 event_cb = evt.event_cb;
103 interval = evt.interval;
104 last_run = evt.last_run;
105 current = evt.current;
106 next_run = evt.next_run;
107 cum_time = evt.cum_time;
108 min_time = evt.min_time;
109 max_time = evt.max_time;
124 FG_LOG(FG_EVENT, FG_INFO, "Running " << description );
126 // record starting time
130 event_cb->call( (void**)NULL );
132 // increment the counter for this event
135 // update the event status
136 status = FG_EVENT_READY;
138 // calculate duration and stats
140 long duration = current - last_run;
142 cum_time += duration;
144 if ( duration < min_time ) {
148 if ( duration > max_time ) {
152 // determine the next absolute run time
153 next_run = last_run + interval;
157 // Dump scheduling stats
159 fgEVENT::PrintStats() const
161 FG_LOG( FG_EVENT, FG_INFO,
163 << " int=" << interval / 1000.0
164 << " cum=" << cum_time
165 << " min=" << min_time
166 << " max=" << max_time
167 << " count=" << count
168 << " ave=" << cum_time / (double)count );
173 fgEVENT_MGR::fgEVENT_MGR( void ) {
177 // Initialize the scheduling subsystem
178 void fgEVENT_MGR::Init( void ) {
179 FG_LOG(FG_EVENT, FG_INFO, "Initializing event manager" );
181 run_queue.erase( run_queue.begin(), run_queue.end() );
182 event_table.erase( event_table.begin(), event_table.end() );
186 // Register an event with the scheduler.
188 fgEVENT_MGR::Register( const string& desc,
189 const fgCallback& cb,
190 fgEVENT::EventState status,
193 // convert interval specified in milleseconds to usec
194 fgEVENT* e = new fgEVENT( desc, cb, status, interval * 1000 );
196 FG_LOG( FG_EVENT, FG_INFO, "Registering event: " << desc );
198 // Actually run the event
201 // Now add to event_table
202 event_table.push_back(e);
206 // Update the scheduling parameters for an event
207 void fgEVENT_MGR::Update( void ) {
211 // Delete a scheduled event
212 void fgEVENT_MGR::Delete( void ) {
216 // Temporarily suspend scheduling of an event
217 void fgEVENT_MGR::Suspend( void ) {
221 // Resume scheduling and event
222 void fgEVENT_MGR::Resume( void ) {
225 // Dump scheduling stats
227 fgEVENT_MGR::PrintStats()
229 FG_LOG( FG_EVENT, FG_INFO, "" );
230 FG_LOG( FG_EVENT, FG_INFO, "Event Stats" );
231 FG_LOG( FG_EVENT, FG_INFO, "-----------" );
233 ConstEventIterator first = event_table.begin();
234 ConstEventIterator last = event_table.end();
235 while ( first != last )
237 (*first)->PrintStats();
240 #if 0 // msvc++ 6.0 barfs at mem_fun()
241 for_each( event_table.begin(),
243 mem_fun( &fgEVENT::PrintStats ) );
245 FG_LOG( FG_EVENT, FG_INFO, "");
249 // Add pending jobs to the run queue and run the job at the front of
251 void fgEVENT_MGR::Process( void ) {
253 FGTimeStamp cur_time;
254 unsigned int i, size;
256 FG_LOG( FG_EVENT, FG_DEBUG, "Processing events" );
258 // get the current time
261 FG_LOG( FG_EVENT, FG_DEBUG,
262 " Current timestamp = " << cur_time.get_seconds() );
264 // printf("Checking if anything is ready to move to the run queue\n");
266 // see if anything else is ready to be placed on the run queue
267 size = event_table.size();
268 // while ( current != last ) {
269 for ( i = 0; i < size; i++ ) {
271 e_ptr = event_table[i];
272 if ( e_ptr->status == fgEVENT::FG_EVENT_READY ) {
273 FG_LOG( FG_EVENT, FG_DEBUG,
274 " Item " << i << " current " << cur_time.get_seconds()
275 << " next run @ " << e_ptr->next_run.get_seconds() );
276 if ( ( e_ptr->next_run - cur_time ) <= 0 ) {
277 run_queue.push_back(e_ptr);
278 e_ptr->status = fgEVENT::FG_EVENT_QUEUED;
283 // Checking to see if there is anything on the run queue
284 // printf("Checking to see if there is anything on the run queue\n");
285 if ( run_queue.size() ) {
286 // printf("Yep, running it\n");
287 e_ptr = run_queue.front();
288 run_queue.pop_front();
295 fgEVENT_MGR::~fgEVENT_MGR( void ) {
296 EventIterator first = event_table.begin();
297 EventIterator last = event_table.end();
298 for ( ; first != last; ++first )
303 run_queue.erase( run_queue.begin(), run_queue.end() );
304 event_table.erase( event_table.begin(), event_table.end() );
309 // Revision 1.17 1999/01/27 04:50:18 curt
310 // Move sun/solaris specific stuff to compiler.h
312 // Revision 1.16 1999/01/21 20:14:18 curt
313 // Sun portability hack.
315 // Revision 1.15 1999/01/09 13:37:42 curt
316 // Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
318 // Revision 1.14 1999/01/07 20:25:32 curt
319 // Portability changes and updates from Bernie Bright.
321 // Revision 1.13 1998/12/04 01:32:46 curt
322 // Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
323 // convenience inline operators.
325 // Revision 1.12 1998/11/23 21:49:07 curt
326 // Borland portability tweaks.
328 // Revision 1.11 1998/11/09 23:41:51 curt
329 // Log message clean ups.
331 // Revision 1.10 1998/11/07 19:07:13 curt
332 // Enable release builds using the --without-logging option to the configure
333 // script. Also a couple log message cleanups, plus some C to C++ comment
336 // Revision 1.9 1998/11/06 21:18:24 curt
337 // Converted to new logstream debugging facility. This allows release
338 // builds with no messages at all (and no performance impact) by using
339 // the -DFG_NDEBUG flag.
341 // Revision 1.8 1998/09/15 02:09:29 curt
342 // Include/fg_callback.hxx
343 // Moved code inline to stop g++ 2.7 from complaining.
345 // Simulator/Time/event.[ch]xx
346 // Changed return type of fgEVENT::printStat(). void caused g++ 2.7 to
347 // complain bitterly.
349 // Minor bugfix and changes.
351 // Simulator/Main/GLUTmain.cxx
352 // Added missing type to idle_state definition - eliminates a warning.
354 // Simulator/Main/fg_init.cxx
355 // Changes to airport lookup.
357 // Simulator/Main/options.cxx
358 // Uses fg_gzifstream when loading config file.
360 // Revision 1.7 1998/08/29 13:11:31 curt
361 // Bernie Bright writes:
362 // I've created some new classes to enable pointers-to-functions and
363 // pointers-to-class-methods to be treated like objects. These objects
364 // can be registered with fgEVENT_MGR.
366 // File "Include/fg_callback.hxx" contains the callback class defns.
368 // Modified fgEVENT and fgEVENT_MGR to use the callback classes. Also
369 // some minor tweaks to STL usage.
371 // Added file "Include/fg_stl_config.h" to deal with STL portability
372 // issues. I've added an initial config for egcs (and probably gcc-2.8.x).
373 // I don't have access to Visual C++ so I've left that for someone else.
374 // This file is influenced by the stl_config.h file delivered with egcs.
376 // Added "Include/auto_ptr.hxx" which contains an implementation of the
377 // STL auto_ptr class which is not provided in all STL implementations
378 // and is needed to use the callback classes.
380 // Deleted fgLightUpdate() which was just a wrapper to call
381 // fgLIGHT::Update().
383 // Modified fg_init.cxx to register two method callbacks in place of the
384 // old wrapper functions.
386 // Revision 1.6 1998/08/20 15:12:26 curt
389 // Revision 1.5 1998/06/12 00:59:52 curt
390 // Build only static libraries.
391 // Declare memmove/memset for Sloaris.
392 // Rewrote fg_time.c routine to get LST start seconds to better handle
393 // Solaris, and be easier to port, and understand the GMT vs. local
396 // Revision 1.4 1998/06/05 18:18:12 curt
397 // Incorporated some automake conditionals to try to support mktime() correctly
398 // on a wider variety of platforms.
399 // Added the declaration of memmove needed by the stl which apparently
400 // solaris only defines for cc compilations and not for c++ (__STDC__)
402 // Revision 1.3 1998/05/22 21:14:53 curt
403 // Rewrote event.cxx in C++ as a class using STL for the internal event list
404 // and run queue this removes the arbitrary list sizes and makes things much
405 // more dynamic. Because this is C++-classified we can now have multiple
406 // event_tables if we'd ever want them.
408 // Revision 1.2 1998/04/25 22:06:33 curt
409 // Edited cvs log messages in source files ... bad bad bad!
411 // Revision 1.1 1998/04/24 00:52:26 curt
412 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
414 // Separated out lighting calcs into their own file.
416 // Revision 1.13 1998/04/18 04:14:08 curt
417 // Moved fg_debug.c to it's own library.
419 // Revision 1.12 1998/04/09 18:40:13 curt
420 // We had unified some of the platform disparate time handling code, and
421 // there was a bug in timesum() which calculated a new time stamp based on
422 // the current time stamp + offset. This hosed the periodic event processing
423 // logic because you'd never arrive at the time the event was scheduled for.
424 // Sky updates and lighting changes are handled via this event mechanism so
425 // they never changed ... it is fixed now.
427 // Revision 1.11 1998/04/03 22:12:55 curt
428 // Converting to Gnu autoconf system.
429 // Centralized time handling differences.
431 // Revision 1.10 1998/03/14 00:28:34 curt
432 // replaced a printf() with an fgPrintf().
434 // Revision 1.9 1998/01/31 00:43:44 curt
435 // Added MetroWorks patches from Carmen Volpe.
437 // Revision 1.8 1998/01/27 00:48:05 curt
438 // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
439 // system and commandline/config file processing code.
441 // Revision 1.7 1998/01/19 19:27:19 curt
442 // Merged in make system changes from Bob Kuehne <rpk@sgi.com>
443 // This should simplify things tremendously.
445 // Revision 1.6 1998/01/19 18:40:39 curt
446 // Tons of little changes to clean up the code and to remove fatal errors
447 // when building with the c++ compiler.
449 // Revision 1.5 1998/01/06 01:20:27 curt
450 // Tweaks to help building with MSVC++
452 // Revision 1.4 1997/12/31 17:46:50 curt
453 // Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
455 // Revision 1.3 1997/12/30 22:22:42 curt
456 // Further integration of event manager.
458 // Revision 1.2 1997/12/30 20:47:58 curt
459 // Integrated new event manager with subsystem initializations.
461 // Revision 1.1 1997/12/30 04:19:22 curt