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 <Debug/fg_debug.h>
49 extern void *memmove(void *, const void *, size_t);
54 fgEVENT_MGR global_events;
57 // run a specified event
58 static void RunEvent(fgEVENT *e) {
61 printf("Running %s\n", e->description);
63 // record starting time
64 timestamp(&(e->last_run));
69 // increment the counter for this event
72 // update the event status
73 e->status = FG_EVENT_READY;
75 // calculate duration and stats
76 timestamp(&(e->current));
77 duration = timediff(&(e->last_run), &(e->current));
79 e->cum_time += duration;
81 if ( duration < e->min_time ) {
82 e->min_time = duration;
85 if ( duration > e->max_time ) {
86 e->max_time = duration;
89 // determine the next absolute run time
90 timesum(&(e->next_run), &(e->last_run), e->interval);
95 fgEVENT_MGR::fgEVENT_MGR( void ) {
99 // Initialize the scheduling subsystem
100 void fgEVENT_MGR::Init( void ) {
101 printf("Initializing event manager\n");
103 while ( event_table.size() ) {
104 event_table.pop_front();
108 while ( run_queue.size() ) {
109 run_queue.pop_front();
114 // Register an event with the scheduler
115 void fgEVENT_MGR::Register(char *desc, void (*event)( void ), int status,
120 printf("Registering event: %s\n", desc);
122 if ( strlen(desc) < 256 ) {
123 strcpy(e.description, desc);
125 strncpy(e.description, desc, 255);
126 e.description[255] = '\0';
131 e.interval = interval;
138 // Actually run the event
141 // Now add to event_table
142 event_table.push_back(e);
146 // Update the scheduling parameters for an event
147 void fgEVENT_MGR::Update( void ) {
151 // Delete a scheduled event
152 void fgEVENT_MGR::Delete( void ) {
156 // Temporarily suspend scheduling of an event
157 void fgEVENT_MGR::Suspend( void ) {
161 // Resume scheduling and event
162 void fgEVENT_MGR::Resume( void ) {
166 // Dump scheduling stats
167 void fgEVENT_MGR::PrintStats( void ) {
168 deque < fgEVENT > :: iterator current = event_table.begin();
169 deque < fgEVENT > :: iterator last = event_table.end();
173 printf("Event Stats\n");
174 printf("-----------\n");
176 while ( current != last ) {
178 printf(" %-20s int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n",
181 e.cum_time, e.min_time, e.max_time, e.count,
182 e.cum_time / (double)e.count);
189 // Add pending jobs to the run queue and run the job at the front of
191 void fgEVENT_MGR::Process( void ) {
193 fg_timestamp cur_time;
194 unsigned int i, size;
196 fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n");
198 // get the current time
199 timestamp(&cur_time);
201 fgPrintf( FG_EVENT, FG_DEBUG,
202 " Current timestamp = %ld\n", cur_time.seconds);
204 // printf("Checking if anything is ready to move to the run queue\n");
206 // see if anything else is ready to be placed on the run queue
207 size = event_table.size();
208 // while ( current != last ) {
209 for ( i = 0; i < size; i++ ) {
211 e_ptr = &event_table[i];
212 if ( e_ptr->status == FG_EVENT_READY ) {
213 fgPrintf(FG_EVENT, FG_DEBUG,
214 " Item %d, current %d, next run @ %ld\n",
215 i, cur_time.seconds, e_ptr->next_run.seconds);
216 if ( timediff(&cur_time, &(e_ptr->next_run)) <= 0) {
217 run_queue.push_back(e_ptr);
218 e_ptr->status = FG_EVENT_QUEUED;
223 // Checking to see if there is anything on the run queue
224 // printf("Checking to see if there is anything on the run queue\n");
225 if ( run_queue.size() ) {
226 // printf("Yep, running it\n");
227 e_ptr = run_queue.front();
228 run_queue.pop_front();
235 fgEVENT_MGR::~fgEVENT_MGR( void ) {
239 void fgEventPrintStats( void ) {
240 global_events.PrintStats();
245 // Revision 1.4 1998/06/05 18:18:12 curt
246 // Incorporated some automake conditionals to try to support mktime() correctly
247 // on a wider variety of platforms.
248 // Added the declaration of memmove needed by the stl which apparently
249 // solaris only defines for cc compilations and not for c++ (__STDC__)
251 // Revision 1.3 1998/05/22 21:14:53 curt
252 // Rewrote event.cxx in C++ as a class using STL for the internal event list
253 // and run queue this removes the arbitrary list sizes and makes things much
254 // more dynamic. Because this is C++-classified we can now have multiple
255 // event_tables if we'd ever want them.
257 // Revision 1.2 1998/04/25 22:06:33 curt
258 // Edited cvs log messages in source files ... bad bad bad!
260 // Revision 1.1 1998/04/24 00:52:26 curt
261 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
263 // Separated out lighting calcs into their own file.
265 // Revision 1.13 1998/04/18 04:14:08 curt
266 // Moved fg_debug.c to it's own library.
268 // Revision 1.12 1998/04/09 18:40:13 curt
269 // We had unified some of the platform disparate time handling code, and
270 // there was a bug in timesum() which calculated a new time stamp based on
271 // the current time stamp + offset. This hosed the periodic event processing
272 // logic because you'd never arrive at the time the event was scheduled for.
273 // Sky updates and lighting changes are handled via this event mechanism so
274 // they never changed ... it is fixed now.
276 // Revision 1.11 1998/04/03 22:12:55 curt
277 // Converting to Gnu autoconf system.
278 // Centralized time handling differences.
280 // Revision 1.10 1998/03/14 00:28:34 curt
281 // replaced a printf() with an fgPrintf().
283 // Revision 1.9 1998/01/31 00:43:44 curt
284 // Added MetroWorks patches from Carmen Volpe.
286 // Revision 1.8 1998/01/27 00:48:05 curt
287 // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
288 // system and commandline/config file processing code.
290 // Revision 1.7 1998/01/19 19:27:19 curt
291 // Merged in make system changes from Bob Kuehne <rpk@sgi.com>
292 // This should simplify things tremendously.
294 // Revision 1.6 1998/01/19 18:40:39 curt
295 // Tons of little changes to clean up the code and to remove fatal errors
296 // when building with the c++ compiler.
298 // Revision 1.5 1998/01/06 01:20:27 curt
299 // Tweaks to help building with MSVC++
301 // Revision 1.4 1997/12/31 17:46:50 curt
302 // Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
304 // Revision 1.3 1997/12/30 22:22:42 curt
305 // Further integration of event manager.
307 // Revision 1.2 1997/12/30 20:47:58 curt
308 // Integrated new event manager with subsystem initializations.
310 // Revision 1.1 1997/12/30 04:19:22 curt