]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/globals.cxx
Temporarily disable Nasal callbacks in lazily loaded scenery models
[flightgear.git] / src / Main / globals.cxx
index 9ed3a6b56478bddcadc44b845ee6e3dbd53d2f7d..8631fa1b07e9fb553e3bc2de83d99d16aa856cb4 100644 (file)
@@ -24,6 +24,9 @@
 #  include <config.h>
 #endif
 
+#include <boost/foreach.hpp>
+#include <algorithm>
+
 #include <simgear/structure/commands.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/misc/sg_dir.hxx>
 #include <simgear/sound/soundmgr_openal.hxx>
 #include <simgear/misc/ResourceManager.hxx>
 #include <simgear/props/propertyObject.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/scene/model/placement.hxx>
 
 #include <Aircraft/controls.hxx>
 #include <Airports/runways.hxx>
 #include <ATCDCL/ATCmgr.hxx>
 #include <Autopilot/route_mgr.hxx>
 #include <Cockpit/panel.hxx>
-#include <GUI/new_gui.hxx>
+#include <GUI/FGFontCache.hxx>
+#include <GUI/gui.h>
 #include <Model/acmodel.hxx>
 #include <Model/modelmgr.hxx>
 #include <MultiPlayer/multiplaymgr.hxx>
@@ -120,7 +126,6 @@ FGGlobals::FGGlobals() :
     renderer( new FGRenderer ),
     subsystem_mgr( new SGSubsystemMgr ),
     event_mgr( new SGEventMgr ),
-    soundmgr( new SGSoundMgr ),
     sim_time_sec( 0.0 ),
     fg_root( "" ),
     time_params( NULL ),
@@ -146,35 +151,39 @@ FGGlobals::FGGlobals() :
     dmelist( NULL ),
     tacanlist( NULL ),
     carrierlist( NULL ),
-    channellist( NULL )    
+    channellist( NULL ),
+    haveUserSettings(false)
 {
   simgear::ResourceManager::instance()->addProvider(new AircraftResourceProvider());
   simgear::PropertyObjectBase::setDefaultRoot(props);
 }
 
-
 // Destructor
 FGGlobals::~FGGlobals() 
 {
-    delete renderer;
-    renderer = NULL;
-    
-// The AIModels manager performs a number of actions upon
+    // save user settings (unless already saved)
+    saveUserSettings();
+
+    // The AIModels manager performs a number of actions upon
     // Shutdown that implicitly assume that other subsystems
     // are still operational (Due to the dynamic allocation and
     // deallocation of AIModel objects. To ensure we can safely
     // shut down all subsystems, make sure we take down the 
     // AIModels system first.
-    SGSubsystem* ai = subsystem_mgr->remove("ai_model");
+    SGSubsystem* ai = subsystem_mgr->remove("ai-model");
     if (ai) {
         ai->unbind();
         delete ai;
     }
-    
+    SGSubsystem* sound = subsystem_mgr->remove("sound");
+
     subsystem_mgr->shutdown();
     subsystem_mgr->unbind();
     delete subsystem_mgr;
     
+    delete renderer;
+    renderer = NULL;
+    
     delete time_params;
     delete mag;
     delete matlib;
@@ -182,8 +191,12 @@ FGGlobals::~FGGlobals()
     delete current_panel;
 
     delete ATC_mgr;
-    controls->unbind();
-    delete controls;
+
+    if (controls)
+    {
+        controls->unbind();
+        delete controls;
+    }
 
     delete channel_options_list;
     delete initial_waypoints;
@@ -197,9 +210,7 @@ FGGlobals::~FGGlobals()
     delete tacanlist;
     delete carrierlist;
     delete channellist;
-
-    soundmgr->unbind();
-    delete soundmgr;
+    delete sound;
 }
 
 
@@ -211,7 +222,7 @@ void FGGlobals::set_fg_root (const string &root) {
     SGPath tmp( fg_root );
     tmp.append( "data" );
     tmp.append( "version" );
-    if ( ulFileExists( tmp.c_str() ) ) {
+    if ( tmp.exists() ) {
         fgGetNode("BAD_FG_ROOT", true)->setStringValue(fg_root);
         fg_root += "/data";
         fgGetNode("GOOD_FG_ROOT", true)->setStringValue(fg_root);
@@ -230,26 +241,30 @@ void FGGlobals::set_fg_root (const string &root) {
       simgear::ResourceManager::PRIORITY_DEFAULT);
 }
 
-void FGGlobals::set_fg_scenery (const string &scenery)
+void FGGlobals::append_fg_scenery (const string &paths)
 {
-    SGPath s;
-    if (scenery.empty()) {
-        s.set( fg_root );
-        s.append( "Scenery" );
-    } else
-        s.set( scenery );
-
-    string_list path_list = sgPathSplit( s.str() );
-    fg_scenery.clear();
+//    fg_scenery.clear();
     SGPropertyNode* sim = fgGetNode("/sim", true);
-    
-    for (unsigned i = 0; i < path_list.size(); i++) {
-        SGPath path(path_list[i]);
+
+  // find first unused fg-scenery property in /sim
+    int propIndex = 0;
+    while (sim->getChild("fg-scenery", propIndex) != NULL) {
+      ++propIndex; 
+    }
+  
+    BOOST_FOREACH(const SGPath& path, sgPathSplit( paths )) {
         if (!path.exists()) {
           SG_LOG(SG_GENERAL, SG_WARN, "scenery path not found:" << path.str());
           continue;
         }
 
+      // check for duplicates
+      string_list::const_iterator ex = std::find(fg_scenery.begin(), fg_scenery.end(), path.str());
+      if (ex != fg_scenery.end()) {
+        SG_LOG(SG_GENERAL, SG_INFO, "skipping duplicate add of scenery path:" << path.str());
+        continue;
+      }
+      
         simgear::Dir dir(path);
         SGPath terrainDir(dir.file("Terrain"));
         SGPath objectsDir(dir.file("Objects"));
@@ -274,8 +289,7 @@ void FGGlobals::set_fg_scenery (const string &scenery)
         fg_scenery.push_back("");
         
       // make scenery dirs available to Nasal
-        sim->removeChild("fg-scenery", i, false);
-        SGPropertyNode* n = sim->getChild("fg-scenery", i, true);
+        SGPropertyNode* n = sim->getChild("fg-scenery", propIndex++, true);
         n->setStringValue(path.str());
         n->setAttribute(SGPropertyNode::WRITE, false);
     } // of path list iteration
@@ -348,7 +362,10 @@ FGGlobals::add_subsystem (const char * name,
 SGSoundMgr *
 FGGlobals::get_soundmgr () const
 {
-    return soundmgr;
+    if (subsystem_mgr)
+        return (SGSoundMgr*) subsystem_mgr->get_subsystem("sound");
+
+    return NULL;
 }
 
 SGEventMgr *
@@ -357,6 +374,23 @@ FGGlobals::get_event_mgr () const
     return event_mgr;
 }
 
+const SGGeod &
+FGGlobals::get_aircraft_position() const
+{
+    if( acmodel != NULL ) {
+        SGModelPlacement * mp = acmodel->get3DModel();
+        if( mp != NULL )
+            return mp->getPosition();
+    }
+    throw sg_exception("Can't get aircraft position", "FGGlobals::get_aircraft_position()" );
+}
+
+SGVec3d
+FGGlobals::get_aircraft_positon_cart() const
+{
+    return SGVec3d::fromGeod(get_aircraft_position());
+}
+
 
 // Save the current state as the initial state.
 void
@@ -406,6 +440,41 @@ FGGlobals::restoreInitialState ()
 
 }
 
+// Load user settings from autosave.xml
+void
+FGGlobals::loadUserSettings()
+{
+    // dummy method for now.
+    //TODO Move code loading autosave.xml in here after the 2.6.0 release.
+    haveUserSettings = true;
+}
+
+// Save user settings in autosave.xml
+void
+FGGlobals::saveUserSettings()
+{
+    // only save settings when we have (tried) to load the previous
+    // settings (otherwise user data was lost)
+    if (!haveUserSettings)
+        return;
+
+    if (fgGetBool("/sim/startup/save-on-exit")) {
+      // don't save settings more than once on shutdown
+      haveUserSettings = false;
+
+      SGPath autosaveFile(fgGetString("/sim/fg-home"));
+      autosaveFile.append( "autosave.xml" );
+      autosaveFile.create_dir( 0700 );
+      SG_LOG(SG_IO, SG_INFO, "Saving user settings to " << autosaveFile.str());
+      try {
+        writeProperties(autosaveFile.str(), globals->get_props(), false, SGPropertyNode::USERARCHIVE);
+      } catch (const sg_exception &e) {
+        guiErrorMessage("Error writing autosave.xml: ", e);
+      }
+      SG_LOG(SG_INPUT, SG_DEBUG, "Finished Saving user settings");
+    }
+}
+
 FGViewer *
 FGGlobals::get_current_view () const
 {