1
0
Fork 0

Make subsystem init incremental.

(Requires latest SimGear!)

Break fgInitSubsystems into several phases - subsystem creation, then binding and then init. Run init over multiple main-loop iterations so the application stays responsive to GUI/OS events during init. 

There should be no behaviour changes due to this, except that during init Windows and OS-X should no longer show the beach ball / 'application not responding feedback', hopefully.
This commit is contained in:
James Turner 2012-09-18 20:29:36 +01:00
parent 9d30d622ae
commit e2eea405a3
3 changed files with 50 additions and 56 deletions

View file

@ -1050,9 +1050,9 @@ bool fgInitGeneral() {
// initialization routines. If you are adding a subsystem to flight // initialization routines. If you are adding a subsystem to flight
// gear, its initialization call should located in this routine. // gear, its initialization call should located in this routine.
// Returns non-zero if a problem encountered. // Returns non-zero if a problem encountered.
bool fgInitSubsystems() { void fgCreateSubsystems() {
SG_LOG( SG_GENERAL, SG_INFO, "Initialize Subsystems"); SG_LOG( SG_GENERAL, SG_INFO, "Creating Subsystems");
SG_LOG( SG_GENERAL, SG_INFO, "========== =========="); SG_LOG( SG_GENERAL, SG_INFO, "========== ==========");
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -1264,13 +1264,12 @@ bool fgInitSubsystems() {
globals->add_subsystem("tile-manager", globals->get_tile_mgr(), globals->add_subsystem("tile-manager", globals->get_tile_mgr(),
SGSubsystemMgr::DISPLAY); SGSubsystemMgr::DISPLAY);
}
//////////////////////////////////////////////////////////////////// void fgPostInitSubsystems()
// Bind and initialize subsystems. {
//////////////////////////////////////////////////////////////////// SGTimeStamp st;
st.stamp();
globals->get_subsystem_mgr()->bind();
globals->get_subsystem_mgr()->init();
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Initialize the Nasal interpreter. // Initialize the Nasal interpreter.
@ -1279,9 +1278,12 @@ bool fgInitSubsystems() {
FGNasalSys* nasal = new FGNasalSys(); FGNasalSys* nasal = new FGNasalSys();
globals->add_subsystem("nasal", nasal, SGSubsystemMgr::INIT); globals->add_subsystem("nasal", nasal, SGSubsystemMgr::INIT);
nasal->init(); nasal->init();
SG_LOG(SG_GENERAL, SG_INFO, "Nasal init took:" << st.elapsedMSec());
// initialize methods that depend on other subsystems. // initialize methods that depend on other subsystems.
st.stamp();
globals->get_subsystem_mgr()->postinit(); globals->get_subsystem_mgr()->postinit();
SG_LOG(SG_GENERAL, SG_INFO, "Subsystems postinit took:" << st.elapsedMSec());
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// TODO FIXME! UGLY KLUDGE! // TODO FIXME! UGLY KLUDGE!
@ -1318,8 +1320,6 @@ bool fgInitSubsystems() {
// Save the initial state for future // Save the initial state for future
// reference. // reference.
globals->saveInitialState(); globals->saveInitialState();
return true;
} }
// Reset: this is what the 'reset' command (and hence, GUI) is attached to // Reset: this is what the 'reset' command (and hence, GUI) is attached to

View file

@ -29,7 +29,6 @@
// forward decls // forward decls
class SGPropertyNode; class SGPropertyNode;
class SGTime;
class SGPath; class SGPath;
// Return the current base package version // Return the current base package version
@ -52,11 +51,12 @@ bool fgInitNav ();
bool fgInitGeneral (); bool fgInitGeneral ();
// This is the top level init routine which calls all the other // Create all the subsystems needed by the sim
// initialization routines. If you are adding a subsystem to flight void fgCreateSubsystems();
// gear, its initialization call should located in this routine.
bool fgInitSubsystems();
// called after the subsystems have been bound and initialised,
// to peform final init
void fgPostInitSubsystems();
// Reset: this is what the 'reset' command (and hence, GUI) is attached to // Reset: this is what the 'reset' command (and hence, GUI) is attached to
void fgReInitSubsystems(); void fgReInitSubsystems();

View file

@ -181,6 +181,7 @@ static void fgIdleFunction ( void ) {
// our initializations out of the idle callback so that we can get a // our initializations out of the idle callback so that we can get a
// splash screen up and running right away. // splash screen up and running right away.
static int idle_state = 0; static int idle_state = 0;
static int spin_count = 0;
static osg::ref_ptr<GeneralInitOperation> genOp; static osg::ref_ptr<GeneralInitOperation> genOp;
if ( idle_state == 0 ) { if ( idle_state == 0 ) {
@ -265,47 +266,40 @@ static void fgIdleFunction ( void ) {
} else if ( idle_state == 6 ) { } else if ( idle_state == 6 ) {
idle_state++; idle_state++;
fgSplashProgress("initializing subsystems"); fgSplashProgress("creating subsystems");
} else if ( idle_state == 7 ) { } else if ( idle_state == 7 ) {
idle_state++; idle_state++;
// Initialize audio support SGTimeStamp st;
#ifdef ENABLE_AUDIO_SUPPORT st.stamp();
fgCreateSubsystems();
SG_LOG(SG_GENERAL, SG_INFO, "Creating subsystems took:" << st.elapsedMSec());
fgSplashProgress("binding subsystems");
// Start the intro music } else if ( idle_state == 8 ) {
if ( fgGetBool("/sim/startup/intro-music") ) { idle_state++;
SGPath mp3file( globals->get_fg_root() ); SGTimeStamp st;
mp3file.append( "Sounds/intro.mp3" ); st.stamp();
globals->get_subsystem_mgr()->bind();
SG_LOG(SG_GENERAL, SG_INFO, "Binding subsystems took:" << st.elapsedMSec());
SG_LOG( SG_GENERAL, SG_INFO, fgSplashProgress("initing subsystems");
"Starting intro music: " << mp3file.str() ); } else if ( idle_state == 9 ) {
SGSubsystem::InitStatus status = globals->get_subsystem_mgr()->incrementalInit();
# if defined( __CYGWIN__ ) if ( status == SGSubsystem::INIT_DONE) {
string command = "start /m `cygpath -w " + mp3file.str() + "`"; ++idle_state;
# elif defined( _WIN32 ) fgSplashProgress("finishing subsystem init");
string command = "start /m " + mp3file.str(); } else {
# else const char* spinChars = "-\\|/";
string command = "mpg123 " + mp3file.str() + "> /dev/null 2>&1"; string msg = string("initing subsystems ") + spinChars[spin_count++ % 4];
# endif fgSplashProgress(msg.c_str());
if (0 != system ( command.c_str() ))
{
SG_LOG( SG_SOUND, SG_WARN,
"Failed to play mp3 file " << mp3file.str() << ". Maybe mp3 player is not installed." );
}
}
#endif
// This is the top level init routine which calls all the
// other subsystem initialization routines. If you are adding
// a subsystem to flightgear, its initialization call should be
// located in this routine.
if( !fgInitSubsystems()) {
SG_LOG( SG_GENERAL, SG_ALERT,
"Subsystem initialization failed ..." );
exit(-1);
} }
// Torsten Dreyer: } else if ( idle_state == 10 ) {
idle_state = 900;
fgPostInitSubsystems();
// Torsten Dreyer:
// ugly hack for automatic runway selection on startup based on // ugly hack for automatic runway selection on startup based on
// metar data. Makes startup.nas obsolete and guarantees the same // metar data. Makes startup.nas obsolete and guarantees the same
// runway selection as for AI traffic. However, this code belongs to // runway selection as for AI traffic. However, this code belongs to
@ -335,7 +329,7 @@ static void fgIdleFunction ( void ) {
fgSplashProgress("initializing graphics engine"); fgSplashProgress("initializing graphics engine");
} else if ( idle_state == 8 ) { } else if ( idle_state == 900 ) {
idle_state = 1000; idle_state = 1000;
// setup OpenGL view parameters // setup OpenGL view parameters