]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scripting/NasalSys.cxx
Add an srand() function to nasal (hooked into sg_srandom_time()).
[flightgear.git] / src / Scripting / NasalSys.cxx
index d999cc8cb2b7ef2913ab76de6c6350a078f75fdc..4bbe082958842bf1ce309034ffd3f3a9e9b40f91 100644 (file)
@@ -16,6 +16,7 @@
 #include <Main/fg_props.hxx>
 
 #include "NasalSys.hxx"
+#include "NasalDisplay.hxx"
 
 // Read and return file contents in a single buffer.  Note use of
 // stat() to get the file size.  This is a win32 function, believe it
@@ -71,7 +72,7 @@ bool FGNasalSys::parseAndRun(const char* sourceCode)
     if(naIsNil(code))
         return false;
 
-    naCall(_context, code, naNil(), naNil(), naNil());
+    naCall(_context, code, 0, 0, naNil(), naNil());
 
     if(!naGetError(_context)) return true;
     logError();
@@ -234,6 +235,15 @@ static naRef f_settimer(naContext c, naRef me, int argc, naRef* args)
     return naNil();
 }
 
+// setlistener(func, property) extension function.  Falls through to
+// FGNasalSys::setListener().  See there for docs.
+static naRef f_setlistener(naContext c, naRef me, int argc, naRef* args)
+{
+    FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal");
+    nasal->setListener(argc, args);
+    return naNil();
+}
+
 // Returns a ghost handle to the argument to the currently executing
 // command
 static naRef f_cmdarg(naContext c, naRef me, int argc, naRef* args)
@@ -278,6 +288,40 @@ static naRef f_rand(naContext c, naRef me, int argc, naRef* args)
     return naNum(sg_random());
 }
 
+static naRef f_srand(naContext c, naRef me, int argc, naRef* args)
+{
+    sg_srandom_time();
+    return naNum(0);
+}
+
+// Wrapper function for screenPrint
+static naRef f_screenPrint(naContext c, naRef me, int argc, naRef* args)
+{
+    if(argc != 1 || !naIsString(args[0]))
+        naRuntimeError(c, "bad arguments to screenPrint()");
+    naRef lmsg = args[0];
+    FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal");
+    nasal->screenPrint(naStr_data(lmsg));
+    return naNil();
+}
+
+// Return an array listing of all files in a directory
+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();
+    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);
+    return result;
+}
+
 // Table of extension functions.  Terminate with zeros.
 static struct { char* name; naCFunction func; } funcs[] = {
     { "getprop",   f_getprop },
@@ -285,9 +329,13 @@ static struct { char* name; naCFunction func; } funcs[] = {
     { "print",     f_print },
     { "_fgcommand", f_fgcommand },
     { "settimer",  f_settimer },
+    { "_setlistener", f_setlistener },
     { "_cmdarg",  f_cmdarg },
     { "_interpolate",  f_interpolate },
     { "rand",  f_rand },
+    { "srand",  f_srand },
+    { "screenPrint", f_screenPrint },
+    { "directory", f_directory },
     { 0, 0 }
 };
 
@@ -444,7 +492,7 @@ void FGNasalSys::createModule(const char* moduleName, const char* fileName,
     if(!naHash_get(_globals, modname, &locals))
         locals = naNewHash(_context);
 
-    naCall(_context, code, naNil(), naNil(), locals);
+    naCall(_context, code, 0, 0, naNil(), locals);
     if(naGetError(_context)) {
         logError();
         return;
@@ -489,7 +537,7 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
     _cmdArg = (SGPropertyNode*)arg;
 
     // Call it!
-    naRef result = naCall(_context, code, naNil(), naNil(), locals);
+    naRef result = naCall(_context, code, 0, 0, naNil(), locals);
     if(!naGetError(_context)) return true;
     logError();
     return false;
@@ -498,7 +546,7 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
 // settimer(func, dt, simtime) extension function.  The first argument
 // is a Nasal function to call, the second is a delta time (from now),
 // in seconds.  The third, if present, is a boolean value indicating
-// that "simulator" time (rather than real time) is to be used.
+// that "real world" time (rather than simulator time) is to be used.
 //
 // Implementation note: the FGTimer objects don't live inside the
 // garbage collector, so the Nasal handler functions have to be
@@ -515,7 +563,7 @@ void FGNasalSys::setTimer(int argc, naRef* args)
     naRef delta = argc > 1 ? args[1] : naNil();
     if(naIsNil(delta)) return;
     
-    bool simtime = (argc > 2 && naTrue(args[2])) ? true : false;
+    bool simtime = (argc > 2 && naTrue(args[2])) ? false : true;
 
     // Generate and register a C++ timer handler
     NasalTimer* t = new NasalTimer;
@@ -530,7 +578,7 @@ void FGNasalSys::setTimer(int argc, naRef* args)
 
 void FGNasalSys::handleTimer(NasalTimer* t)
 {
-    naCall(_context, t->handler, naNil(), naNil(), naNil());
+    naCall(_context, t->handler, 0, 0, naNil(), naNil());
     if(naGetError(_context))
         logError();
     gcRelease(t->gcKey);
@@ -553,3 +601,27 @@ void FGNasalSys::NasalTimer::timerExpired()
     nasal->handleTimer(this);
     delete this;
 }
+
+// setlistener(property, func) extension function.  The first argument
+// is either a ghost (SGPropertyNode_ptr*) or a string (global property
+// path), the second is a Nasal function.
+void FGNasalSys::setListener(int argc, naRef* args)
+{
+    SGPropertyNode* node;
+    naRef prop = argc > 0 ? args[0] : naNil();
+    if(naIsString(prop)) node = fgGetNode(naStr_data(prop), true);
+    else if(naIsGhost(prop)) node = *(SGPropertyNode_ptr*)naGhost_ptr(prop);
+    else return;
+
+    naRef handler = argc > 1 ? args[1] : naNil();
+    if(!(naIsCode(handler) || naIsCCode(handler) || naIsFunc(handler)))
+        return;
+
+    node->addChangeListener(new FGNasalListener(handler, this, gcSave(handler)));
+}
+
+// functions providing access to the NasalDisplay - used to display text directly on the screen
+void FGNasalSys::screenPrint(const char* src)
+{
+  globals->get_Nasal_display()->RegisterSingleMessage(src, 0);
+}