]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scripting/NasalSys.cxx
Don't restore initial screen geometry because there is nothing in fg_os* to resize...
[flightgear.git] / src / Scripting / NasalSys.cxx
index 539ac763b00a426138b51d71af5077d318e89952..c0b25c4eaf47377baa79a1279da23315840800ef 100644 (file)
@@ -361,6 +361,11 @@ void FGNasalSys::init()
     // Add in the math library under "math"
     hashset(_globals, "math", naMathLib(_context));
 
+    // Add in the IO library.  Disabled currently until after the
+    // 0.9.10 release.
+    // hashset(_globals, "io", naIOLib(_context));
+    // hashset(_globals, "bits", naBitsLib(_context));
+
     // Add our custom extension functions:
     for(i=0; funcs[i].name; i++)
         hashset(_globals, funcs[i].name,
@@ -387,6 +392,7 @@ void FGNasalSys::init()
         if(file.extension() != "nas") continue;
         loadModule(fullpath, file.base().c_str());
     }
+    ulCloseDir(dir);
 
     // Pull scripts out of the property tree, too
     loadPropertyScripts();
@@ -533,12 +539,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
@@ -546,10 +553,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
@@ -660,3 +672,87 @@ naRef FGNasalSys::removeListener(int argc, naRef* args)
     return naNum(_listener.size());
 }
 
+
+
+// FGNasalListener class.
+
+FGNasalListener::FGNasalListener(SGPropertyNode_ptr node, naRef handler,
+                                 FGNasalSys* nasal, int key) :
+    _node(node),
+    _handler(handler),
+    _gcKey(key),
+    _nas(nasal),
+    _active(0)
+{
+}
+
+FGNasalListener::~FGNasalListener()
+{
+    _nas->gcRelease(_gcKey);
+}
+
+void FGNasalListener::valueChanged(SGPropertyNode* node)
+{
+    if (_active) {
+        SG_LOG(SG_NASAL, SG_ALERT, "Recursive listener call "
+                "on property " << node->getPath());
+        return;
+    }
+    _active++;
+    _nas->_cmdArg = node;
+    naContext c = naNewContext();
+    naModUnlock();
+    naCall(c, _handler, 0, 0, naNil(), naNil());
+    naModLock();
+    if(naGetError(c))
+        _nas->logError(c);
+    naFreeContext(c);
+    _active--;
+}
+
+
+
+
+// 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());
+}
+
+