]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scripting/NasalSys.cxx
Make the Nasal NaN check less aggressive - still SG_ALERT, but return nil instead...
[flightgear.git] / src / Scripting / NasalSys.cxx
index a210d03569c50bbafbc35ba4bda2f4720e1f9f03..1f952b325c25d05a11dba82efdd76414290bc375 100644 (file)
 #include <fstream>
 #include <sstream>
 
-#include <plib/ul.h>
-
 #include <simgear/nasal/nasal.h>
 #include <simgear/props/props.hxx>
 #include <simgear/math/sg_random.h>
 #include <simgear/misc/sg_path.hxx>
+#include <simgear/misc/sg_dir.hxx>
 #include <simgear/misc/interpolator.hxx>
 #include <simgear/scene/material/mat.hxx>
 #include <simgear/structure/commands.hxx>
@@ -33,6 +32,7 @@
 #include <Main/util.hxx>
 #include <Scenery/scenery.hxx>
 #include <Navaids/navrecord.hxx>
+#include <Navaids/procedure.hxx>
 
 #include "NasalSys.hxx"
 
@@ -186,8 +186,16 @@ static naRef f_getprop(naContext c, naRef me, int argc, naRef* args)
     case props::BOOL:   case props::INT:
     case props::LONG:   case props::FLOAT:
     case props::DOUBLE:
-        return naNum(p->getDoubleValue());
-
+        {
+        double dv = p->getDoubleValue();
+        if (osg::isNaN(dv)) {
+          SG_LOG(SG_GENERAL, SG_ALERT, "Nasal getprop: property " << p->getPath() << " is NaN");
+          return naNil();
+        }
+        
+        return naNum(dv);
+        }
+        
     case props::STRING:
     case props::UNSPECIFIED:
         {
@@ -212,6 +220,7 @@ static naRef f_setprop(naContext c, naRef me, int argc, naRef* args)
     buf[BUFLEN] = 0;
     char* p = buf;
     int buflen = BUFLEN;
+    if(argc < 2) naRuntimeError(c, "setprop() expects at least 2 arguments");
     for(int i=0; i<argc-1; i++) {
         naRef s = naStringValue(c, args[i]);
         if(naIsNil(s)) return naNil();
@@ -233,6 +242,11 @@ static naRef f_setprop(naContext c, naRef me, int argc, naRef* args)
             naRef n = naNumValue(val);
             if(naIsNil(n))
                 naRuntimeError(c, "setprop() value is not string or number");
+                
+            if (osg::isNaN(n.num)) {
+                naRuntimeError(c, "setprop() passed a NaN");
+            }
+            
             result = props->setDoubleValue(buf, n.num);
         }
     } catch (const string& err) {
@@ -362,18 +376,33 @@ static naRef f_directory(naContext c, naRef me, int argc, naRef* args)
 {
     if(argc != 1 || !naIsString(args[0]))
         naRuntimeError(c, "bad arguments to directory()");
-    naRef ldir = args[0];
-    ulDir* dir = ulOpenDir(naStr_data(args[0]));
-    if(!dir) return naNil();
+    
+    simgear::Dir d(SGPath(naStr_data(args[0])));
+    if(!d.exists()) return naNil();
     naRef result = naNewVector(c);
-    ulDirEnt* dent;
-    while((dent = ulReadDir(dir)))
-        naVec_append(result, naStr_fromdata(naNewString(c), dent->d_name,
-                                            strlen(dent->d_name)));
-    ulCloseDir(dir);
+
+    simgear::PathList paths = d.children(simgear::Dir::TYPE_FILE | simgear::Dir::TYPE_DIR);
+    for (unsigned int i=0; i<paths.size(); ++i) {
+      std::string p = paths[i].file();
+      naVec_append(result, naStr_fromdata(naNewString(c), p.c_str(), p.size()));
+    }
+    
     return result;
 }
 
+/**
+ * Given a data path, resolve it in FG_ROOT or an FG_AIRCRFT directory
+ */
+static naRef f_resolveDataPath(naContext c, naRef me, int argc, naRef* args)
+{
+    if(argc != 1 || !naIsString(args[0]))
+        naRuntimeError(c, "bad arguments to resolveDataPath()");
+
+    SGPath p = globals->resolve_maybe_aircraft_path(naStr_data(args[0]));
+    const char* pdata = p.c_str();
+    return naStr_fromdata(naNewString(c), const_cast<char*>(pdata), strlen(pdata));
+}
+
 // Parse XML file.
 //     parsexml(<path> [, <start-tag> [, <end-tag> [, <data> [, <pi>]]]]);
 //
@@ -599,6 +628,28 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args)
           HASHSET("ils_frequency_mhz", 17, naNum(rwy->ILS()->get_freq() / 100.0));
         }
         
+        std::vector<flightgear::SID*> sids(rwy->getSIDs());
+        naRef sidVec = naNewVector(c);
+        
+        for (unsigned int s=0; s < sids.size(); ++s) {
+          naRef procId = naStr_fromdata(naNewString(c),
+                    const_cast<char *>(sids[s]->ident().c_str()),
+                    sids[s]->ident().length());
+          naVec_append(sidVec, procId);
+        }
+        HASHSET("sids", 4, sidVec); 
+        
+        std::vector<flightgear::STAR*> stars(rwy->getSTARs());
+        naRef starVec = naNewVector(c);
+      
+        for (unsigned int s=0; s < stars.size(); ++s) {
+          naRef procId = naStr_fromdata(naNewString(c),
+                    const_cast<char *>(stars[s]->ident().c_str()),
+                    stars[s]->ident().length());
+          naVec_append(starVec, procId);
+        }
+        HASHSET("stars", 5, starVec); 
+
 #undef HASHSET
         naHash_set(rwys, rwyid, rwydata);
     }
@@ -635,6 +686,7 @@ static struct { const char* name; naCFunction func; } funcs[] = {
     { "srand",  f_srand },
     { "abort", f_abort },
     { "directory", f_directory },
+    { "resolvepath", f_resolveDataPath },
     { "parsexml", f_parsexml },
     { "systime", f_systime },
     { "carttogeod", f_carttogeod },
@@ -684,18 +736,14 @@ void FGNasalSys::init()
     hashset(_globals, "__gcsave", _gcHash);
 
     // Now load the various source files in the Nasal directory
-    SGPath p(globals->get_fg_root());
-    p.append("Nasal");
-    ulDirEnt* dent;
-    ulDir* dir = ulOpenDir(p.c_str());
-    while(dir && (dent = ulReadDir(dir)) != 0) {
-        SGPath fullpath(p);
-        fullpath.append(dent->d_name);
-        SGPath file(dent->d_name);
-        if(file.extension() != "nas") continue;
-        loadModule(fullpath, file.base().c_str());
+    simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));
+    simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas");
+    
+    for (unsigned int i=0; i<scripts.size(); ++i) {
+      SGPath fullpath(scripts[i]);
+      SGPath file = fullpath.file();
+      loadModule(fullpath, file.base().c_str());
     }
-    ulCloseDir(dir);
 
     // set signal and remove node to avoid restoring at reinit
     const char *s = "nasal-dir-initialized";
@@ -750,8 +798,7 @@ void FGNasalSys::loadPropertyScripts()
         while((fn = n->getChild("file", j)) != NULL) {
             file_specified = true;
             const char* file = fn->getStringValue();
-            SGPath p(globals->get_fg_root());
-            p.append(file);
+            SGPath p = globals->resolve_maybe_aircraft_path(file);
             loadModule(p, module);
             j++;
         }