]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scripting/NasalSys.cxx
add alert message
[flightgear.git] / src / Scripting / NasalSys.cxx
index 2415d5f9ad51ef5cdec4c0d87b6f31f1d817024e..ae3d51631cb044b2576b4209a990f6d0967e215f 100644 (file)
@@ -500,6 +500,15 @@ void FGNasalSys::createModule(const char* moduleName, const char* fileName,
     hashset(_globals, moduleName, locals);
 }
 
+void FGNasalSys::deleteModule(const char* moduleName)
+{
+    naRef modname = naNewString(_context);
+    naStr_fromdata(modname, (char*)moduleName, strlen(moduleName));
+    naModLock();
+    naHash_delete(_globals, modname);
+    naModUnlock();
+}
+
 naRef FGNasalSys::parse(const char* filename, const char* buf, int len)
 {
     int errLine = -1;
@@ -524,12 +533,13 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
     naRef code = parse(arg->getPath(true), nasal, strlen(nasal));
     if(naIsNil(code)) return false;
 
+    naContext c = naNewContext();
     naRef locals = naNil();
-    if (moduleName[0]) {
-        naRef modname = naNewString(_context);
+    if(moduleName[0]) {
+        naRef modname = naNewString(c);
         naStr_fromdata(modname, (char*)moduleName, strlen(moduleName));
         if(!naHash_get(_globals, modname, &locals))
-            locals = naNewHash(_context);
+            locals = naNewHash(c);
     }
     // Cache the command argument for inspection via cmdarg().  For
     // performance reasons, we won't bother with it if the invoked
@@ -537,10 +547,15 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
     _cmdArg = (SGPropertyNode*)arg;
 
     // Call it!
-    naRef result = naCall(_context, code, 0, 0, naNil(), locals);
-    if(!naGetError(_context)) return true;
-    logError(_context);
-    return false;
+    naModUnlock();
+    naRef result = naCall(c, code, 0, 0, naNil(), locals);
+    naModLock();
+    bool error = naGetError(c);
+    if(error)
+       logError(c);
+
+    naFreeContext(c);
+    return !error;
 }
 
 // settimer(func, dt, simtime) extension function.  The first argument
@@ -626,8 +641,9 @@ naRef FGNasalSys::setListener(int argc, naRef* args)
 
     FGNasalListener *nl = new FGNasalListener(node, handler, this,
             gcSave(handler));
-    _listener[_listenerId] = nl;
     node->addChangeListener(nl, initial);
+
+    _listener[_listenerId] = nl;
     return naNum(_listenerId++);
 }
 
@@ -647,6 +663,51 @@ naRef FGNasalSys::removeListener(int argc, naRef* args)
     nl->_node->removeChangeListener(nl);
     _listener.erase(i);
     delete nl;
-    return id;
+    return naNum(_listener.size());
+}
+
+
+
+// FGNasalModelData class.  If sgLoad3DModel() is called with a pointer to
+// such a class, then it lets modelLoaded() run the <load> script, and the
+// destructor the <unload> script. The latter happens when the model branch
+// is removed from the scene graph.
+
+void FGNasalModelData::modelLoaded(const string& path, SGPropertyNode *prop,
+                                   ssgBranch *)
+{
+    SGPropertyNode *n = prop->getNode("nasal"), *load;
+    if (!n)
+        return;
+
+    load = n->getNode("load");
+    _unload = n->getNode("unload");
+    if (!load && !_unload)
+        return;
+
+    _module = path;
+    const char *s = load ? load->getStringValue() : "";
+    FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal");
+    nas->createModule(_module.c_str(), _module.c_str(), s, strlen(s));
+}
+
+FGNasalModelData::~FGNasalModelData()
+{
+    if (_module.empty())
+        return;
+
+    FGNasalSys *nas = (FGNasalSys *)globals->get_subsystem("nasal");
+    if (!nas) {
+        SG_LOG(SG_NASAL, SG_ALERT, "Trying to run an <unload> script "
+                "without Nasal subsystem present.");
+        return;
+    }
+
+    if (_unload) {
+        const char *s = _unload->getStringValue();
+        nas->createModule(_module.c_str(), _module.c_str(), s, strlen(s));
+    }
+    nas->deleteModule(_module.c_str());
 }
 
+