# include <config.h>
#endif
-#include <string.h>
-#include <stdio.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
+#include <string>
+
+#include "Include/compiler.h"
+
+#include STL_ALGORITHM
+#include STL_FUNCTIONAL
+
+#ifdef FG_HAVE_STD_INCLUDES
+# include <cstdio>
+# ifdef HAVE_STDLIB_H
+# include <cstdlib>
+# endif
+#else
+# include <stdio.h>
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
#endif
#if defined( HAVE_WINDOWS_H ) && defined(__MWERKS__)
// contains milliseconds
#endif
-#include <Debug/fg_debug.h>
+#include <Debug/logstream.hxx>
#include "event.hxx"
+FG_USING_STD(for_each);
+FG_USING_STD(mem_fun);
-#ifdef __sun__
-extern "C" {
- extern void *memmove(void *, const void *, size_t);
-}
-#endif
+fgEVENT_MGR global_events;
-fgEVENT_MGR global_events;
+fgEVENT::fgEVENT( const string& desc,
+ const fgCallback& cb,
+ EventState evt_status,
+ int evt_interval )
+ : description(desc),
+ event_cb(cb.clone()),
+ status(evt_status),
+ interval(evt_interval),
+ cum_time(0),
+ min_time(100000),
+ max_time(0),
+ count(0)
+{
+}
+#if 0
+fgEVENT::fgEVENT( const fgEVENT& evt )
+ : description(evt.description),
+ event_cb(evt.event_cb),
+ status(evt.status),
+ interval(evt.interval),
+ last_run(evt.last_run),
+ current(evt.current),
+ next_run(evt.next_run),
+ cum_time(evt.cum_time),
+ min_time(evt.min_time),
+ max_time(evt.max_time),
+ count(evt.count)
+{
+}
-// run a specified event
-static void RunEvent(fgEVENT *e) {
- long duration;
+fgEVENT&
+fgEVENT::operator= ( const fgEVENT& evt )
+{
+ if ( this != &evt )
+ {
+ description = evt.description;
+ event_cb = evt.event_cb;
+ status = evt.status;
+ interval = evt.interval;
+ last_run = evt.last_run;
+ current = evt.current;
+ next_run = evt.next_run;
+ cum_time = evt.cum_time;
+ min_time = evt.min_time;
+ max_time = evt.max_time;
+ count = evt.count;
+ }
+ return *this;
+}
+#endif
- printf("Running %s\n", e->description);
+fgEVENT::~fgEVENT()
+{
+ delete event_cb;
+}
+
+void
+fgEVENT::run()
+{
+ FG_LOG(FG_EVENT, FG_INFO, "Running " << description );
// record starting time
- timestamp(&(e->last_run));
+ last_run.stamp();
// run the event
- (*e->event)();
+ event_cb->call( (void**)NULL );
// increment the counter for this event
- e->count++;
+ count++;
// update the event status
- e->status = FG_EVENT_READY;
+ status = FG_EVENT_READY;
// calculate duration and stats
- timestamp(&(e->current));
- duration = timediff(&(e->last_run), &(e->current));
+ current.stamp();
+ long duration = current - last_run;
- e->cum_time += duration;
+ cum_time += duration;
- if ( duration < e->min_time ) {
- e->min_time = duration;
+ if ( duration < min_time ) {
+ min_time = duration;
}
- if ( duration > e->max_time ) {
- e->max_time = duration;
+ if ( duration > max_time ) {
+ max_time = duration;
}
// determine the next absolute run time
- timesum(&(e->next_run), &(e->last_run), e->interval);
+ next_run = last_run + interval;
}
+// Dump scheduling stats
+int
+fgEVENT::PrintStats() const
+{
+ FG_LOG( FG_EVENT, FG_INFO,
+ " " << description
+ << " int=" << interval / 1000.0
+ << " cum=" << cum_time
+ << " min=" << min_time
+ << " max=" << max_time
+ << " count=" << count
+ << " ave=" << cum_time / (double)count );
+ return 0;
+}
+
// Constructor
fgEVENT_MGR::fgEVENT_MGR( void ) {
}
// Initialize the scheduling subsystem
void fgEVENT_MGR::Init( void ) {
- printf("Initializing event manager\n");
- // clear event table
- while ( event_table.size() ) {
- event_table.pop_front();
- }
+ FG_LOG(FG_EVENT, FG_INFO, "Initializing event manager" );
- // clear run queue
- while ( run_queue.size() ) {
- run_queue.pop_front();
- }
+ run_queue.erase( run_queue.begin(), run_queue.end() );
+ event_table.erase( event_table.begin(), event_table.end() );
}
-// Register an event with the scheduler
-void fgEVENT_MGR::Register(char *desc, void (*event)( void ), int status,
- int interval)
+// Register an event with the scheduler.
+void
+fgEVENT_MGR::Register( const string& desc,
+ const fgCallback& cb,
+ fgEVENT::EventState status,
+ int interval )
{
- fgEVENT e;
+ // convert interval specified in milleseconds to usec
+ fgEVENT* e = new fgEVENT( desc, cb, status, interval * 1000 );
- printf("Registering event: %s\n", desc);
-
- if ( strlen(desc) < 256 ) {
- strcpy(e.description, desc);
- } else {
- strncpy(e.description, desc, 255);
- e.description[255] = '\0';
- }
-
- e.event = event;
- e.status = status;
- e.interval = interval;
-
- e.cum_time = 0;
- e.min_time = 100000;
- e.max_time = 0;
- e.count = 0;
+ FG_LOG( FG_EVENT, FG_INFO, "Registering event: " << desc );
// Actually run the event
- RunEvent(&e);
+ e->run();
// Now add to event_table
event_table.push_back(e);
void fgEVENT_MGR::Resume( void ) {
}
-
// Dump scheduling stats
-void fgEVENT_MGR::PrintStats( void ) {
- deque < fgEVENT > :: iterator current = event_table.begin();
- deque < fgEVENT > :: iterator last = event_table.end();
- fgEVENT e;
-
- printf("\n");
- printf("Event Stats\n");
- printf("-----------\n");
-
- while ( current != last ) {
- e = *current++;
- printf(" %-20s int=%.2fs cum=%ld min=%ld max=%ld count=%ld ave=%.2f\n",
- e.description,
- e.interval / 1000.0,
- e.cum_time, e.min_time, e.max_time, e.count,
- e.cum_time / (double)e.count);
+void
+fgEVENT_MGR::PrintStats()
+{
+ FG_LOG( FG_EVENT, FG_INFO, "" );
+ FG_LOG( FG_EVENT, FG_INFO, "Event Stats" );
+ FG_LOG( FG_EVENT, FG_INFO, "-----------" );
+
+ ConstEventIterator first = event_table.begin();
+ ConstEventIterator last = event_table.end();
+ while ( first != last )
+ {
+ (*first)->PrintStats();
+ ++first;
}
-
- printf("\n");
+#if 0 // msvc++ 6.0 barfs at mem_fun()
+ for_each( event_table.begin(),
+ event_table.end(),
+ mem_fun( &fgEVENT::PrintStats ) );
+#endif
+ FG_LOG( FG_EVENT, FG_INFO, "");
}
// the queue
void fgEVENT_MGR::Process( void ) {
fgEVENT *e_ptr;
- fg_timestamp cur_time;
+ FGTimeStamp cur_time;
unsigned int i, size;
- fgPrintf(FG_EVENT, FG_DEBUG, "Processing events\n");
+ FG_LOG( FG_EVENT, FG_DEBUG, "Processing events" );
// get the current time
- timestamp(&cur_time);
+ cur_time.stamp();
- fgPrintf( FG_EVENT, FG_DEBUG,
- " Current timestamp = %ld\n", cur_time.seconds);
+ FG_LOG( FG_EVENT, FG_DEBUG,
+ " Current timestamp = " << cur_time.get_seconds() );
// printf("Checking if anything is ready to move to the run queue\n");
// while ( current != last ) {
for ( i = 0; i < size; i++ ) {
// e = *current++;
- e_ptr = &event_table[i];
- if ( e_ptr->status == FG_EVENT_READY ) {
- fgPrintf(FG_EVENT, FG_DEBUG,
- " Item %d, current %d, next run @ %ld\n",
- i, cur_time.seconds, e_ptr->next_run.seconds);
- if ( timediff(&cur_time, &(e_ptr->next_run)) <= 0) {
+ e_ptr = event_table[i];
+ if ( e_ptr->status == fgEVENT::FG_EVENT_READY ) {
+ FG_LOG( FG_EVENT, FG_DEBUG,
+ " Item " << i << " current " << cur_time.get_seconds()
+ << " next run @ " << e_ptr->next_run.get_seconds() );
+ if ( ( e_ptr->next_run - cur_time ) <= 0 ) {
run_queue.push_back(e_ptr);
- e_ptr->status = FG_EVENT_QUEUED;
+ e_ptr->status = fgEVENT::FG_EVENT_QUEUED;
}
}
}
// printf("Yep, running it\n");
e_ptr = run_queue.front();
run_queue.pop_front();
- RunEvent(e_ptr);
+ e_ptr->run();
}
}
// Destructor
fgEVENT_MGR::~fgEVENT_MGR( void ) {
-}
-
+ EventIterator first = event_table.begin();
+ EventIterator last = event_table.end();
+ for ( ; first != last; ++first )
+ {
+ delete (*first);
+ }
-void fgEventPrintStats( void ) {
- global_events.PrintStats();
+ run_queue.erase( run_queue.begin(), run_queue.end() );
+ event_table.erase( event_table.begin(), event_table.end() );
}
// $Log$
+// Revision 1.15 1999/01/09 13:37:42 curt
+// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
+//
+// Revision 1.14 1999/01/07 20:25:32 curt
+// Portability changes and updates from Bernie Bright.
+//
+// Revision 1.13 1998/12/04 01:32:46 curt
+// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
+// convenience inline operators.
+//
+// Revision 1.12 1998/11/23 21:49:07 curt
+// Borland portability tweaks.
+//
+// Revision 1.11 1998/11/09 23:41:51 curt
+// Log message clean ups.
+//
+// Revision 1.10 1998/11/07 19:07:13 curt
+// Enable release builds using the --without-logging option to the configure
+// script. Also a couple log message cleanups, plus some C to C++ comment
+// conversion.
+//
+// Revision 1.9 1998/11/06 21:18:24 curt
+// Converted to new logstream debugging facility. This allows release
+// builds with no messages at all (and no performance impact) by using
+// the -DFG_NDEBUG flag.
+//
+// Revision 1.8 1998/09/15 02:09:29 curt
+// Include/fg_callback.hxx
+// Moved code inline to stop g++ 2.7 from complaining.
+//
+// Simulator/Time/event.[ch]xx
+// Changed return type of fgEVENT::printStat(). void caused g++ 2.7 to
+// complain bitterly.
+//
+// Minor bugfix and changes.
+//
+// Simulator/Main/GLUTmain.cxx
+// Added missing type to idle_state definition - eliminates a warning.
+//
+// Simulator/Main/fg_init.cxx
+// Changes to airport lookup.
+//
+// Simulator/Main/options.cxx
+// Uses fg_gzifstream when loading config file.
+//
+// Revision 1.7 1998/08/29 13:11:31 curt
+// Bernie Bright writes:
+// I've created some new classes to enable pointers-to-functions and
+// pointers-to-class-methods to be treated like objects. These objects
+// can be registered with fgEVENT_MGR.
+//
+// File "Include/fg_callback.hxx" contains the callback class defns.
+//
+// Modified fgEVENT and fgEVENT_MGR to use the callback classes. Also
+// some minor tweaks to STL usage.
+//
+// Added file "Include/fg_stl_config.h" to deal with STL portability
+// issues. I've added an initial config for egcs (and probably gcc-2.8.x).
+// I don't have access to Visual C++ so I've left that for someone else.
+// This file is influenced by the stl_config.h file delivered with egcs.
+//
+// Added "Include/auto_ptr.hxx" which contains an implementation of the
+// STL auto_ptr class which is not provided in all STL implementations
+// and is needed to use the callback classes.
+//
+// Deleted fgLightUpdate() which was just a wrapper to call
+// fgLIGHT::Update().
+//
+// Modified fg_init.cxx to register two method callbacks in place of the
+// old wrapper functions.
+//
+// Revision 1.6 1998/08/20 15:12:26 curt
+// Tweak ...
+//
+// Revision 1.5 1998/06/12 00:59:52 curt
+// Build only static libraries.
+// Declare memmove/memset for Sloaris.
+// Rewrote fg_time.c routine to get LST start seconds to better handle
+// Solaris, and be easier to port, and understand the GMT vs. local
+// timezone issues.
+//
// Revision 1.4 1998/06/05 18:18:12 curt
// Incorporated some automake conditionals to try to support mktime() correctly
// on a wider variety of platforms.