From 070dba29f9390806457206c2660f2daebd3d847c Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 16 Mar 2014 22:52:55 +0000 Subject: [PATCH] Close dialogs on GUI shutdown - avoids orphaned dialogs on reset - requires some guards in NasalSys since Nasal is shutdown first, but dialogs can have Nasal modules. --- src/GUI/new_gui.cxx | 8 +++++++- src/GUI/new_gui.hxx | 3 ++- src/Scripting/NasalSys.cxx | 23 +++++++++++++++++++++-- src/Scripting/NasalSys.hxx | 1 + 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx index 66f4a115a..d2eb8b140 100644 --- a/src/GUI/new_gui.cxx +++ b/src/GUI/new_gui.cxx @@ -88,6 +88,12 @@ NewGUI::init () void NewGUI::shutdown() { + DialogDict::iterator it = _active_dialogs.begin(); + for (; it != _active_dialogs.end(); ++it) { + delete it->second; + } + _active_dialogs.clear(); + fgUntie("/sim/menubar/visibility"); _menubar.reset(); _dialog_props.clear(); @@ -129,7 +135,7 @@ NewGUI::createMenuBarImplementation() void NewGUI::reset (bool reload) { - map::iterator iter; + DialogDict::iterator iter; string_list openDialogs; // close all open dialogs and remember them ... for (iter = _active_dialogs.begin(); iter != _active_dialogs.end(); ++iter) diff --git a/src/GUI/new_gui.hxx b/src/GUI/new_gui.hxx index 1ab1361c8..a0e4e69af 100644 --- a/src/GUI/new_gui.hxx +++ b/src/GUI/new_gui.hxx @@ -223,7 +223,8 @@ private: std::auto_ptr _menubar; FGDialog * _active_dialog; - std::map _active_dialogs; + typedef std::map DialogDict; + DialogDict _active_dialogs; typedef std::map NamePathDict; // mapping from dialog names to the corresponding XML property list diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index e658ccc55..ae5cbe59f 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -201,7 +201,8 @@ static char* readfile(const char* file, int* lenOut) return buf; } -FGNasalSys::FGNasalSys() +FGNasalSys::FGNasalSys() : + _inited(false) { nasalSys = this; _context = 0; @@ -249,6 +250,9 @@ naRef FGNasalSys::callMethod(naRef code, naRef self, int argc, naRef* args, naRe FGNasalSys::~FGNasalSys() { + if (_inited) { + SG_LOG(SG_GENERAL, SG_ALERT, "Nasal was not shutdown"); + } nasalSys = 0; } @@ -732,6 +736,9 @@ void FGNasalSys::setCmdArg(SGPropertyNode* aNode) void FGNasalSys::init() { + if (_inited) { + SG_LOG(SG_GENERAL, SG_ALERT, "duplicate init of Nasal"); + } int i; _context = naNewContext(); @@ -803,10 +810,16 @@ void FGNasalSys::init() // now Nasal modules are loaded, we can do some delayed work postinitNasalPositioned(_globals, _context); postinitNasalGUI(_globals, _context); + + _inited = true; } void FGNasalSys::shutdown() { + if (!_inited) { + return; + } + shutdownNasalPositioned(); map::iterator it, end = _listener.end(); @@ -837,7 +850,7 @@ void FGNasalSys::shutdown() _globals = naNil(); naGC(); - + _inited = false; } naRef FGNasalSys::wrappedPropsNode(SGPropertyNode* aProps) @@ -1085,6 +1098,12 @@ bool FGNasalSys::createModule(const char* moduleName, const char* fileName, void FGNasalSys::deleteModule(const char* moduleName) { + if (!_inited) { + // can occur on shutdown due to us being shutdown first, but other + // subsystems having Nasal objects. + return; + } + naContext ctx = naNewContext(); naRef modname = naNewString(ctx); naStr_fromdata(modname, (char*)moduleName, strlen(moduleName)); diff --git a/src/Scripting/NasalSys.hxx b/src/Scripting/NasalSys.hxx index d4680f139..8915c38bf 100644 --- a/src/Scripting/NasalSys.hxx +++ b/src/Scripting/NasalSys.hxx @@ -172,6 +172,7 @@ private: naRef parse(const char* filename, const char* buf, int len); naRef genPropsModule(); + bool _inited; naContext _context; naRef _globals, _string; -- 2.39.5