#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;
_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--;
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
hashset(_globals, funcs[i].name,
naNewFunc(_context, naNewCCode(_context, funcs[i].func)));
- initNasalPositioned(_globals, _context);
+
// And our SGPropertyNode wrapper
hashset(_globals, "props", genPropsModule());
_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);
// 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;
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
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