]> git.mxchange.org Git - flightgear.git/blob - Time/event.cxx
Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
[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 #if defined( linux ) || defined( __FreeBSD__ )
43 #  define _G_NO_EXTERN_TEMPLATES
44 #endif
45
46 #include "Include/fg_stl_config.h"
47 #include STL_ALGORITHM
48 #include STL_FUNCTIONAL
49
50 #include <Debug/logstream.hxx>
51
52 #include "event.hxx"
53
54
55 fgEVENT_MGR global_events;
56
57
58 fgEVENT::fgEVENT( const string& desc,
59                   const fgCallback& cb,
60                   EventState _status,
61                   int _interval )
62     : description(desc),
63       event_cb(cb.clone()),
64       status(_status),
65       interval(_interval),
66       cum_time(0),
67       min_time(100000),
68       max_time(0),
69       count(0)
70 {
71 }
72
73 fgEVENT::fgEVENT( const fgEVENT& evt )
74     : description(evt.description),
75 #ifdef _FG_NEED_AUTO_PTR
76       // Ugly - cast away const until proper auto_ptr implementation.
77       event_cb((auto_ptr<fgCallback>&)(evt.event_cb)),
78 #else
79       event_cb(evt.event_cb),
80 #endif
81       status(evt.status),
82       interval(evt.interval),
83       last_run(evt.last_run),
84       current(evt.current),
85       next_run(evt.next_run),
86       cum_time(evt.cum_time),
87       min_time(evt.min_time),
88       max_time(evt.max_time),
89       count(evt.count)
90 {
91 }
92
93 fgEVENT::~fgEVENT()
94 {
95 //     cout << "fgEVENT::~fgEVENT" << endl;
96 }
97
98 void
99 fgEVENT::run()
100 {
101     FG_LOG(FG_EVENT, FG_INFO, "Running " << description );
102
103     // record starting time
104     last_run.stamp();
105
106     // run the event
107     event_cb->call( (void**)NULL );
108
109     // increment the counter for this event
110     count++;
111
112     // update the event status
113     status = FG_EVENT_READY;
114
115     // calculate duration and stats
116     current.stamp();
117     long duration = current - last_run;
118
119     cum_time += duration;
120
121     if ( duration < min_time ) {
122         min_time = duration;
123     }
124
125     if ( duration > max_time ) {
126         max_time = duration;
127     }
128
129     // determine the next absolute run time
130     next_run =  last_run + interval;
131 }
132
133
134 // Dump scheduling stats
135 int
136 fgEVENT::PrintStats() const
137 {
138     FG_LOG( FG_EVENT, FG_INFO, 
139             "  " << description 
140             << " int=" << interval / 1000.0
141             << " cum=" << cum_time
142             << " min=" << min_time
143             << " max=" <<  max_time
144             << " count=" << count
145             << " ave=" << cum_time / (double)count );
146     return 0;
147 }
148
149 // Constructor
150 fgEVENT_MGR::fgEVENT_MGR( void ) {
151 }
152
153
154 // Initialize the scheduling subsystem
155 void fgEVENT_MGR::Init( void ) {
156     FG_LOG(FG_EVENT, FG_INFO, "Initializing event manager" );
157
158     run_queue.erase( run_queue.begin(), run_queue.end() );
159     event_table.erase( event_table.begin(), event_table.end() );
160 }
161
162
163 // Register an event with the scheduler.
164 void
165 fgEVENT_MGR::Register( const string& desc,
166                        const fgCallback& cb,
167                        fgEVENT::EventState status, 
168                        int interval )
169 {
170     fgEVENT e( desc, cb, status, interval );
171
172     FG_LOG( FG_EVENT, FG_INFO, "Registering event: " << desc );
173
174     // Actually run the event
175     e.run();
176
177     // Now add to event_table
178     event_table.push_back(e);
179 }
180
181
182 // Update the scheduling parameters for an event
183 void fgEVENT_MGR::Update( void ) {
184 }
185
186
187 // Delete a scheduled event
188 void fgEVENT_MGR::Delete( void ) {
189 }
190
191
192 // Temporarily suspend scheduling of an event
193 void fgEVENT_MGR::Suspend( void ) {
194 }
195
196
197 // Resume scheduling and event
198 void fgEVENT_MGR::Resume( void ) {
199 }
200
201 // Dump scheduling stats
202 void
203 fgEVENT_MGR::PrintStats()
204 {
205     FG_LOG( FG_EVENT, FG_INFO, "" );
206     FG_LOG( FG_EVENT, FG_INFO, "Event Stats" );
207     FG_LOG( FG_EVENT, FG_INFO, "-----------" );
208
209     for_each( event_table.begin(),
210               event_table.end(),
211               mem_fun_ref( &fgEVENT::PrintStats ));
212
213     FG_LOG( FG_EVENT, FG_INFO, "");
214 }
215
216
217 // Add pending jobs to the run queue and run the job at the front of
218 // the queue
219 void fgEVENT_MGR::Process( void ) {
220     fgEVENT *e_ptr;
221     fgTIMESTAMP cur_time;
222     unsigned int i, size;
223
224     FG_LOG( FG_EVENT, FG_DEBUG, "Processing events" );
225     
226     // get the current time
227     cur_time.stamp();
228
229     FG_LOG( FG_EVENT, FG_DEBUG, 
230             "  Current timestamp = " << cur_time.get_seconds() );
231
232     // printf("Checking if anything is ready to move to the run queue\n");
233
234     // see if anything else is ready to be placed on the run queue
235     size = event_table.size();
236     // while ( current != last ) {
237     for ( i = 0; i < size; i++ ) {
238         // e = *current++;
239         e_ptr = &event_table[i];
240         if ( e_ptr->status == fgEVENT::FG_EVENT_READY ) {
241             FG_LOG( FG_EVENT, FG_DEBUG, 
242                     "  Item " << i << " current " << cur_time.get_seconds()
243                     << " next run @ " << e_ptr->next_run.get_seconds() );
244             if ( ( e_ptr->next_run - cur_time ) <= 0 ) {
245                 run_queue.push_back(e_ptr);
246                 e_ptr->status = fgEVENT::FG_EVENT_QUEUED;
247             }
248         }
249     }
250
251     // Checking to see if there is anything on the run queue
252     // printf("Checking to see if there is anything on the run queue\n");
253     if ( run_queue.size() ) {
254         // printf("Yep, running it\n");
255         e_ptr = run_queue.front();
256         run_queue.pop_front();
257         e_ptr->run();
258     }
259 }
260
261
262 // Destructor
263 fgEVENT_MGR::~fgEVENT_MGR( void ) {
264 }
265
266
267 // $Log$
268 // Revision 1.13  1998/12/04 01:32:46  curt
269 // Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
270 // convenience inline operators.
271 //
272 // Revision 1.12  1998/11/23 21:49:07  curt
273 // Borland portability tweaks.
274 //
275 // Revision 1.11  1998/11/09 23:41:51  curt
276 // Log message clean ups.
277 //
278 // Revision 1.10  1998/11/07 19:07:13  curt
279 // Enable release builds using the --without-logging option to the configure
280 // script.  Also a couple log message cleanups, plus some C to C++ comment
281 // conversion.
282 //
283 // Revision 1.9  1998/11/06 21:18:24  curt
284 // Converted to new logstream debugging facility.  This allows release
285 // builds with no messages at all (and no performance impact) by using
286 // the -DFG_NDEBUG flag.
287 //
288 // Revision 1.8  1998/09/15 02:09:29  curt
289 // Include/fg_callback.hxx
290 //   Moved code inline to stop g++ 2.7 from complaining.
291 //
292 // Simulator/Time/event.[ch]xx
293 //   Changed return type of fgEVENT::printStat().  void caused g++ 2.7 to
294 //   complain bitterly.
295 //
296 // Minor bugfix and changes.
297 //
298 // Simulator/Main/GLUTmain.cxx
299 //   Added missing type to idle_state definition - eliminates a warning.
300 //
301 // Simulator/Main/fg_init.cxx
302 //   Changes to airport lookup.
303 //
304 // Simulator/Main/options.cxx
305 //   Uses fg_gzifstream when loading config file.
306 //
307 // Revision 1.7  1998/08/29 13:11:31  curt
308 // Bernie Bright writes:
309 //   I've created some new classes to enable pointers-to-functions and
310 //   pointers-to-class-methods to be treated like objects.  These objects
311 //   can be registered with fgEVENT_MGR.
312 //
313 //   File "Include/fg_callback.hxx" contains the callback class defns.
314 //
315 //   Modified fgEVENT and fgEVENT_MGR to use the callback classes.  Also
316 //   some minor tweaks to STL usage.
317 //
318 //   Added file "Include/fg_stl_config.h" to deal with STL portability
319 //   issues.  I've added an initial config for egcs (and probably gcc-2.8.x).
320 //   I don't have access to Visual C++ so I've left that for someone else.
321 //   This file is influenced by the stl_config.h file delivered with egcs.
322 //
323 //   Added "Include/auto_ptr.hxx" which contains an implementation of the
324 //   STL auto_ptr class which is not provided in all STL implementations
325 //   and is needed to use the callback classes.
326 //
327 //   Deleted fgLightUpdate() which was just a wrapper to call
328 //   fgLIGHT::Update().
329 //
330 //   Modified fg_init.cxx to register two method callbacks in place of the
331 //   old wrapper functions.
332 //
333 // Revision 1.6  1998/08/20 15:12:26  curt
334 // Tweak ...
335 //
336 // Revision 1.5  1998/06/12 00:59:52  curt
337 // Build only static libraries.
338 // Declare memmove/memset for Sloaris.
339 // Rewrote fg_time.c routine to get LST start seconds to better handle
340 //   Solaris, and be easier to port, and understand the GMT vs. local
341 //   timezone issues.
342 //
343 // Revision 1.4  1998/06/05 18:18:12  curt
344 // Incorporated some automake conditionals to try to support mktime() correctly
345 // on a wider variety of platforms.
346 // Added the declaration of memmove needed by the stl which apparently
347 // solaris only defines for cc compilations and not for c++ (__STDC__)
348 //
349 // Revision 1.3  1998/05/22 21:14:53  curt
350 // Rewrote event.cxx in C++ as a class using STL for the internal event list
351 // and run queue this removes the arbitrary list sizes and makes things much
352 // more dynamic.  Because this is C++-classified we can now have multiple
353 // event_tables if we'd ever want them.
354 //
355 // Revision 1.2  1998/04/25 22:06:33  curt
356 // Edited cvs log messages in source files ... bad bad bad!
357 //
358 // Revision 1.1  1998/04/24 00:52:26  curt
359 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
360 // Fog color fixes.
361 // Separated out lighting calcs into their own file.
362 //
363 // Revision 1.13  1998/04/18 04:14:08  curt
364 // Moved fg_debug.c to it's own library.
365 //
366 // Revision 1.12  1998/04/09 18:40:13  curt
367 // We had unified some of the platform disparate time handling code, and
368 // there was a bug in timesum() which calculated a new time stamp based on
369 // the current time stamp + offset.  This hosed the periodic event processing
370 // logic because you'd never arrive at the time the event was scheduled for.
371 // Sky updates and lighting changes are handled via this event mechanism so
372 // they never changed ... it is fixed now.
373 //
374 // Revision 1.11  1998/04/03 22:12:55  curt
375 // Converting to Gnu autoconf system.
376 // Centralized time handling differences.
377 //
378 // Revision 1.10  1998/03/14 00:28:34  curt
379 // replaced a printf() with an fgPrintf().
380 //
381 // Revision 1.9  1998/01/31 00:43:44  curt
382 // Added MetroWorks patches from Carmen Volpe.
383 //
384 // Revision 1.8  1998/01/27 00:48:05  curt
385 // Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
386 // system and commandline/config file processing code.
387 //
388 // Revision 1.7  1998/01/19 19:27:19  curt
389 // Merged in make system changes from Bob Kuehne <rpk@sgi.com>
390 // This should simplify things tremendously.
391 //
392 // Revision 1.6  1998/01/19 18:40:39  curt
393 // Tons of little changes to clean up the code and to remove fatal errors
394 // when building with the c++ compiler.
395 //
396 // Revision 1.5  1998/01/06 01:20:27  curt
397 // Tweaks to help building with MSVC++
398 //
399 // Revision 1.4  1997/12/31 17:46:50  curt
400 // Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
401 //
402 // Revision 1.3  1997/12/30 22:22:42  curt
403 // Further integration of event manager.
404 //
405 // Revision 1.2  1997/12/30 20:47:58  curt
406 // Integrated new event manager with subsystem initializations.
407 //
408 // Revision 1.1  1997/12/30 04:19:22  curt
409 // Initial revision.