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)
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
42 #include "Include/fg_stl_config.h"
43 #include STL_ALGORITHM
44 #include STL_FUNCTIONAL
46 #include <Debug/fg_debug.h>
51 fgEVENT_MGR global_events;
54 fgEVENT::fgEVENT( const string& desc,
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)),
75 event_cb(evt.event_cb),
78 interval(evt.interval),
79 last_run(evt.last_run),
81 next_run(evt.next_run),
82 cum_time(evt.cum_time),
83 min_time(evt.min_time),
84 max_time(evt.max_time),
91 // cout << "fgEVENT::~fgEVENT" << endl;
97 printf("Running %s\n", description.c_str() );
99 // record starting time
100 timestamp( &last_run );
103 event_cb->call( (void**)NULL );
105 // increment the counter for this event
108 // update the event status
109 status = FG_EVENT_READY;
111 // calculate duration and stats
112 timestamp( ¤t );
113 long duration = timediff( &last_run, ¤t );
115 cum_time += duration;
117 if ( duration < min_time ) {
121 if ( duration > max_time ) {
125 // determine the next absolute run time
126 timesum( &next_run, &last_run, interval );
130 // Dump scheduling stats
132 fgEVENT::PrintStats() const
134 printf(" %-30s int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n",
137 cum_time, min_time, max_time, count,
138 cum_time / (double)count);
143 fgEVENT_MGR::fgEVENT_MGR( void ) {
147 // Initialize the scheduling subsystem
148 void fgEVENT_MGR::Init( void ) {
149 printf("Initializing event manager\n");
151 run_queue.erase( run_queue.begin(), run_queue.end() );
152 event_table.erase( event_table.begin(), event_table.end() );
156 // Register an event with the scheduler.
158 fgEVENT_MGR::Register( const string& desc,
159 const fgCallback& cb,
160 fgEVENT::EventState status,
163 fgEVENT e( desc, cb, status, interval );
165 printf("Registering event: %s\n", desc.c_str() );
167 // Actually run the event
170 // Now add to event_table
171 event_table.push_back(e);
175 // Update the scheduling parameters for an event
176 void fgEVENT_MGR::Update( void ) {
180 // Delete a scheduled event
181 void fgEVENT_MGR::Delete( void ) {
185 // Temporarily suspend scheduling of an event
186 void fgEVENT_MGR::Suspend( void ) {
190 // Resume scheduling and event
191 void fgEVENT_MGR::Resume( void ) {
195 // Dump scheduling stats
197 fgEVENT_MGR::PrintStats()
200 printf("Event Stats\n");
201 printf("-----------\n");
203 for_each( event_table.begin(),
205 mem_fun_ref( &fgEVENT::PrintStats ));
211 // Add pending jobs to the run queue and run the job at the front of
213 void fgEVENT_MGR::Process( void ) {
215 fg_timestamp cur_time;
216 unsigned int i, size;
218 fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n");
220 // get the current time
221 timestamp(&cur_time);
223 fgPrintf( FG_EVENT, FG_DEBUG,
224 " Current timestamp = %ld\n", cur_time.seconds);
226 // printf("Checking if anything is ready to move to the run queue\n");
228 // see if anything else is ready to be placed on the run queue
229 size = event_table.size();
230 // while ( current != last ) {
231 for ( i = 0; i < size; i++ ) {
233 e_ptr = &event_table[i];
234 if ( e_ptr->status == fgEVENT::FG_EVENT_READY ) {
235 fgPrintf(FG_EVENT, FG_DEBUG,
236 " Item %d, current %d, next run @ %ld\n",
237 i, cur_time.seconds, e_ptr->next_run.seconds);
238 if ( timediff(&cur_time, &(e_ptr->next_run)) <= 0) {
239 run_queue.push_back(e_ptr);
240 e_ptr->status = fgEVENT::FG_EVENT_QUEUED;
245 // Checking to see if there is anything on the run queue
246 // printf("Checking to see if there is anything on the run queue\n");
247 if ( run_queue.size() ) {
248 // printf("Yep, running it\n");
249 e_ptr = run_queue.front();
250 run_queue.pop_front();
257 fgEVENT_MGR::~fgEVENT_MGR( void ) {
262 // Revision 1.7 1998/08/29 13:11:31 curt
263 // Bernie Bright writes:
264 // I've created some new classes to enable pointers-to-functions and
265 // pointers-to-class-methods to be treated like objects. These objects
266 // can be registered with fgEVENT_MGR.
268 // File "Include/fg_callback.hxx" contains the callback class defns.
270 // Modified fgEVENT and fgEVENT_MGR to use the callback classes. Also
271 // some minor tweaks to STL usage.
273 // Added file "Include/fg_stl_config.h" to deal with STL portability
274 // issues. I've added an initial config for egcs (and probably gcc-2.8.x).
275 // I don't have access to Visual C++ so I've left that for someone else.
276 // This file is influenced by the stl_config.h file delivered with egcs.
278 // Added "Include/auto_ptr.hxx" which contains an implementation of the
279 // STL auto_ptr class which is not provided in all STL implementations
280 // and is needed to use the callback classes.
282 // Deleted fgLightUpdate() which was just a wrapper to call
283 // fgLIGHT::Update().
285 // Modified fg_init.cxx to register two method callbacks in place of the
286 // old wrapper functions.
288 // Revision 1.6 1998/08/20 15:12:26 curt
291 // Revision 1.5 1998/06/12 00:59:52 curt
292 // Build only static libraries.
293 // Declare memmove/memset for Sloaris.
294 // Rewrote fg_time.c routine to get LST start seconds to better handle
295 // Solaris, and be easier to port, and understand the GMT vs. local
298 // Revision 1.4 1998/06/05 18:18:12 curt
299 // Incorporated some automake conditionals to try to support mktime() correctly
300 // on a wider variety of platforms.
301 // Added the declaration of memmove needed by the stl which apparently
302 // solaris only defines for cc compilations and not for c++ (__STDC__)
304 // Revision 1.3 1998/05/22 21:14:53 curt
305 // Rewrote event.cxx in C++ as a class using STL for the internal event list
306 // and run queue this removes the arbitrary list sizes and makes things much
307 // more dynamic. Because this is C++-classified we can now have multiple
308 // event_tables if we'd ever want them.
310 // Revision 1.2 1998/04/25 22:06:33 curt
311 // Edited cvs log messages in source files ... bad bad bad!
313 // Revision 1.1 1998/04/24 00:52:26 curt
314 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
316 // Separated out lighting calcs into their own file.
318 // Revision 1.13 1998/04/18 04:14:08 curt
319 // Moved fg_debug.c to it's own library.
321 // Revision 1.12 1998/04/09 18:40:13 curt
322 // We had unified some of the platform disparate time handling code, and
323 // there was a bug in timesum() which calculated a new time stamp based on
324 // the current time stamp + offset. This hosed the periodic event processing
325 // logic because you'd never arrive at the time the event was scheduled for.
326 // Sky updates and lighting changes are handled via this event mechanism so
327 // they never changed ... it is fixed now.
329 // Revision 1.11 1998/04/03 22:12:55 curt
330 // Converting to Gnu autoconf system.
331 // Centralized time handling differences.
333 // Revision 1.10 1998/03/14 00:28:34 curt
334 // replaced a printf() with an fgPrintf().
336 // Revision 1.9 1998/01/31 00:43:44 curt
337 // Added MetroWorks patches from Carmen Volpe.
339 // Revision 1.8 1998/01/27 00:48:05 curt
340 // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
341 // system and commandline/config file processing code.
343 // Revision 1.7 1998/01/19 19:27:19 curt
344 // Merged in make system changes from Bob Kuehne <rpk@sgi.com>
345 // This should simplify things tremendously.
347 // Revision 1.6 1998/01/19 18:40:39 curt
348 // Tons of little changes to clean up the code and to remove fatal errors
349 // when building with the c++ compiler.
351 // Revision 1.5 1998/01/06 01:20:27 curt
352 // Tweaks to help building with MSVC++
354 // Revision 1.4 1997/12/31 17:46:50 curt
355 // Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
357 // Revision 1.3 1997/12/30 22:22:42 curt
358 // Further integration of event manager.
360 // Revision 1.2 1997/12/30 20:47:58 curt
361 // Integrated new event manager with subsystem initializations.
363 // Revision 1.1 1997/12/30 04:19:22 curt