From 3a03671566c2c0b307e0282067ad3425d68e7679 Mon Sep 17 00:00:00 2001 From: mfranz Date: Mon, 15 Oct 2007 16:28:40 +0000 Subject: [PATCH] - add argc/argv arguments to FGNasalSys::call - add support for childAdded/childRemoved listeners - use regular function arguments for property ghosts - warning-- --- src/Scripting/NasalSys.cxx | 68 +++++++++++++++++++++++++++----------- src/Scripting/NasalSys.hxx | 12 ++++--- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index 86dbfdff6..6fbb4db55 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -80,12 +80,12 @@ FGNasalSys::FGNasalSys() // 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, naRef locals) +naRef FGNasalSys::call(naRef code, int argc, naRef* args, naRef locals) { naContext ctx = naNewContext(); if(_callCount) naModUnlock(); _callCount++; - naRef result = naCall(ctx, code, 0, 0, naNil(), locals); + naRef result = naCall(ctx, code, argc, args, naNil(), locals); if(naGetError(ctx)) logError(ctx); _callCount--; @@ -111,7 +111,7 @@ bool FGNasalSys::parseAndRun(const char* sourceCode) strlen(sourceCode)); if(naIsNil(code)) return false; - call(code, naNil()); + call(code, 0, 0, naNil()); return true; } @@ -586,7 +586,7 @@ static naRef f_airportinfo(naContext c, naRef me, int argc, naRef* args) // Table of extension functions. Terminate with zeros. -static struct { char* name; naCFunction func; } funcs[] = { +static struct { const char* name; naCFunction func; } funcs[] = { { "getprop", f_getprop }, { "setprop", f_setprop }, { "print", f_print }, @@ -792,7 +792,7 @@ void FGNasalSys::createModule(const char* moduleName, const char* fileName, _cmdArg = (SGPropertyNode*)arg; - call(code, locals); + call(code, 0, 0, locals); hashset(_globals, moduleName, locals); } @@ -845,7 +845,7 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg) // code doesn't need it. _cmdArg = (SGPropertyNode*)arg; - call(code, locals); + call(code, 0, 0, locals); return true; } @@ -889,7 +889,7 @@ void FGNasalSys::setTimer(naContext c, int argc, naRef* args) void FGNasalSys::handleTimer(NasalTimer* t) { - call(t->handler, naNil()); + call(t->handler, 0, 0, naNil()); gcRelease(t->gcKey); } @@ -944,9 +944,9 @@ naRef FGNasalSys::setListener(naContext c, int argc, naRef* args) return naNil(); } - bool persistent = argc > 3 ? naTrue(args[3]) : true; + int type = argc > 3 && naIsNum(args[3]) ? args[3].num : 1; FGNasalListener *nl = new FGNasalListener(node, handler, this, - gcSave(handler), _listenerId, persistent); + gcSave(handler), _listenerId, type); bool initial = argc > 2 && naTrue(args[2]); node->addChangeListener(nl, initial); @@ -984,17 +984,16 @@ naRef FGNasalSys::removeListener(naContext c, int argc, naRef* args) // FGNasalListener class. FGNasalListener::FGNasalListener(SGPropertyNode_ptr node, naRef handler, - FGNasalSys* nasal, int key, int id, - bool persistent) : + FGNasalSys* nasal, int key, int id, int type) : _node(node), _handler(handler), _gcKey(key), _id(id), _nas(nasal), + _type(type), _active(0), _dead(false), _first_call(true), - _persistent(persistent), _last_int(0L), _last_float(0.0) { @@ -1006,21 +1005,50 @@ FGNasalListener::~FGNasalListener() _nas->gcRelease(_gcKey); } -void FGNasalListener::valueChanged(SGPropertyNode* node) +void FGNasalListener::call(SGPropertyNode* cmdarg, int argc, naRef* args) { - // drop recursive listener calls if(_active || _dead) return; - if(_persistent || changed(node) || _first_call) { - SG_LOG(SG_NASAL, SG_DEBUG, "trigger listener #" << _id); - _active++; - _nas->_cmdArg = node; - _nas->call(_handler, naNil()); - _active--; + SG_LOG(SG_NASAL, SG_DEBUG, "trigger listener #" << _id); + _active++; + _nas->_cmdArg = cmdarg; + _nas->call(_handler, argc, args, naNil()); + _active--; +} + +void FGNasalListener::valueChanged(SGPropertyNode* node) +{ + if(_type < 2 && node != _node) + return; + + if(_type > 0 || changed(_node) || _first_call) { + naRef arg[3]; + arg[0] = _nas->propNodeGhost(_node); + arg[1] = _nas->propNodeGhost(node); + arg[2] = naNil(); + call(_node, 3, arg); } _first_call = false; } +void FGNasalListener::childAdded(SGPropertyNode* parent, SGPropertyNode* child) +{ + naRef arg[3]; + arg[0] = _nas->propNodeGhost(_node); + arg[1] = _nas->propNodeGhost(child); + arg[2] = naNum(1); + call(parent, 3, arg); +} + +void FGNasalListener::childRemoved(SGPropertyNode* parent, SGPropertyNode* child) +{ + naRef arg[3]; + arg[0] = _nas->propNodeGhost(_node); + arg[1] = _nas->propNodeGhost(child); + arg[2] = naNum(0); + call(parent, 3, arg); +} + bool FGNasalListener::changed(SGPropertyNode* node) { SGPropertyNode::Type type = node->getType(); diff --git a/src/Scripting/NasalSys.hxx b/src/Scripting/NasalSys.hxx index 99ef409d6..9fcc98ae9 100644 --- a/src/Scripting/NasalSys.hxx +++ b/src/Scripting/NasalSys.hxx @@ -58,7 +58,7 @@ public: void deleteModule(const char* moduleName); - naRef call(naRef code, naRef locals); + naRef call(naRef code, int argc, naRef* args, naRef locals); private: friend class FGNasalScript; @@ -132,23 +132,27 @@ private: class FGNasalListener : public SGPropertyChangeListener { public: FGNasalListener(SGPropertyNode_ptr node, naRef handler, - FGNasalSys* nasal, int key, int id, bool persistent); + FGNasalSys* nasal, int key, int id, int type); ~FGNasalListener(); void valueChanged(SGPropertyNode* node); - bool changed(SGPropertyNode* node); + void childAdded(SGPropertyNode* parent, SGPropertyNode* child); + void childRemoved(SGPropertyNode* parent, SGPropertyNode* child); private: + bool changed(SGPropertyNode* node); + void call(SGPropertyNode* cmdarg, int argc, naRef* args); + friend class FGNasalSys; SGPropertyNode_ptr _node; naRef _handler; int _gcKey; int _id; FGNasalSys* _nas; + int _type; unsigned int _active; bool _dead; bool _first_call; - bool _persistent; long _last_int; double _last_float; string _last_string; -- 2.39.5