X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScripting%2Fnasal-props.cxx;h=1df4b0d42b93741296eb0229dafb18166b102d1a;hb=688d76613e2ece5fdb0e36b5d836719d7a68830c;hp=9f309903a11b7401a2b7992a49926bd53da9ab89;hpb=e503591af4f16814d78ded49c5979e273d81a0be;p=flightgear.git diff --git a/src/Scripting/nasal-props.cxx b/src/Scripting/nasal-props.cxx index 9f309903a..1df4b0d42 100644 --- a/src/Scripting/nasal-props.cxx +++ b/src/Scripting/nasal-props.cxx @@ -5,9 +5,9 @@ #include -#include #include #include +#include #include
@@ -45,6 +45,15 @@ naRef FGNasalSys::propNodeGhost(SGPropertyNode* handle) return propNodeGhostCreate(_context, handle); } +SGPropertyNode* ghostToPropNode(naRef ref) +{ + if (!naIsGhost(ref) || (naGhost_type(ref) != &PropNodeGhostType)) + return NULL; + + SGPropertyNode_ptr* pp = (SGPropertyNode_ptr*) naGhost_ptr(ref); + return pp->ptr(); +} + #define NASTR(s) s ? naStr_fromdata(naNewString(c),(char*)(s),strlen(s)) : naNil() // @@ -54,17 +63,20 @@ naRef FGNasalSys::propNodeGhost(SGPropertyNode* handle) // array. This allows the Nasal handlers to do things like: // Node.getChild = func { _getChild(me.ghost, arg) } // -#define NODEARG() \ +#define NODENOARG() \ if(argc < 2 || !naIsGhost(args[0]) || \ naGhost_type(args[0]) != &PropNodeGhostType) \ naRuntimeError(c, "bad argument to props function"); \ - SGPropertyNode_ptr* node = (SGPropertyNode_ptr*)naGhost_ptr(args[0]); \ + SGPropertyNode_ptr* node = (SGPropertyNode_ptr*)naGhost_ptr(args[0]); + +#define NODEARG() \ + NODENOARG(); \ naRef argv = args[1] static naRef f_getType(naContext c, naRef me, int argc, naRef* args) { using namespace simgear; - NODEARG(); + NODENOARG(); const char* t = "unknown"; switch((*node)->getType()) { case props::NONE: t = "NONE"; break; @@ -103,6 +115,7 @@ static naRef f_getAttribute(naContext c, naRef me, int argc, naRef* args) else if(!strcmp(a, "trace-read")) attr = SGPropertyNode::TRACE_READ; else if(!strcmp(a, "trace-write")) attr = SGPropertyNode::TRACE_WRITE; else if(!strcmp(a, "userarchive")) attr = SGPropertyNode::USERARCHIVE; + else if(!strcmp(a, "preserve")) attr = SGPropertyNode::PRESERVE; else { naRuntimeError(c, "props.getAttribute() with invalid attribute"); return naNil(); @@ -128,6 +141,7 @@ static naRef f_setAttribute(naContext c, naRef me, int argc, naRef* args) else if(!strcmp(a, "trace-read")) attr = SGPropertyNode::TRACE_READ; else if(!strcmp(a, "trace-write")) attr = SGPropertyNode::TRACE_WRITE; else if(!strcmp(a, "userarchive")) attr = SGPropertyNode::USERARCHIVE; + else if(!strcmp(a, "preserve")) attr = SGPropertyNode::PRESERVE; else { naRuntimeError(c, "props.setAttribute() with invalid attribute"); return naNil(); @@ -139,13 +153,13 @@ static naRef f_setAttribute(naContext c, naRef me, int argc, naRef* args) static naRef f_getName(naContext c, naRef me, int argc, naRef* args) { - NODEARG(); + NODENOARG(); return NASTR((*node)->getName()); } static naRef f_getIndex(naContext c, naRef me, int argc, naRef* args) { - NODEARG(); + NODENOARG(); return naNum((*node)->getIndex()); } @@ -155,7 +169,7 @@ naRef makeVectorFromVec(naContext c, const T& vec) const int num_components = sizeof(vec.data()) / sizeof(typename T::value_type); naRef vector = naNewVector(c); - naVec_setsize(vector, num_components); + naVec_setsize(c, vector, num_components); for (int i = 0; i < num_components; ++i) naVec_set(vector, i, naNum(vec[i])); return vector; @@ -164,12 +178,21 @@ naRef makeVectorFromVec(naContext c, const T& vec) static naRef f_getValue(naContext c, naRef me, int argc, naRef* args) { using namespace simgear; - NODEARG(); + NODENOARG(); switch((*node)->getType()) { case props::BOOL: case props::INT: case props::LONG: case props::FLOAT: case props::DOUBLE: - return naNum((*node)->getDoubleValue()); + { + double dv = (*node)->getDoubleValue(); + if (osg::isNaN(dv)) { + SG_LOG(SG_NASAL, SG_ALERT, "Nasal getValue: property " << (*node)->getPath() << " is NaN"); + return naNil(); + } + + return naNum(dv); + } + case props::STRING: case props::UNSPECIFIED: return NASTR((*node)->getStringValue()); @@ -217,7 +240,13 @@ static naRef f_setValue(naContext c, naRef me, int argc, naRef* args) naRef n = naNumValue(val); if(naIsNil(n)) naRuntimeError(c, "props.setValue() with non-number"); - result = (*node)->setDoubleValue(naNumValue(val).num); + + double d = naNumValue(val).num; + if (osg::isNaN(d)) { + naRuntimeError(c, "props.setValue() passed a NaN"); + } + + result = (*node)->setDoubleValue(d); } return naNum(result); } @@ -250,14 +279,19 @@ static naRef f_setDoubleValue(naContext c, naRef me, int argc, naRef* args) { NODEARG(); naRef r = naNumValue(naVec_get(argv, 0)); - if(naIsNil(r)) + if (naIsNil(r)) naRuntimeError(c, "props.setDoubleValue() with non-number"); + + if (osg::isNaN(r.num)) { + naRuntimeError(c, "props.setDoubleValue() passed a NaN"); + } + return naNum((*node)->setDoubleValue(r.num)); } static naRef f_getParent(naContext c, naRef me, int argc, naRef* args) { - NODEARG(); + NODENOARG(); SGPropertyNode* n = (*node)->getParent(); if(!n) return naNil(); return propNodeGhostCreate(c, n); @@ -368,13 +402,13 @@ static naRef f_alias(naContext c, naRef me, int argc, naRef* args) static naRef f_unalias(naContext c, naRef me, int argc, naRef* args) { - NODEARG(); + NODENOARG(); return naNum((*node)->unalias()); } static naRef f_getAliasTarget(naContext c, naRef me, int argc, naRef* args) { - NODEARG(); + NODENOARG(); return propNodeGhostCreate(c, (*node)->getAliasTarget()); }