X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScripting%2FNasalSys.cxx;h=870d6def1455f0831e095243af62223d333bb799;hb=9c28ed02577e6d32e1365567107adbd048f3d743;hp=d198a3a069444f4339671f6677713e9c7a67d8eb;hpb=b3ce2c3cfe91358f59a00c42606c86bba4c25e6c;p=flightgear.git diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index d198a3a06..870d6def1 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -71,7 +71,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(); @@ -86,11 +86,11 @@ FGNasalScript* FGNasalSys::parseScript(const char* src, const char* name) char buf[256]; if(!name) { - sprintf(buf, "FGNasalScript@%8.8x", (int)script); + sprintf(buf, "FGNasalScript@%p", script); name = buf; } - script->_code = parse(name, src); + script->_code = parse(name, src, strlen(src)); if(naIsNil(script->_code)) { delete script; return 0; @@ -116,11 +116,11 @@ void FGNasalSys::hashset(naRef hash, const char* key, naRef val) // is the utility function that walks the property tree. // Future enhancement: support integer arguments to specify array // elements. -static SGPropertyNode* findnode(naContext c, naRef vec, int len) +static SGPropertyNode* findnode(naContext c, naRef* vec, int len) { SGPropertyNode* p = globals->get_props(); for(int i=0; igetNode(naStr_data(a)); if(p == 0) return 0; @@ -131,9 +131,9 @@ static SGPropertyNode* findnode(naContext c, naRef vec, int len) // getprop() extension function. Concatenates its string arguments as // property names and returns the value of the specified property. Or // nil if it doesn't exist. -static naRef f_getprop(naContext c, naRef args) +static naRef f_getprop(naContext c, naRef me, int argc, naRef* args) { - const SGPropertyNode* p = findnode(c, args, naVec_size(args)); + const SGPropertyNode* p = findnode(c, args, argc); if(!p) return naNil(); switch(p->getType()) { @@ -143,12 +143,14 @@ static naRef f_getprop(naContext c, naRef args) return naNum(p->getDoubleValue()); case SGPropertyNode::STRING: + case SGPropertyNode::UNSPECIFIED: { naRef nastr = naNewString(c); const char* val = p->getStringValue(); naStr_fromdata(nastr, (char*)val, strlen(val)); return nastr; } + case SGPropertyNode::ALIAS: // <--- FIXME, recurse? default: return naNil(); } @@ -157,16 +159,15 @@ static naRef f_getprop(naContext c, naRef args) // setprop() extension function. Concatenates its string arguments as // property names and sets the value of the specified property to the // final argument. -static naRef f_setprop(naContext c, naRef args) +static naRef f_setprop(naContext c, naRef me, int argc, naRef* args) { #define BUFLEN 1024 - int argc = naVec_size(args); char buf[BUFLEN + 1]; buf[BUFLEN] = 0; char* p = buf; int buflen = BUFLEN; for(int i=0; iget_props(); - naRef val = naVec_get(args, argc-1); + naRef val = args[argc-1]; if(naIsString(val)) props->setStringValue(buf, naStr_data(val)); else props->setDoubleValue(buf, naNumValue(val).num); return naNil(); @@ -188,16 +189,17 @@ static naRef f_setprop(naContext c, naRef args) // print() extension function. Concatenates and prints its arguments // to the FlightGear log. Uses the highest log level (SG_ALERT), to // make sure it appears. Is there better way to do this? -static naRef f_print(naContext c, naRef args) +static naRef f_print(naContext c, naRef me, int argc, naRef* args) { #define BUFLEN 1024 char buf[BUFLEN + 1]; buf[BUFLEN] = 0; // extra nul to handle strncpy brain damage + buf[0] = 0; // Zero-length in case there are no arguments char* p = buf; int buflen = BUFLEN; - int n = naVec_size(args); + int n = argc; for(int i=0; iget_commands()->execute(naStr_data(cmd), *node); return naNil(); @@ -225,16 +227,16 @@ static naRef f_fgcommand(naContext c, naRef args) // settimer(func, dt, simtime) extension function. Falls through to // FGNasalSys::setTimer(). See there for docs. -static naRef f_settimer(naContext c, naRef args) +static naRef f_settimer(naContext c, naRef me, int argc, naRef* args) { FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal"); - nasal->setTimer(args); + nasal->setTimer(argc, args); return naNil(); } // Returns a ghost handle to the argument to the currently executing // command -static naRef f_cmdarg(naContext c, naRef args) +static naRef f_cmdarg(naContext c, naRef me, int argc, naRef* args) { FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal"); return nasal->cmdArgGhost(); @@ -244,15 +246,15 @@ static naRef f_cmdarg(naContext c, naRef args) // ghost (SGPropertyNode_ptr*) or a string (global property path) to // interpolate. The second argument is a vector of pairs of // value/delta numbers. -static naRef f_interpolate(naContext c, naRef args) +static naRef f_interpolate(naContext c, naRef me, int argc, naRef* args) { SGPropertyNode* node; - naRef prop = naVec_get(args, 0); + 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 naNil(); - naRef curve = naVec_get(args, 1); + naRef curve = argc > 1 ? args[1] : naNil(); if(!naIsVector(curve)) return naNil(); int nPoints = naVec_size(curve) / 2; double* values = new double[nPoints]; @@ -264,9 +266,14 @@ static naRef f_interpolate(naContext c, naRef args) ((SGInterpolator*)globals->get_subsystem("interpolator")) ->interpolate(node, nPoints, values, deltas); + + return naNil(); } -static naRef f_rand(naContext c, naRef args) +// This is a better RNG than the one in the default Nasal distribution +// (which is based on the C library rand() implementation). It will +// override. +static naRef f_rand(naContext c, naRef me, int argc, naRef* args) { return naNum(sg_random()); } @@ -330,7 +337,7 @@ void FGNasalSys::init() fullpath.append(dent->d_name); SGPath file(dent->d_name); if(file.extension() != "nas") continue; - readScriptFile(fullpath, file.base().c_str()); + loadModule(fullpath, file.base().c_str()); } // Pull scripts out of the property tree, too @@ -350,20 +357,37 @@ void FGNasalSys::loadPropertyScripts() if(n->hasChild("module")) module = n->getStringValue("module"); + // allow multiple files to be specified within in a single + // Nasal module tag + int j = 0; + SGPropertyNode *fn; + bool file_specified = false; + while ( (fn = n->getChild("file", j)) != NULL ) { + file_specified = true; + const char* file = fn->getStringValue(); + SGPath p(globals->get_fg_root()); + p.append(file); + loadModule(p, module); + j++; + } + + // Old code which only allowed a single file to be specified per module + /* const char* file = n->getStringValue("file"); if(!n->hasChild("file")) file = 0; // Hrm... if(file) { SGPath p(globals->get_fg_root()); p.append(file); - readScriptFile(p, module); + loadModule(p, module); } + */ const char* src = n->getStringValue("script"); if(!n->hasChild("script")) src = 0; // Hrm... if(src) - initModule(module, n->getPath(), src, strlen(src)); + createModule(module, n->getPath(), src, strlen(src)); - if(!file && !src) + if(!file_specified && !src) SG_LOG(SG_NASAL, SG_ALERT, "Nasal error: " << "no or