X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScripting%2FNasalSys.cxx;h=aee1dc54d94e4b556f81d4c14fead7fa8a2d0be8;hb=12076bce0e9fb66286f14931e8f4eb12fc0b9b82;hp=5f67b2c13c63fa63eb3920c85a7134ee144ca66f;hpb=f5a79fc89390d0b0ba85818b23f44061b0873e36;p=flightgear.git diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index 5f67b2c13..aee1dc54d 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -26,10 +26,15 @@ #include "NasalSys.hxx" #include "NasalPositioned.hxx" +#include "NasalCanvas.hxx" +#include "NasalClipboard.hxx" +#include "NasalCondition.hxx" + #include
#include
#include
+ using std::map; static FGNasalSys* nasalSys = 0; @@ -98,18 +103,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 +186,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 @@ -209,7 +225,7 @@ static naRef f_getprop(naContext c, naRef me, int argc, naRef* args) case props::DOUBLE: { double dv = p->getDoubleValue(); - if (osg::isNaN(dv)) { + if (SGMisc::isNaN(dv)) { SG_LOG(SG_NASAL, SG_ALERT, "Nasal getprop: property " << p->getPath() << " is NaN"); return naNil(); } @@ -264,7 +280,7 @@ static naRef f_setprop(naContext c, naRef me, int argc, naRef* args) if(naIsNil(n)) naRuntimeError(c, "setprop() value is not string or number"); - if (osg::isNaN(n.num)) { + if (SGMisc::isNaN(n.num)) { naRuntimeError(c, "setprop() passed a NaN"); } @@ -529,7 +545,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 +556,11 @@ void FGNasalSys::init() _gcHash = naNewHash(_context); hashset(_globals, "__gcsave", _gcHash); + initNasalPositioned(_globals, _context, _gcHash); + NasalClipboard::init(this); + initNasalCanvas(_globals, _context, _gcHash); + 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 +582,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::iterator it, end = _dead_listener.end(); for(it = _dead_listener.begin(); it != end; ++it) delete *it; @@ -607,10 +634,8 @@ bool pathSortPredicate(const SGPath& p1, const SGPath& p2) void FGNasalSys::loadScriptDirectory(simgear::Dir nasalDir) { simgear::PathList scripts = nasalDir.children(simgear::Dir::TYPE_FILE, ".nas"); - // sort scripts, avoid loading sequence effects due to file system's - // random directory order - std::sort(scripts.begin(), scripts.end(), pathSortPredicate); - + // Note: simgear::Dir already reports file entries in a deterministic order, + // so a fixed loading sequence is guaranteed (same for every user) for (unsigned int i=0; igetStringValue("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 +859,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