X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScripting%2Fnasal-props.cxx;h=9f309903a11b7401a2b7992a49926bd53da9ab89;hb=8545e5926a5afbd1299b940a087fcf5c8e19bb90;hp=c76762bfd62003c7ed08276dd570af4af6bfa5ad;hpb=2a70b874932b7caa9ee319a455c4272ae983efd7;p=flightgear.git diff --git a/src/Scripting/nasal-props.cxx b/src/Scripting/nasal-props.cxx index c76762bfd..9f309903a 100644 --- a/src/Scripting/nasal-props.cxx +++ b/src/Scripting/nasal-props.cxx @@ -3,6 +3,9 @@ # include "config.h" #endif +#include + +#include #include #include @@ -10,6 +13,8 @@ #include "NasalSys.hxx" +using namespace std; + // Implementation of a Nasal wrapper for the SGPropertyNode class, // using the Nasal "ghost" (er... Garbage collection Handle for // OutSide Thingy) facility. @@ -26,7 +31,7 @@ static void propNodeGhostDestroy(void* ghost) delete prop; } -naGhostType PropNodeGhostType = { propNodeGhostDestroy }; +naGhostType PropNodeGhostType = { propNodeGhostDestroy, "prop" }; static naRef propNodeGhostCreate(naContext c, SGPropertyNode* n) { @@ -58,18 +63,22 @@ naRef FGNasalSys::propNodeGhost(SGPropertyNode* handle) static naRef f_getType(naContext c, naRef me, int argc, naRef* args) { + using namespace simgear; NODEARG(); - char* t = "unknown"; + const char* t = "unknown"; switch((*node)->getType()) { - case SGPropertyNode::NONE: t = "NONE"; break; - case SGPropertyNode::ALIAS: t = "ALIAS"; break; - case SGPropertyNode::BOOL: t = "BOOL"; break; - case SGPropertyNode::INT: t = "INT"; break; - case SGPropertyNode::LONG: t = "LONG"; break; - case SGPropertyNode::FLOAT: t = "FLOAT"; break; - case SGPropertyNode::DOUBLE: t = "DOUBLE"; break; - case SGPropertyNode::STRING: t = "STRING"; break; - case SGPropertyNode::UNSPECIFIED: t = "UNSPECIFIED"; break; + case props::NONE: t = "NONE"; break; + case props::ALIAS: t = "ALIAS"; break; + case props::BOOL: t = "BOOL"; break; + case props::INT: t = "INT"; break; + case props::LONG: t = "LONG"; break; + case props::FLOAT: t = "FLOAT"; break; + case props::DOUBLE: t = "DOUBLE"; break; + case props::STRING: t = "STRING"; break; + case props::UNSPECIFIED: t = "UNSPECIFIED"; break; + case props::VEC3D: t = "VEC3D"; break; + case props::VEC4D: t = "VEC4D"; break; + case props::EXTENDED: t = "EXTENDED"; break; // shouldn't happen } return NASTR(t); } @@ -77,18 +86,19 @@ static naRef f_getType(naContext c, naRef me, int argc, naRef* args) static naRef f_getAttribute(naContext c, naRef me, int argc, naRef* args) { NODEARG(); - if(naVec_size(argv) == 0) return naNum((*node)->getAttributes()); + if(naVec_size(argv) == 0) return naNum(unsigned((*node)->getAttributes())); naRef val = naVec_get(argv, 0); - char *a = naStr_data(val); + const char *a = naStr_data(val); SGPropertyNode::Attribute attr; if(!a) a = ""; - if(!strcmp(a, "children")) return naNum((*node)->nChildren()); + if(!strcmp(a, "last")) return naNum(SGPropertyNode::LAST_USED_ATTRIBUTE); + else if(!strcmp(a, "children")) return naNum((*node)->nChildren()); else if(!strcmp(a, "listeners")) return naNum((*node)->nListeners()); - else if(!strcmp(a, "refcount")) return naNum(node->getNumRefs()); + else if(!strcmp(a, "references")) return naNum(node->getNumRefs()); else if(!strcmp(a, "tied")) return naNum((*node)->isTied()); else if(!strcmp(a, "alias")) return naNum((*node)->isAlias()); - else if(!strcmp(a, "read")) attr = SGPropertyNode::READ; - else if(!strcmp(a, "write")) attr = SGPropertyNode::WRITE; + else if(!strcmp(a, "readable")) attr = SGPropertyNode::READ; + else if(!strcmp(a, "writable")) attr = SGPropertyNode::WRITE; else if(!strcmp(a, "archive")) attr = SGPropertyNode::ARCHIVE; else if(!strcmp(a, "trace-read")) attr = SGPropertyNode::TRACE_READ; else if(!strcmp(a, "trace-write")) attr = SGPropertyNode::TRACE_WRITE; @@ -110,10 +120,10 @@ static naRef f_setAttribute(naContext c, naRef me, int argc, naRef* args) return ret; } SGPropertyNode::Attribute attr; - char *a = naStr_data(val); + const char *a = naStr_data(val); if(!a) a = ""; - if(!strcmp(a, "read")) attr = SGPropertyNode::READ; - else if(!strcmp(a, "write")) attr = SGPropertyNode::WRITE; + if(!strcmp(a, "readable")) attr = SGPropertyNode::READ; + else if(!strcmp(a, "writable")) attr = SGPropertyNode::WRITE; else if(!strcmp(a, "archive")) attr = SGPropertyNode::ARCHIVE; else if(!strcmp(a, "trace-read")) attr = SGPropertyNode::TRACE_READ; else if(!strcmp(a, "trace-write")) attr = SGPropertyNode::TRACE_WRITE; @@ -139,34 +149,77 @@ static naRef f_getIndex(naContext c, naRef me, int argc, naRef* args) return naNum((*node)->getIndex()); } +template +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); + for (int i = 0; i < num_components; ++i) + naVec_set(vector, i, naNum(vec[i])); + return vector; +} + static naRef f_getValue(naContext c, naRef me, int argc, naRef* args) { + using namespace simgear; NODEARG(); switch((*node)->getType()) { - case SGPropertyNode::BOOL: case SGPropertyNode::INT: - case SGPropertyNode::LONG: case SGPropertyNode::FLOAT: - case SGPropertyNode::DOUBLE: + case props::BOOL: case props::INT: + case props::LONG: case props::FLOAT: + case props::DOUBLE: return naNum((*node)->getDoubleValue()); - case SGPropertyNode::STRING: - case SGPropertyNode::UNSPECIFIED: + case props::STRING: + case props::UNSPECIFIED: return NASTR((*node)->getStringValue()); + case props::VEC3D: + return makeVectorFromVec(c, (*node)->getValue()); + case props::VEC4D: + return makeVectorFromVec(c, (*node)->getValue()); default: return naNil(); } } +template +T makeVecFromVector(naRef vector) +{ + T vec; + const int num_components + = sizeof(vec.data()) / sizeof(typename T::value_type); + int size = naVec_size(vector); + + for (int i = 0; i < num_components && i < size; ++i) { + naRef element = naVec_get(vector, i); + naRef n = naNumValue(element); + if (!naIsNil(n)) + vec[i] = n.num; + } + return vec; +} + static naRef f_setValue(naContext c, naRef me, int argc, naRef* args) { NODEARG(); naRef val = naVec_get(argv, 0); - if(naIsString(val)) (*node)->setStringValue(naStr_data(val)); - else { + bool result = false; + if(naIsString(val)) { + result = (*node)->setStringValue(naStr_data(val)); + } else if(naIsVector(val)) { + if(naVec_size(val) == 3) + result = (*node)->setValue(makeVecFromVector(val)); + else if(naVec_size(val) == 4) + result = (*node)->setValue(makeVecFromVector(val)); + else + naRuntimeError(c, "props.setValue() vector value has wrong size"); + } else { naRef n = naNumValue(val); if(naIsNil(n)) naRuntimeError(c, "props.setValue() with non-number"); - (*node)->setDoubleValue(naNumValue(val).num); + result = (*node)->setDoubleValue(naNumValue(val).num); } - return naNil(); + return naNum(result); } static naRef f_setIntValue(naContext c, naRef me, int argc, naRef* args) @@ -183,16 +236,14 @@ static naRef f_setIntValue(naContext c, naRef me, int argc, naRef* args) double tmp2 = tmp1.num; int iv = (int)tmp2; - (*node)->setIntValue(iv); - return naNil(); + return naNum((*node)->setIntValue(iv)); } static naRef f_setBoolValue(naContext c, naRef me, int argc, naRef* args) { NODEARG(); naRef val = naVec_get(argv, 0); - (*node)->setBoolValue(naTrue(val) ? true : false); - return naNil(); + return naNum((*node)->setBoolValue(naTrue(val) ? true : false)); } static naRef f_setDoubleValue(naContext c, naRef me, int argc, naRef* args) @@ -201,8 +252,7 @@ static naRef f_setDoubleValue(naContext c, naRef me, int argc, naRef* args) naRef r = naNumValue(naVec_get(argv, 0)); if(naIsNil(r)) naRuntimeError(c, "props.setDoubleValue() with non-number"); - (*node)->setDoubleValue(r.num); - return naNil(); + return naNum((*node)->setDoubleValue(r.num)); } static naRef f_getParent(naContext c, naRef me, int argc, naRef* args) @@ -266,12 +316,13 @@ static naRef f_removeChild(naContext c, naRef me, int argc, naRef* args) naRef child = naVec_get(argv, 0); naRef index = naVec_get(argv, 1); if(!naIsString(child) || !naIsNum(index)) return naNil(); + SGPropertyNode_ptr n = 0; try { - (*node)->removeChild(naStr_data(child), (int)index.num, false); + n = (*node)->removeChild(naStr_data(child), (int)index.num, false); } catch (const string& err) { naRuntimeError(c, (char *)err.c_str()); } - return naNil(); + return propNodeGhostCreate(c, n); } static naRef f_removeChildren(naContext c, naRef me, int argc, naRef* args) @@ -299,6 +350,34 @@ static naRef f_removeChildren(naContext c, naRef me, int argc, naRef* args) return result; } +static naRef f_alias(naContext c, naRef me, int argc, naRef* args) +{ + NODEARG(); + SGPropertyNode* al; + naRef prop = naVec_get(argv, 0); + try { + if(naIsString(prop)) al = globals->get_props()->getNode(naStr_data(prop), true); + else if(naIsGhost(prop)) al = *(SGPropertyNode_ptr*)naGhost_ptr(prop); + else throw string("props.alias() with bad argument"); + } catch (const string& err) { + naRuntimeError(c, (char *)err.c_str()); + return naNil(); + } + return naNum((*node)->alias(al)); +} + +static naRef f_unalias(naContext c, naRef me, int argc, naRef* args) +{ + NODEARG(); + return naNum((*node)->unalias()); +} + +static naRef f_getAliasTarget(naContext c, naRef me, int argc, naRef* args) +{ + NODEARG(); + return propNodeGhostCreate(c, (*node)->getAliasTarget()); +} + static naRef f_getNode(naContext c, naRef me, int argc, naRef* args) { NODEARG(); @@ -344,6 +423,9 @@ static struct { { f_getChildren, "_getChildren" }, { f_removeChild, "_removeChild" }, { f_removeChildren, "_removeChildren" }, + { f_alias, "_alias" }, + { f_unalias, "_unalias" }, + { f_getAliasTarget, "_getAliasTarget" }, { f_getNode, "_getNode" }, { f_new, "_new" }, { f_globals, "_globals" },