There was an integer overflow in the way elapsed_time_ms. Because the
SGTimeStamp "-" operator returns it's result in usec's, there is an upper bound of 37.8 minutes on the maximum difference this operator can reliably report before the math overflows. I change the global "int elapsed_time_ms" variable to a "double sim_time_ms" and restructured how the value is calculated. ---- The practical result of the overflow bug is that a large negative dt was passed to the event manager and the end effect was that no events would be run until their counters caught up ... in another 37.8 minutes or so.
This commit is contained in:
parent
89324e0cfe
commit
586d767ab6
6 changed files with 21 additions and 23 deletions
|
@ -264,10 +264,10 @@ setAircraftDir (const char * dir)
|
|||
/**
|
||||
* Return the number of milliseconds elapsed since simulation started.
|
||||
*/
|
||||
static long
|
||||
static double
|
||||
getElapsedTime_ms ()
|
||||
{
|
||||
return globals->get_elapsed_time_ms();
|
||||
return globals->get_sim_time_ms();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ FGGlobals *globals;
|
|||
|
||||
// Constructor
|
||||
FGGlobals::FGGlobals() :
|
||||
elapsed_time_ms(0L),
|
||||
sim_time_ms(0.0),
|
||||
#if defined(FX) && defined(XMESA)
|
||||
fullscreen( true ),
|
||||
#endif
|
||||
|
|
|
@ -80,7 +80,7 @@ class FGGlobals
|
|||
private:
|
||||
|
||||
// Number of milliseconds elapsed since the start of the program.
|
||||
long elapsed_time_ms;
|
||||
double sim_time_ms;
|
||||
|
||||
// Root of FlightGear data tree
|
||||
string fg_root;
|
||||
|
@ -174,8 +174,9 @@ public:
|
|||
FGGlobals();
|
||||
~FGGlobals();
|
||||
|
||||
inline long get_elapsed_time_ms () const { return elapsed_time_ms; }
|
||||
inline void set_elapsed_time_ms (long t) { elapsed_time_ms = t; }
|
||||
inline double get_sim_time_ms () const { return sim_time_ms; }
|
||||
inline void inc_sim_time_ms (double dt) { sim_time_ms += dt; }
|
||||
inline void set_sim_time_ms (double t) { sim_time_ms = t; }
|
||||
|
||||
inline const string &get_fg_root () const { return fg_root; }
|
||||
inline void set_fg_root (const string &root) { fg_root = root; }
|
||||
|
|
|
@ -79,11 +79,11 @@ FGLogger::unbind ()
|
|||
void
|
||||
FGLogger::update (int dt)
|
||||
{
|
||||
long elapsed_ms = globals->get_elapsed_time_ms();
|
||||
double sim_time_ms = globals->get_sim_time_ms();
|
||||
for (unsigned int i = 0; i < _logs.size(); i++) {
|
||||
if ((elapsed_ms - _logs[i].last_time_ms) >= _logs[i].interval_ms) {
|
||||
_logs[i].last_time_ms = elapsed_ms;
|
||||
(*_logs[i].output) << globals->get_elapsed_time_ms();
|
||||
if ((sim_time_ms - _logs[i].last_time_ms) >= _logs[i].interval_ms) {
|
||||
_logs[i].last_time_ms = sim_time_ms;
|
||||
(*_logs[i].output) << globals->get_sim_time_ms();
|
||||
for (unsigned int j = 0; j < _logs[i].nodes.size(); j++) {
|
||||
(*_logs[i].output) << _logs[i].delimiter
|
||||
<< _logs[i].nodes[j]->getStringValue();
|
||||
|
@ -102,7 +102,7 @@ FGLogger::update (int dt)
|
|||
FGLogger::Log::Log ()
|
||||
: output(0),
|
||||
interval_ms(0),
|
||||
last_time_ms(-999999L),
|
||||
last_time_ms(-999999.0),
|
||||
delimiter(',')
|
||||
{
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ private:
|
|||
vector<SGPropertyNode *> nodes;
|
||||
ostream * output;
|
||||
long interval_ms;
|
||||
long last_time_ms;
|
||||
double last_time_ms;
|
||||
char delimiter;
|
||||
};
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ ssgSimpleState *default_state;
|
|||
ssgSimpleState *hud_and_panel;
|
||||
ssgSimpleState *menus;
|
||||
|
||||
SGTimeStamp start_time_stamp;
|
||||
SGTimeStamp last_time_stamp;
|
||||
SGTimeStamp current_time_stamp;
|
||||
|
||||
void fgBuildRenderStates( void ) {
|
||||
|
@ -393,10 +393,11 @@ void trRenderFrame( void ) {
|
|||
// Update all Visuals (redraws anything graphics related)
|
||||
void fgRenderFrame( void ) {
|
||||
|
||||
static long old_elapsed_ms = 0;
|
||||
|
||||
int dt_ms = int(globals->get_elapsed_time_ms() - old_elapsed_ms);
|
||||
old_elapsed_ms = globals->get_elapsed_time_ms();
|
||||
// Update the elapsed time.
|
||||
current_time_stamp.stamp();
|
||||
int dt_ms = (current_time_stamp - last_time_stamp) / 1000L;
|
||||
globals->inc_sim_time_ms( dt_ms );
|
||||
last_time_stamp = current_time_stamp;
|
||||
|
||||
// Process/manage pending events
|
||||
global_events.update( dt_ms );
|
||||
|
@ -440,17 +441,13 @@ void fgRenderFrame( void ) {
|
|||
if ( fgGetBool("/sim/startup/splash-screen") ) {
|
||||
fgSplashUpdate(0.0);
|
||||
}
|
||||
start_time_stamp.stamp(); // Keep resetting the start time
|
||||
// Keep resetting sim time while the sim is initializing
|
||||
globals->set_sim_time_ms( 0.0 );
|
||||
} else {
|
||||
// idle_state is now 1000 meaning we've finished all our
|
||||
// initializations and are running the main loop, so this will
|
||||
// now work without seg faulting the system.
|
||||
|
||||
// Update the elapsed time.
|
||||
current_time_stamp.stamp();
|
||||
globals->set_elapsed_time_ms( (current_time_stamp - start_time_stamp)
|
||||
/ 1000L );
|
||||
|
||||
// calculate our current position in cartesian space
|
||||
scenery.set_center( scenery.get_next_center() );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue