]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_init.cxx
Crash-fix: mat-lib is now reference-counted.
[flightgear.git] / src / Main / fg_init.cxx
index e9748c28cf5f610f8ebb1452ba2c02b8a98fa16a..3abb334601472843151010de39fdc7721254706f 100644 (file)
@@ -50,6 +50,7 @@
 
 #include <osgViewer/Viewer>
 
+#include <simgear/canvas/Canvas.hxx>
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/structure/exception.hxx>
@@ -64,6 +65,7 @@
 
 #include <simgear/scene/model/modellib.hxx>
 #include <simgear/scene/material/matlib.hxx>
+#include <simgear/scene/material/Effect.hxx>
 #include <simgear/scene/model/particles.hxx>
 #include <simgear/scene/tsync/terrasync.hxx>
 
@@ -87,6 +89,7 @@
 
 #include <Canvas/canvas_mgr.hxx>
 #include <Canvas/gui_mgr.hxx>
+#include <Canvas/FGCanvasSystemAdapter.hxx>
 #include <GUI/new_gui.hxx>
 #include <GUI/MessageBox.hxx>
 #include <Input/input.hxx>
@@ -407,16 +410,17 @@ bool fgInitHome()
 #else
     // POSIX, do open+unlink trick to the file is deleted on exit, even if we
     // crash or exit(-1)
-    size_t len = snprintf(buf, 16, "%d", getpid());
+    ssize_t len = snprintf(buf, 16, "%d", getpid());
     int fd = ::open(pidPath.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644);
     if (fd >= 0) {
-        ::write(fd, buf, len);
-        ::unlink(pidPath.c_str()); // delete file when app quits
-        result = true;
+        result = ::write(fd, buf, len) == len;
+        if( ::unlink(pidPath.c_str()) != 0 ) // delete file when app quits
+          result = false;
     }
-    
-    fgSetBool("/sim/fghome-readonly", false);
 #endif
+
+    fgSetBool("/sim/fghome-readonly", false);
+
     if (!result) {
         flightgear::fatalMessageBox("File permissions problem",
                                     "Can't write to user-data storage folder, check file permissions and FG_HOME.",
@@ -432,7 +436,7 @@ int fgInitConfig ( int argc, char **argv, bool reinit )
     
     simgear::Dir exportDir(simgear::Dir(dataPath).file("Export"));
     if (!exportDir.exists()) {
-      exportDir.create(0777);
+      exportDir.create(0755);
     }
     
     // Set /sim/fg-home and don't allow malign code to override it until
@@ -692,6 +696,9 @@ void fgCreateSubsystems(bool duringReset) {
     ////////////////////////////////////////////////////////////////////
     // Initialize the canvas 2d drawing subsystem.
     ////////////////////////////////////////////////////////////////////
+    simgear::canvas::Canvas::setSystemAdapter(
+      simgear::canvas::SystemAdapterPtr(new canvas::FGCanvasSystemAdapter)
+    );
     globals->add_subsystem("Canvas", new CanvasMgr, SGSubsystemMgr::DISPLAY);
     globals->add_subsystem("CanvasGUI", new GUIMgr, SGSubsystemMgr::DISPLAY);
 
@@ -932,16 +939,26 @@ void fgReInitSubsystems()
 
 void fgStartNewReset()
 {
-    globals->saveInitialState();
+    SGPropertyNode_ptr preserved(new SGPropertyNode);
+    
+    if (!copyPropertiesWithAttribute(globals->get_props(), preserved, SGPropertyNode::PRESERVE))
+        SG_LOG(SG_GENERAL, SG_ALERT, "Error saving preserved state");
     
     fgSetBool("/sim/signals/reinit", true);
     fgSetBool("/sim/freeze/master", true);
     
     SGSubsystemMgr* subsystemManger = globals->get_subsystem_mgr();
+    // Nasal is manually inited in fgPostInit, ensure it's already shutdown
+    // before other subsystems, so Nasal listeners don't fire during shutdonw
+    SGSubsystem* nasal = subsystemManger->get_subsystem("nasal");
+    nasal->shutdown();
+    nasal->unbind();
+    subsystemManger->remove("nasal");
+    
     subsystemManger->shutdown();
     subsystemManger->unbind();
     
-    // remove them all (with some exceptions?)
+    // remove most subsystems, with a few exceptions.
     for (int g=0; g<SGSubsystemMgr::MAX_GROUPS; ++g) {
         SGSubsystemGroup* grp = subsystemManger->get_group(static_cast<SGSubsystemMgr::GroupType>(g));
         const string_list& names(grp->member_names());
@@ -975,6 +992,9 @@ void fgStartNewReset()
     // don't cancel the pager until after shutdown, since AIModels (and
     // potentially others) can queue delete requests on the pager.
     render->getViewer()->getDatabasePager()->cancel();
+    render->getViewer()->getDatabasePager()->clear();
+    
+    osgDB::Registry::instance()->clearObjectCache();
     
     // preserve the event handler; re-creating it would entail fixing the
     // idle handler
@@ -982,15 +1002,25 @@ void fgStartNewReset()
     
     globals->set_renderer(NULL);
     globals->set_matlib(NULL);
+    globals->set_chatter_queue(NULL);
+    
+    simgear::clearEffectCache();
     simgear::SGModelLib::resetPropertyRoot();
+        
+    simgear::GlobalParticleCallback::setSwitch(NULL);
     
     globals->resetPropertyRoot();
-    globals->restoreInitialState();
-    
     fgInitConfig(0, NULL, true);
     fgInitGeneral(); // all of this?
     
-    fgGetNode("/sim")->removeChild("aircraft-dir");    
+    if ( copyProperties(preserved, globals->get_props()) ) {
+        SG_LOG( SG_GENERAL, SG_INFO, "Preserved state restored successfully" );
+    } else {
+        SG_LOG( SG_GENERAL, SG_INFO,
+               "Some errors restoring preserved state (read-only props?)" );
+    }
+
+    fgGetNode("/sim")->removeChild("aircraft-dir");
     fgInitAircraft(true);
     flightgear::Options::sharedInstance()->processOptions();
     
@@ -999,14 +1029,15 @@ void fgStartNewReset()
     globals->set_renderer(render);
     render->init();
     render->setViewer(viewer.get());
+
     viewer->getDatabasePager()->setUpThreads(1, 1);
-    render->splashinit();
     
+    // must do this before splashinit for Rembrandt
     flightgear::CameraGroup::buildDefaultGroup(viewer.get());
-
+    render->splashinit();
+    
     fgOSResetProperties();
 
-    
 // init some things manually
 // which do not follow the regular init pattern