]> git.mxchange.org Git - flightgear.git/commitdiff
Restructure positional finalisation for sim-reset.
authorJames Turner <zakalawe@mac.com>
Sat, 15 Dec 2012 15:25:45 +0000 (15:25 +0000)
committerJames Turner <zakalawe@mac.com>
Sat, 15 Dec 2012 15:25:45 +0000 (15:25 +0000)
Make position finalisation happen in the same phase as scenery load, i.e as a task during the main loop, instead of during the init loop. This is compatible with the existing reset logic. Unfortunately more work is needed; the environment code doesn't update the local station quickly enough on reset. (Fixing that is next!)

src/Main/fg_init.cxx
src/Main/main.cxx
src/Main/positioninit.cxx
src/Main/positioninit.hxx
src/Scenery/tilemgr.cxx
src/Viewer/renderer.cxx
src/Viewer/renderer.hxx

index 86fa6f0971f7a84a0b617394859f5d1cda5eb070..96e13809254aa3ae35fb1c88b2be1c09f968bc90 100644 (file)
@@ -798,6 +798,8 @@ void fgReInitSubsystems()
     globals->restoreInitialState();
 
     // update our position based on current presets
+    // this will mark position as needed finalized which we'll do in the
+    // main-loop
     flightgear::initPosition();
     
     // Force reupdating the positions of the ai 3d models. They are used for
index 2073b9e1581df3a1fe77180f868a1aa819dd6173..abb786253f4e27bf6f5becde0110505d91896977 100644 (file)
@@ -217,15 +217,9 @@ static void fgIdleFunction ( void ) {
         }
       
     } else if ( idle_state == 10 ) {
-        idle_state = 800;
+        idle_state = 900;
         fgPostInitSubsystems();
-    } else if ( idle_state == 800 ) {
-        if (flightgear::finalizePosition()) {
-            idle_state = 900;
-            fgSplashProgress("init-graphics");
-        } else {
-            fgSplashProgress("finalize-position");
-        }
+        fgSplashProgress("finalize-position");
     } else if ( idle_state == 900 ) {
         idle_state = 1000;
         
index c904a48fa78f69957b6f4106e6fcd2234b8c4dc1..c7c63b5336f586c7079d4448672a076ff7f12675 100644 (file)
@@ -25,6 +25,7 @@
 // simgear
 #include <simgear/props/props_io.hxx>
 #include <simgear/structure/exception.hxx>
+#include <simgear/structure/event_mgr.hxx>
 
 #include "globals.hxx"
 #include "fg_props.hxx"
@@ -44,6 +45,9 @@ namespace flightgear
 /// unresponsive, we need a timeout value. This value is reset on initPosition,
 /// and tracked through each call to finalizePosition.
 static SGTimeStamp global_finalizeTime;
+static bool global_callbackRegistered = false;
+
+static void finalizePosition();
   
 // Set current tower position lon/lat given an airport id
 static bool fgSetTowerPosFromAirportID( const string& id) {
@@ -401,7 +405,11 @@ static bool fgSetPosFromFix( const string& id )
 bool initPosition()
 {
   global_finalizeTime = SGTimeStamp(); // reset to invalid
-  
+  if (!global_callbackRegistered) {
+    globals->get_event_mgr()->addTask("finalizePosition", &finalizePosition, 0.1);
+    global_callbackRegistered = true;
+  }
+    
   double gs = fgGetDouble("/sim/presets/glideslope-deg")
   * SG_DEGREES_TO_RADIANS ;
   double od = fgGetDouble("/sim/presets/offset-distance-nm");
@@ -544,16 +552,57 @@ bool initPosition()
     fgSetBool("/sim/presets/onground", true);
   }
   
+  fgSetBool("/sim/position-finalized", false);
+    
   return true;
 }
   
-bool finalizePosition()
+bool finalizeMetar()
+{
+  double hdg = fgGetDouble( "/environment/metar/base-wind-dir-deg", 9999.0 );
+  string apt = fgGetString( "/sim/startup/options/airport" );
+  string rwy = fgGetString( "/sim/startup/options/runway" );
+  double strthdg = fgGetDouble( "/sim/startup/options/heading-deg", 9999.0 );
+  string parkpos = fgGetString( "/sim/presets/parkpos" );
+  bool onground = fgGetBool( "/sim/presets/onground", false );
+  // this logic is taken from former startup.nas
+  bool needMetar = (hdg < 360.0) && !apt.empty() && (strthdg > 360.0) &&
+  rwy.empty() && onground && parkpos.empty();
+  
+  if (needMetar) {
+    // timeout so we don't spin forever if the network is down
+    if (global_finalizeTime.elapsedMSec() > fgGetInt("/sim/startup/metar-fetch-timeout-msec", 10000)) {
+      SG_LOG(SG_GENERAL, SG_WARN, "finalizePosition: timed out waiting for METAR fetch");
+      return true;
+    }
+    
+    if (!fgGetBool( "/environment/metar/valid" )) {
+      // bit hacky - run these two subsystems. We can't run the whole
+      // lot since some view things aren't initialised and hence FGLight
+      // crashes.
+      globals->get_subsystem("http")->update(0.0);
+      globals->get_subsystem("environment")->update(0.0);
+      return false;
+    }
+    
+    SG_LOG(SG_ENVIRONMENT, SG_INFO,
+           "Using METAR for runway selection: '" << fgGetString("/environment/metar/data") << "'" );
+    setPosFromAirportIDandHdg( apt, hdg );
+    // fall through to return true
+  } // of need-metar case
+  
+  return true;
+}
+  
+void finalizePosition()
 {
   // first call to finalize after an initPosition call
   if (global_finalizeTime.get_usec() == 0) {
     global_finalizeTime = SGTimeStamp::now();
   }
   
+  bool done = true;
+  
     /* Scenarios require Nasal, so FGAIManager loads the scenarios,
      * including its models such as a/c carriers, in its 'postinit',
      * which is the very last thing we do.
@@ -569,42 +618,16 @@ bool finalizePosition()
         // clear preset location and re-trigger position setup
         fgSetDouble("/sim/presets/longitude-deg", 9999);
         fgSetDouble("/sim/presets/latitude-deg", 9999);
-        return initPosition();
+        initPosition();
+    } else {
+        done = finalizeMetar();
+    }
+  
+    fgSetBool("/sim/position-finalized", done);
+    if (done) {
+        globals->get_event_mgr()->removeTask("finalizePosition");
+        global_callbackRegistered = false;
     }
-
-    double hdg = fgGetDouble( "/environment/metar/base-wind-dir-deg", 9999.0 );
-    string apt = fgGetString( "/sim/startup/options/airport" );
-    string rwy = fgGetString( "/sim/startup/options/runway" );
-    double strthdg = fgGetDouble( "/sim/startup/options/heading-deg", 9999.0 );
-    string parkpos = fgGetString( "/sim/presets/parkpos" );
-    bool onground = fgGetBool( "/sim/presets/onground", false );
-// this logic is taken from former startup.nas
-    bool needMetar = (hdg < 360.0) && !apt.empty() && (strthdg > 360.0) &&
-        rwy.empty() && onground && parkpos.empty();
-    
-    if (needMetar) {
-      // timeout so we don't spin forever if the network is down
-      if (global_finalizeTime.elapsedMSec() > fgGetInt("/sim/startup/metar-fetch-timeout-msec", 5000)) {
-        SG_LOG(SG_GENERAL, SG_WARN, "finalizePosition: timed out waiting for METAR fetch");
-        return true;
-      }
-    
-      if (!fgGetBool( "/environment/metar/valid" )) {
-        // bit hacky - run these two subsystems. We can't run the whole
-        // lot since some view things aren't initialised and hence FGLight
-        // crashes.
-        globals->get_subsystem("http")->update(0.0);
-        globals->get_subsystem("environment")->update(0.0);
-        return false;
-      }
-      
-      SG_LOG(SG_ENVIRONMENT, SG_INFO,
-             "Using METAR for runway selection: '" << fgGetString("/environment/metar/data") << "'" );
-      setPosFromAirportIDandHdg( apt, hdg );
-        // fall through to return true
-    } // of need-metar case
-    
-    return true;
 }
     
 } // of namespace flightgear
index 69a7e6809a7894fc01c35213aa86caeafa470100..ac12adecd213b8fc5843a916e7697b16660805e2 100644 (file)
@@ -27,15 +27,6 @@ namespace flightgear
   
 // Set the initial position based on presets (or defaults)
 bool initPosition();
-
-/**
- * finalize the position once subsystems, Nasal and scenarios are loaded;
- * all of which can potentially affect the position.
- * returns true if the position is finally set, or false if more time
- * is required to finalize the position (eg, awaiting METAR to set the
- * active runway)
- */
-bool finalizePosition();
     
 // Listen to /sim/tower/airport-id and set tower view position accordingly
 void initTowerLocationListener();
index 7dfeddf922af5c5ce62317cf3d65746014d10e45..22efc3da3cfdb7e1468fd55bc8f084c923b01a1d 100644 (file)
@@ -322,14 +322,19 @@ void FGTileMgr::update(double)
     if (!_scenery_loaded->getBoolValue())
     {
         bool fdmInited = fgGetBool("sim/fdm-initialized");
-        if (_scenery_override->getBoolValue() || (isSceneryLoaded() && fdmInited))
+        bool positionFinalized = fgGetBool("sim/position-finalized");
+        bool sceneryOverride = _scenery_override->getBoolValue();
+        
+    // we are done if final position is set and the scenery & FDM are done.
+    // scenery-override can ignore the last two, but not position finalization.
+        if (positionFinalized && (sceneryOverride || (isSceneryLoaded() && fdmInited)))
         {
             _scenery_loaded->setBoolValue(true);
             fgSplashProgress("");
         }
         else
         {
-            fgSplashProgress("loading-scenery");
+            fgSplashProgress(positionFinalized ? "loading-scenery" : "finalize-position");
             // be nice to loader threads while waiting for initial scenery, reduce to 20fps
             SGTimeStamp::sleepForMSec(50);
         }
index 3f82a205209c7afb374295a76b451778eabdc938..2e8d8fe875cac2061b1692673370793611e3f4b7 100644 (file)
@@ -517,6 +517,8 @@ FGRenderer::init( void )
     if (!_classicalRenderer)
         _pipeline = makeRenderingPipeline(_renderer, 0);
     _scenery_loaded   = fgGetNode("/sim/sceneryloaded", true);
+    _position_finalized = fgGetNode("/sim/position-finalized", true);
+    
     _panel_hotspots   = fgGetNode("/sim/panel-hotspots", true);
     _virtual_cockpit  = fgGetNode("/sim/virtual-cockpit", true);
 
@@ -1543,7 +1545,7 @@ FGRenderer::setupView( void )
 // Update all Visuals (redraws anything graphics related)
 void
 FGRenderer::update( ) {
-    if (!_scenery_loaded->getBoolValue())
+    if (!_position_finalized || !_scenery_loaded->getBoolValue())
     {
         _splash_alpha->setDoubleValue(1.0);
         return;
index a98a4b62fca7181452cb7b0306fcff02a1e8b41a..a064dcd30ee67c3a60ea639dfe252cfeec012745 100644 (file)
@@ -121,7 +121,8 @@ public:
 protected:
     osg::ref_ptr<osgViewer::Viewer> viewer;
     osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
-    SGPropertyNode_ptr _scenery_loaded;
+    SGPropertyNode_ptr _scenery_loaded, _position_finalized;
+    
     SGPropertyNode_ptr _skyblend, _splash_alpha;
     SGPropertyNode_ptr _point_sprites, _enhanced_lighting, _distance_attenuation;
     SGPropertyNode_ptr _textures;