From e0aef846e30d9cda73c4e0e10fb13e2b845db5d7 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 21 Nov 2010 23:43:41 +0000 Subject: [PATCH] Fixing bug #172 - warp handling during pause. --- src/Main/fg_commands.cxx | 12 ++----- src/Main/fg_props.cxx | 57 +++++++++-------------------- src/Main/globals.cxx | 22 ++++++++++-- src/Main/globals.hxx | 18 +++------- src/Time/TimeManager.cxx | 77 +++++++++++++++++++++++++++++----------- src/Time/TimeManager.hxx | 12 +++++-- 6 files changed, 110 insertions(+), 88 deletions(-) diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index 28bf42770..a8c45e999 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -697,8 +697,6 @@ do_timeofday (const SGPropertyNode * arg) = fgGetNode("/position/longitude-deg"); static const SGPropertyNode *latitude = fgGetNode("/position/latitude-deg"); - static const SGPropertyNode *cur_time_override - = fgGetNode("/sim/time/cur-time-override", true); int orig_warp = globals->get_warp(); SGTime *t = globals->get_time_params(); @@ -759,14 +757,10 @@ do_timeofday (const SGPropertyNode * arg) * SGD_DEGREES_TO_RADIANS, 180.0, false ); } - // cout << "warp = " << warp << endl; - globals->set_warp( orig_warp + warp ); - - t->update( longitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, - cur_time_override->getLongValue(), - globals->get_warp() ); + + fgSetInt("/sim/time/warp", orig_warp + warp); + return true; } diff --git a/src/Main/fg_props.cxx b/src/Main/fg_props.cxx index 4d944bfc3..3312889f0 100644 --- a/src/Main/fg_props.cxx +++ b/src/Main/fg_props.cxx @@ -256,7 +256,14 @@ static const char * getDateString () { static char buf[64]; // FIXME - struct tm * t = globals->get_time_params()->getGmt(); + + SGTime * st = globals->get_time_params(); + if (!st) { + buf[0] = 0; + return buf; + } + + struct tm * t = st->getGmt(); sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); @@ -270,9 +277,6 @@ getDateString () static void setDateString (const char * date_string) { - static const SGPropertyNode *cur_time_override - = fgGetNode("/sim/time/cur-time-override", true); - SGTime * st = globals->get_time_params(); struct tm * current_time = st->getGmt(); struct tm new_time; @@ -298,16 +302,13 @@ setDateString (const char * date_string) // values, one way or another. new_time.tm_year -= 1900; new_time.tm_mon -= 1; - // Now, tell flight gear to use // the new time. This was far // too difficult, by the way. long int warp = mktime(&new_time) - mktime(current_time) + globals->get_warp(); - double lon = fgGetDouble("/position/longitude-deg") * SG_DEGREES_TO_RADIANS; - double lat = fgGetDouble("/position/latitude-deg") * SG_DEGREES_TO_RADIANS; - globals->set_warp(warp); - st->update(lon, lat, cur_time_override->getLongValue(), warp); + + fgSetInt("/sim/time/warp", warp); } /** @@ -317,7 +318,13 @@ static const char * getGMTString () { static char buf[16]; - struct tm *t = globals->get_time_params()->getGmt(); + SGTime * st = globals->get_time_params(); + if (!st) { + buf[0] = 0; + return buf; + } + + struct tm *t = st->getGmt(); snprintf(buf, 16, "%.2d:%.2d:%.2d", t->tm_hour, t->tm_min, t->tm_sec); return buf; @@ -367,30 +374,6 @@ getTrackMag () return magtrack; } -static long -getWarp () -{ - return globals->get_warp(); -} - -static void -setWarp (long warp) -{ - globals->set_warp(warp); -} - -static long -getWarpDelta () -{ - return globals->get_warp_delta(); -} - -static void -setWarpDelta (long delta) -{ - globals->set_warp_delta(delta); -} - static bool getWindingCCW () { @@ -515,9 +498,6 @@ FGProperties::bind () fgTie("/environment/magnetic-variation-deg", getMagVar); fgTie("/environment/magnetic-dip-deg", getMagDip); - fgTie("/sim/time/warp", getWarp, setWarp, false); - fgTie("/sim/time/warp-delta", getWarpDelta, setWarpDelta); - // Misc. Temporary junk. fgTie("/sim/temp/winding-ccw", getWindingCCW, setWindingCCW, false); } @@ -545,9 +525,6 @@ FGProperties::unbind () fgUntie("/environment/magnetic-variation-deg"); fgUntie("/environment/magnetic-dip-deg"); - fgUntie("/sim/time/warp"); - fgUntie("/sim/time/warp-delta"); - // Misc. Temporary junk. fgUntie("/sim/temp/winding-ccw"); fgUntie("/sim/temp/full-screen"); diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index aa34a9660..2e72e8276 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -122,8 +122,6 @@ FGGlobals::FGGlobals() : soundmgr( new SGSoundMgr ), sim_time_sec( 0.0 ), fg_root( "" ), - warp( 0 ), - warp_delta( 0 ), time_params( NULL ), ephem( NULL ), mag( NULL ), @@ -401,4 +399,24 @@ FGGlobals::get_current_view () const return viewmgr->get_current_view(); } +long int FGGlobals::get_warp() const +{ + return fgGetInt("/sim/time/warp"); +} + +void FGGlobals::set_warp( long int w ) +{ + fgSetInt("/sim/time/warp", w); +} + +long int FGGlobals::get_warp_delta() const +{ + return fgGetInt("/sim/time/warp-delta"); +} + +void FGGlobals::set_warp_delta( long int d ) +{ + fgSetInt("/sim/time/warp-delta", d); +} + // end of globals.cxx diff --git a/src/Main/globals.hxx b/src/Main/globals.hxx index 097e3acb5..e241b6297 100644 --- a/src/Main/globals.hxx +++ b/src/Main/globals.hxx @@ -104,14 +104,6 @@ private: std::string browser; - // An offset in seconds from the true time. Allows us to adjust - // the effective time of day. - long int warp; - - // How much to change the value of warp each iteration. Allows us - // to make time progress faster than normal (or even run in reverse.) - long int warp_delta; - // Time structure SGTime *time_params; @@ -227,13 +219,11 @@ public: inline const std::string &get_browser () const { return browser; } void set_browser (const std::string &b) { browser = b; } - inline long int get_warp() const { return warp; } - inline void set_warp( long int w ) { warp = w; } - inline void inc_warp( long int w ) { warp += w; } + long int get_warp() const; + void set_warp( long int w ); - inline long int get_warp_delta() const { return warp_delta; } - inline void set_warp_delta( long int d ) { warp_delta = d; } - inline void inc_warp_delta( long int d ) { warp_delta += d; } + long int get_warp_delta() const; + void set_warp_delta( long int d ); inline SGTime *get_time_params() const { return time_params; } inline void set_time_params( SGTime *t ) { time_params = t; } diff --git a/src/Time/TimeManager.cxx b/src/Time/TimeManager.cxx index f28deeaf9..2e2389695 100644 --- a/src/Time/TimeManager.cxx +++ b/src/Time/TimeManager.cxx @@ -58,10 +58,15 @@ void TimeManager::init() _firstUpdate = true; _inited = true; _dtRemainder = 0.0; + _adjustWarpOnUnfreeze = false; _maxDtPerFrame = fgGetNode("/sim/max-simtime-per-frame", true); _clockFreeze = fgGetNode("/sim/freeze/clock", true); _timeOverride = fgGetNode("/sim/time/cur-time-override", true); + _warp = fgGetNode("/sim/time/warp", true); + _warp->addChangeListener(this); + + _warpDelta = fgGetNode("/sim/time/warp-delta", true); _longitudeDeg = fgGetNode("/position/longitude-deg", true); _latitudeDeg = fgGetNode("/position/latitude-deg", true); @@ -70,16 +75,17 @@ void TimeManager::init() zone.append("Timezone"); double lon = _longitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS; double lat = _latitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS; + _impl = new SGTime(lon, lat, zone.str(), _timeOverride->getLongValue()); - globals->set_warp_delta(0); + _warpDelta->setIntValue(0); globals->get_event_mgr()->addTask("updateLocalTime", this, &TimeManager::updateLocalTime, 30*60 ); updateLocalTime(); _impl->update(lon, lat, _timeOverride->getLongValue(), - globals->get_warp()); + _warp->getIntValue()); globals->set_time_params(_impl); // frame/update-rate counters @@ -95,14 +101,38 @@ void TimeManager::postinit() void TimeManager::reinit() { + shutdown(); + init(); + postinit(); +} + +void TimeManager::shutdown() +{ + _warp->removeChangeListener(this); + globals->set_time_params(NULL); delete _impl; _impl = NULL; _inited = false; globals->get_event_mgr()->removeTask("updateLocalTime"); - - init(); - postinit(); +} + +void TimeManager::valueChanged(SGPropertyNode* aProp) +{ + if (aProp == _warp) { + if (_clockFreeze->getBoolValue()) { + // if the warp is changed manually while frozen, don't modify it when + // un-freezing - the user wants to unfreeze with exactly the warp + // they specified. + _adjustWarpOnUnfreeze = false; + } + + double lon = _longitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS; + double lat = _latitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS; + _impl->update(lon, lat, + _timeOverride->getLongValue(), + _warp->getIntValue()); + } } void TimeManager::computeTimeDeltas(double& simDt, double& realDt) @@ -177,25 +207,32 @@ void TimeManager::computeTimeDeltas(double& simDt, double& realDt) void TimeManager::update(double dt) { bool freeze = _clockFreeze->getBoolValue(); + time_t now = time(NULL); + if (freeze) { // clock freeze requested if (_timeOverride->getLongValue() == 0) { - fgSetLong( "/sim/time/cur-time-override", _impl->get_cur_time()); - globals->set_warp(0); + _timeOverride->setLongValue(now); + _adjustWarpOnUnfreeze = true; } } else { // no clock freeze requested if (_lastClockFreeze) { - // clock just unfroze, let's set warp as the difference - // between frozen time and current time so we don't get a - // time jump (and corresponding sky object and lighting - // jump.) - globals->set_warp(_timeOverride->getLongValue() - time(NULL)); - fgSetLong( "/sim/time/cur-time-override", 0 ); + if (_adjustWarpOnUnfreeze) { + // clock just unfroze, let's set warp as the difference + // between frozen time and current time so we don't get a + // time jump (and corresponding sky object and lighting + // jump.) + int adjust = _timeOverride->getLongValue() - now; + SG_LOG(SG_GENERAL, SG_INFO, "adjusting on un-freeze:" << adjust); + _warp->setIntValue(_warp->getIntValue() + adjust); + } + _timeOverride->setLongValue(0); } - if ( globals->get_warp_delta() != 0 ) { - globals->inc_warp( globals->get_warp_delta() ); + int warpDelta = _warpDelta->getIntValue(); + if (warpDelta != 0) { + _warp->setIntValue(_warp->getIntValue() + warpDelta); } } @@ -204,7 +241,7 @@ void TimeManager::update(double dt) double lat = _latitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS; _impl->update(lon, lat, _timeOverride->getLongValue(), - globals->get_warp()); + _warp->getIntValue()); computeFrameRate(); } @@ -304,7 +341,7 @@ void TimeManager::updateLocalTime() void TimeManager::initTimeOffset() { // Handle potential user specified time offsets - int orig_warp = globals->get_warp(); + int orig_warp = _warp->getIntValue(); time_t cur_time = _impl->get_cur_time(); time_t currGMT = sgTimeGetGMT( gmtime(&cur_time) ); time_t systemLocalTime = sgTimeGetGMT( localtime(&cur_time) ); @@ -355,10 +392,8 @@ void TimeManager::initTimeOffset() warp = 0; } - globals->set_warp( orig_warp + warp ); - _impl->update(lon, lat, _timeOverride->getLongValue(), - globals->get_warp() ); + _warp->setIntValue( orig_warp + warp ); SG_LOG( SG_GENERAL, SG_INFO, "After fgInitTimeOffset(): warp = " - << globals->get_warp() ); + << _warp->getIntValue() ); } diff --git a/src/Time/TimeManager.hxx b/src/Time/TimeManager.hxx index c0a89c39a..d0dff8155 100644 --- a/src/Time/TimeManager.hxx +++ b/src/Time/TimeManager.hxx @@ -26,7 +26,7 @@ // forward decls class SGTime; -class TimeManager : public SGSubsystem +class TimeManager : public SGSubsystem, public SGPropertyChangeListener { public: TimeManager(); @@ -36,10 +36,14 @@ public: virtual void init(); virtual void reinit(); virtual void postinit(); + virtual void shutdown(); void update(double dt); +// SGPropertyChangeListener overrides + virtual void valueChanged(SGPropertyNode *); private: + /** * Ensure a consistent update-rate using a combination of * sleep()-ing and busy-waiting. @@ -64,8 +68,12 @@ private: SGPropertyNode_ptr _maxDtPerFrame; SGPropertyNode_ptr _clockFreeze; SGPropertyNode_ptr _timeOverride; + SGPropertyNode_ptr _warp; + SGPropertyNode_ptr _warpDelta; + bool _lastClockFreeze; - + bool _adjustWarpOnUnfreeze; + SGPropertyNode_ptr _longitudeDeg; SGPropertyNode_ptr _latitudeDeg; -- 2.39.5