]> git.mxchange.org Git - flightgear.git/blob - Time/event.cxx
Tweak ...
[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 <Debug/fg_debug.h>
43
44 #include "event.hxx"
45
46
47 fgEVENT_MGR global_events;
48
49
50 // run a specified event
51 static void RunEvent(fgEVENT *e) {
52     long duration;
53
54     printf("Running %s\n", e->description);
55
56     // record starting time
57     timestamp(&(e->last_run));
58
59     // run the event
60     (*e->event)();
61
62     // increment the counter for this event
63     e->count++;
64
65     // update the event status
66     e->status = FG_EVENT_READY;
67
68     // calculate duration and stats
69     timestamp(&(e->current));
70     duration = timediff(&(e->last_run), &(e->current));
71
72     e->cum_time += duration;
73
74     if ( duration < e->min_time ) {
75         e->min_time = duration;
76     }
77
78     if ( duration > e->max_time ) {
79         e->max_time = duration;
80     }
81
82     // determine the next absolute run time
83     timesum(&(e->next_run), &(e->last_run), e->interval);
84 }
85
86
87 // Constructor
88 fgEVENT_MGR::fgEVENT_MGR( void ) {
89 }
90
91
92 // Initialize the scheduling subsystem
93 void fgEVENT_MGR::Init( void ) {
94     printf("Initializing event manager\n");
95     // clear event table
96     while ( event_table.size() ) {
97         event_table.pop_front();
98     }
99
100     // clear run queue
101     while ( run_queue.size() ) {
102         run_queue.pop_front();
103     }
104 }
105
106
107 // Register an event with the scheduler
108 void fgEVENT_MGR::Register(char *desc, void (*event)( void ), int status, 
109                     int interval)
110 {
111     fgEVENT e;
112
113     printf("Registering event: %s\n", desc);
114
115     if ( strlen(desc) < 256 ) {
116         strcpy(e.description, desc);
117     } else {
118         strncpy(e.description, desc, 255);
119         e.description[255] = '\0';
120     }
121
122     e.event = event;
123     e.status = status;
124     e.interval = interval;
125
126     e.cum_time = 0;
127     e.min_time = 100000;
128     e.max_time = 0;
129     e.count = 0;
130
131     // Actually run the event
132     RunEvent(&e);
133
134     // Now add to event_table
135     event_table.push_back(e);
136 }
137
138
139 // Update the scheduling parameters for an event
140 void fgEVENT_MGR::Update( void ) {
141 }
142
143
144 // Delete a scheduled event
145 void fgEVENT_MGR::Delete( void ) {
146 }
147
148
149 // Temporarily suspend scheduling of an event
150 void fgEVENT_MGR::Suspend( void ) {
151 }
152
153
154 // Resume scheduling and event
155 void fgEVENT_MGR::Resume( void ) {
156 }
157
158
159 // Dump scheduling stats
160 void fgEVENT_MGR::PrintStats( void ) {
161     deque < fgEVENT > :: iterator current = event_table.begin();
162     deque < fgEVENT > :: iterator last    = event_table.end();
163     fgEVENT e;
164
165     printf("\n");
166     printf("Event Stats\n");
167     printf("-----------\n");
168
169     while ( current != last ) {
170         e = *(current++);
171         printf("  %-20s int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n",
172                e.description, 
173                e.interval / 1000.0,
174                e.cum_time, e.min_time, e.max_time, e.count, 
175                e.cum_time / (double)e.count);
176     }
177
178     printf("\n");
179 }
180
181
182 // Add pending jobs to the run queue and run the job at the front of
183 // the queue
184 void fgEVENT_MGR::Process( void ) {
185     fgEVENT *e_ptr;
186     fg_timestamp cur_time;
187     unsigned int i, size;
188
189     fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n");
190     
191     // get the current time
192     timestamp(&cur_time);
193
194     fgPrintf( FG_EVENT, FG_DEBUG, 
195               "  Current timestamp = %ld\n", cur_time.seconds);
196
197     // printf("Checking if anything is ready to move to the run queue\n");
198
199     // see if anything else is ready to be placed on the run queue
200     size = event_table.size();
201     // while ( current != last ) {
202     for ( i = 0; i < size; i++ ) {
203         // e = *current++;
204         e_ptr = &event_table[i];
205         if ( e_ptr->status == FG_EVENT_READY ) {
206             fgPrintf(FG_EVENT, FG_DEBUG, 
207                      "  Item %d, current %d, next run @ %ld\n", 
208                      i, cur_time.seconds, e_ptr->next_run.seconds);
209             if ( timediff(&cur_time, &(e_ptr->next_run)) <= 0) {
210                 run_queue.push_back(e_ptr);
211                 e_ptr->status = FG_EVENT_QUEUED;
212             }
213         }
214     }
215
216     // Checking to see if there is anything on the run queue
217     // printf("Checking to see if there is anything on the run queue\n");
218     if ( run_queue.size() ) {
219         // printf("Yep, running it\n");
220         e_ptr = run_queue.front();
221         run_queue.pop_front();
222         RunEvent(e_ptr);
223     }
224 }
225
226
227 // Destructor
228 fgEVENT_MGR::~fgEVENT_MGR( void ) {
229 }
230
231
232 void fgEventPrintStats( void ) {
233     global_events.PrintStats();
234 }
235
236
237 // $Log$
238 // Revision 1.6  1998/08/20 15:12:26  curt
239 // Tweak ...
240 //
241 // Revision 1.5  1998/06/12 00:59:52  curt
242 // Build only static libraries.
243 // Declare memmove/memset for Sloaris.
244 // Rewrote fg_time.c routine to get LST start seconds to better handle
245 //   Solaris, and be easier to port, and understand the GMT vs. local
246 //   timezone issues.
247 //
248 // Revision 1.4  1998/06/05 18:18:12  curt
249 // Incorporated some automake conditionals to try to support mktime() correctly
250 // on a wider variety of platforms.
251 // Added the declaration of memmove needed by the stl which apparently
252 // solaris only defines for cc compilations and not for c++ (__STDC__)
253 //
254 // Revision 1.3  1998/05/22 21:14:53  curt
255 // Rewrote event.cxx in C++ as a class using STL for the internal event list
256 // and run queue this removes the arbitrary list sizes and makes things much
257 // more dynamic.  Because this is C++-classified we can now have multiple
258 // event_tables if we'd ever want them.
259 //
260 // Revision 1.2  1998/04/25 22:06:33  curt
261 // Edited cvs log messages in source files ... bad bad bad!
262 //
263 // Revision 1.1  1998/04/24 00:52:26  curt
264 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
265 // Fog color fixes.
266 // Separated out lighting calcs into their own file.
267 //
268 // Revision 1.13  1998/04/18 04:14:08  curt
269 // Moved fg_debug.c to it's own library.
270 //
271 // Revision 1.12  1998/04/09 18:40:13  curt
272 // We had unified some of the platform disparate time handling code, and
273 // there was a bug in timesum() which calculated a new time stamp based on
274 // the current time stamp + offset.  This hosed the periodic event processing
275 // logic because you'd never arrive at the time the event was scheduled for.
276 // Sky updates and lighting changes are handled via this event mechanism so
277 // they never changed ... it is fixed now.
278 //
279 // Revision 1.11  1998/04/03 22:12:55  curt
280 // Converting to Gnu autoconf system.
281 // Centralized time handling differences.
282 //
283 // Revision 1.10  1998/03/14 00:28:34  curt
284 // replaced a printf() with an fgPrintf().
285 //
286 // Revision 1.9  1998/01/31 00:43:44  curt
287 // Added MetroWorks patches from Carmen Volpe.
288 //
289 // Revision 1.8  1998/01/27 00:48:05  curt
290 // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
291 // system and commandline/config file processing code.
292 //
293 // Revision 1.7  1998/01/19 19:27:19  curt
294 // Merged in make system changes from Bob Kuehne <rpk@sgi.com>
295 // This should simplify things tremendously.
296 //
297 // Revision 1.6  1998/01/19 18:40:39  curt
298 // Tons of little changes to clean up the code and to remove fatal errors
299 // when building with the c++ compiler.
300 //
301 // Revision 1.5  1998/01/06 01:20:27  curt
302 // Tweaks to help building with MSVC++
303 //
304 // Revision 1.4  1997/12/31 17:46:50  curt
305 // Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
306 //
307 // Revision 1.3  1997/12/30 22:22:42  curt
308 // Further integration of event manager.
309 //
310 // Revision 1.2  1997/12/30 20:47:58  curt
311 // Integrated new event manager with subsystem initializations.
312 //
313 // Revision 1.1  1997/12/30 04:19:22  curt
314 // Initial revision.