]> git.mxchange.org Git - flightgear.git/blob - Time/event.cxx
Incorporated some automake conditionals to try to support mktime() correctly
[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 #ifdef __sun__
48 extern "C" {
49   extern void *memmove(void *, const void *, size_t);
50 }
51 #endif
52
53
54 fgEVENT_MGR global_events;
55
56
57 // run a specified event
58 static void RunEvent(fgEVENT *e) {
59     long duration;
60
61     printf("Running %s\n", e->description);
62
63     // record starting time
64     timestamp(&(e->last_run));
65
66     // run the event
67     (*e->event)();
68
69     // increment the counter for this event
70     e->count++;
71
72     // update the event status
73     e->status = FG_EVENT_READY;
74
75     // calculate duration and stats
76     timestamp(&(e->current));
77     duration = timediff(&(e->last_run), &(e->current));
78
79     e->cum_time += duration;
80
81     if ( duration < e->min_time ) {
82         e->min_time = duration;
83     }
84
85     if ( duration > e->max_time ) {
86         e->max_time = duration;
87     }
88
89     // determine the next absolute run time
90     timesum(&(e->next_run), &(e->last_run), e->interval);
91 }
92
93
94 // Constructor
95 fgEVENT_MGR::fgEVENT_MGR( void ) {
96 }
97
98
99 // Initialize the scheduling subsystem
100 void fgEVENT_MGR::Init( void ) {
101     printf("Initializing event manager\n");
102     // clear event table
103     while ( event_table.size() ) {
104         event_table.pop_front();
105     }
106
107     // clear run queue
108     while ( run_queue.size() ) {
109         run_queue.pop_front();
110     }
111 }
112
113
114 // Register an event with the scheduler
115 void fgEVENT_MGR::Register(char *desc, void (*event)( void ), int status, 
116                     int interval)
117 {
118     fgEVENT e;
119
120     printf("Registering event: %s\n", desc);
121
122     if ( strlen(desc) < 256 ) {
123         strcpy(e.description, desc);
124     } else {
125         strncpy(e.description, desc, 255);
126         e.description[255] = '\0';
127     }
128
129     e.event = event;
130     e.status = status;
131     e.interval = interval;
132
133     e.cum_time = 0;
134     e.min_time = 100000;
135     e.max_time = 0;
136     e.count = 0;
137
138     // Actually run the event
139     RunEvent(&e);
140
141     // Now add to event_table
142     event_table.push_back(e);
143 }
144
145
146 // Update the scheduling parameters for an event
147 void fgEVENT_MGR::Update( void ) {
148 }
149
150
151 // Delete a scheduled event
152 void fgEVENT_MGR::Delete( void ) {
153 }
154
155
156 // Temporarily suspend scheduling of an event
157 void fgEVENT_MGR::Suspend( void ) {
158 }
159
160
161 // Resume scheduling and event
162 void fgEVENT_MGR::Resume( void ) {
163 }
164
165
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();
170     fgEVENT e;
171
172     printf("\n");
173     printf("Event Stats\n");
174     printf("-----------\n");
175
176     while ( current != last ) {
177         e = *current++;
178         printf("  %-20s int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n",
179                e.description, 
180                e.interval / 1000.0,
181                e.cum_time, e.min_time, e.max_time, e.count, 
182                e.cum_time / (double)e.count);
183     }
184
185     printf("\n");
186 }
187
188
189 // Add pending jobs to the run queue and run the job at the front of
190 // the queue
191 void fgEVENT_MGR::Process( void ) {
192     fgEVENT *e_ptr;
193     fg_timestamp cur_time;
194     unsigned int i, size;
195
196     fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n");
197     
198     // get the current time
199     timestamp(&cur_time);
200
201     fgPrintf( FG_EVENT, FG_DEBUG, 
202               "  Current timestamp = %ld\n", cur_time.seconds);
203
204     // printf("Checking if anything is ready to move to the run queue\n");
205
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++ ) {
210         // e = *current++;
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;
219             }
220         }
221     }
222
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();
229         RunEvent(e_ptr);
230     }
231 }
232
233
234 // Destructor
235 fgEVENT_MGR::~fgEVENT_MGR( void ) {
236 }
237
238
239 void fgEventPrintStats( void ) {
240     global_events.PrintStats();
241 }
242
243
244 // $Log$
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__)
250 //
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.
256 //
257 // Revision 1.2  1998/04/25 22:06:33  curt
258 // Edited cvs log messages in source files ... bad bad bad!
259 //
260 // Revision 1.1  1998/04/24 00:52:26  curt
261 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
262 // Fog color fixes.
263 // Separated out lighting calcs into their own file.
264 //
265 // Revision 1.13  1998/04/18 04:14:08  curt
266 // Moved fg_debug.c to it's own library.
267 //
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.
275 //
276 // Revision 1.11  1998/04/03 22:12:55  curt
277 // Converting to Gnu autoconf system.
278 // Centralized time handling differences.
279 //
280 // Revision 1.10  1998/03/14 00:28:34  curt
281 // replaced a printf() with an fgPrintf().
282 //
283 // Revision 1.9  1998/01/31 00:43:44  curt
284 // Added MetroWorks patches from Carmen Volpe.
285 //
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.
289 //
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.
293 //
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.
297 //
298 // Revision 1.5  1998/01/06 01:20:27  curt
299 // Tweaks to help building with MSVC++
300 //
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()
303 //
304 // Revision 1.3  1997/12/30 22:22:42  curt
305 // Further integration of event manager.
306 //
307 // Revision 1.2  1997/12/30 20:47:58  curt
308 // Integrated new event manager with subsystem initializations.
309 //
310 // Revision 1.1  1997/12/30 04:19:22  curt
311 // Initial revision.