]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scripting/NasalSys.cxx
Expose SGCondition as a ghost to Nasal directly.
[flightgear.git] / src / Scripting / NasalSys.cxx
index 5f67b2c13c63fa63eb3920c85a7134ee144ca66f..b38e0fbcd35137e43dd8d7cc8d78281380068995 100644 (file)
@@ -13,6 +13,7 @@
 #include <sys/stat.h>
 #include <fstream>
 #include <sstream>
+#include <algorithm> // for std::sort
 
 #include <simgear/nasal/nasal.h>
 #include <simgear/props/props.hxx>
 
 #include "NasalSys.hxx"
 #include "NasalPositioned.hxx"
+#include "NasalCanvas.hxx"
+#include "NasalClipboard.hxx"
+#include "NasalCondition.hxx"
+
 #include <Main/globals.hxx>
 #include <Main/util.hxx>
 #include <Main/fg_props.hxx>
 
+
 using std::map;
 
 static FGNasalSys* nasalSys = 0;
@@ -98,18 +104,38 @@ FGNasalSys::FGNasalSys()
     _callCount = 0;
 }
 
+// Utility.  Sets a named key in a hash by C string, rather than nasal
+// string object.
+void FGNasalSys::hashset(naRef hash, const char* key, naRef val)
+{
+    naRef s = naNewString(_context);
+    naStr_fromdata(s, (char*)key, strlen(key));
+    naHash_set(hash, s, val);
+}
+
+void FGNasalSys::globalsSet(const char* key, naRef val)
+{
+  hashset(_globals, key, val);
+}
+
+naRef FGNasalSys::call(naRef code, int argc, naRef* args, naRef locals)
+{
+  return callMethod(code, naNil(), argc, args, locals);
+}
+
 // Does a naCall() in a new context.  Wrapped here to make lock
 // tracking easier.  Extension functions are called with the lock, but
 // we have to release it before making a new naCall().  So rather than
 // drop the lock in every extension function that might call back into
 // Nasal, we keep a stack depth counter here and only unlock/lock
 // around the naCall if it isn't the first one.
-naRef FGNasalSys::call(naRef code, int argc, naRef* args, naRef locals)
+
+naRef FGNasalSys::callMethod(naRef code, naRef self, int argc, naRef* args, naRef locals)
 {
     naContext ctx = naNewContext();
     if(_callCount) naModUnlock();
     _callCount++;
-    naRef result = naCall(ctx, code, argc, args, naNil(), locals);
+    naRef result = naCall(ctx, code, argc, args, self, locals);
     if(naGetError(ctx))
         logError(ctx);
     _callCount--;
@@ -161,15 +187,6 @@ FGNasalScript* FGNasalSys::parseScript(const char* src, const char* name)
     return script;
 }
 
-// Utility.  Sets a named key in a hash by C string, rather than nasal
-// string object.
-void FGNasalSys::hashset(naRef hash, const char* key, naRef val)
-{
-    naRef s = naNewString(_context);
-    naStr_fromdata(s, (char*)key, strlen(key));
-    naHash_set(hash, s, val);
-}
-
 // The get/setprop functions accept a *list* of strings and walk
 // through the property tree with them to find the appropriate node.
 // This allows a Nasal object to hold onto a property path and use it
@@ -529,7 +546,7 @@ void FGNasalSys::init()
         hashset(_globals, funcs[i].name,
                 naNewFunc(_context, naNewCCode(_context, funcs[i].func)));
 
-    initNasalPositioned(_globals, _context);
+
   
     // And our SGPropertyNode wrapper
     hashset(_globals, "props", genPropsModule());
@@ -540,6 +557,11 @@ void FGNasalSys::init()
     _gcHash = naNewHash(_context);
     hashset(_globals, "__gcsave", _gcHash);
 
+    initNasalPositioned(_globals, _context, _gcHash);
+    initNasalCanvas(_globals, _context, _gcHash);
+    NasalClipboard::init(this);
+    initNasalCondition(_globals, _context, _gcHash);
+  
     // Now load the various source files in the Nasal directory
     simgear::Dir nasalDir(SGPath(globals->get_fg_root(), "Nasal"));
     loadScriptDirectory(nasalDir);
@@ -561,10 +583,16 @@ void FGNasalSys::init()
 
     // Pull scripts out of the property tree, too
     loadPropertyScripts();
+  
+    // now Nasal modules are loaded, we can do some delayed work
+    postinitNasalPositioned(_globals, _context);
 }
 
 void FGNasalSys::update(double)
 {
+    if( NasalClipboard::getInstance() )
+        NasalClipboard::getInstance()->update();
+
     if(!_dead_listener.empty()) {
         vector<FGNasalListener *>::iterator it, end = _dead_listener.end();
         for(it = _dead_listener.begin(); it != end; ++it) delete *it;
@@ -804,11 +832,12 @@ naRef FGNasalSys::parse(const char* filename, const char* buf, int len)
     return naBindFunction(_context, code, _globals);
 }
 
-bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
+bool FGNasalSys::handleCommand( const char* moduleName,
+                                const char* fileName,
+                                const char* src,
+                                const SGPropertyNode* arg )
 {
-    const char* nasal = arg->getStringValue("script");
-    const char* moduleName = arg->getStringValue("module");
-    naRef code = parse(arg->getPath(true).c_str(), nasal, strlen(nasal));
+    naRef code = parse(fileName, src, strlen(src));
     if(naIsNil(code)) return false;
 
     // Commands can be run "in" a module.  Make sure that module
@@ -833,6 +862,17 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
     return true;
 }
 
+bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
+{
+  const char* src = arg->getStringValue("script");
+  const char* moduleName = arg->getStringValue("module");
+
+  return handleCommand( moduleName,
+                        arg ? arg->getPath(true).c_str() : moduleName,
+                        src,
+                        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