Restructure positional finalisation for sim-reset.
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!)
This commit is contained in:
parent
c9976155d6
commit
487638be7f
7 changed files with 76 additions and 58 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue