1
0
Fork 0

- add argc/argv arguments to FGNasalSys::call

- add support for childAdded/childRemoved listeners
- use regular function arguments for property ghosts
- warning--
This commit is contained in:
mfranz 2007-10-15 16:28:40 +00:00
parent 02a813abde
commit 3a03671566
2 changed files with 56 additions and 24 deletions

View file

@ -80,12 +80,12 @@ FGNasalSys::FGNasalSys()
// drop the lock in every extension function that might call back into // drop the lock in every extension function that might call back into
// Nasal, we keep a stack depth counter here and only unlock/lock // Nasal, we keep a stack depth counter here and only unlock/lock
// around the naCall if it isn't the first one. // 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(); naContext ctx = naNewContext();
if(_callCount) naModUnlock(); if(_callCount) naModUnlock();
_callCount++; _callCount++;
naRef result = naCall(ctx, code, 0, 0, naNil(), locals); naRef result = naCall(ctx, code, argc, args, naNil(), locals);
if(naGetError(ctx)) if(naGetError(ctx))
logError(ctx); logError(ctx);
_callCount--; _callCount--;
@ -111,7 +111,7 @@ bool FGNasalSys::parseAndRun(const char* sourceCode)
strlen(sourceCode)); strlen(sourceCode));
if(naIsNil(code)) if(naIsNil(code))
return false; return false;
call(code, naNil()); call(code, 0, 0, naNil());
return true; 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. // 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 }, { "getprop", f_getprop },
{ "setprop", f_setprop }, { "setprop", f_setprop },
{ "print", f_print }, { "print", f_print },
@ -792,7 +792,7 @@ void FGNasalSys::createModule(const char* moduleName, const char* fileName,
_cmdArg = (SGPropertyNode*)arg; _cmdArg = (SGPropertyNode*)arg;
call(code, locals); call(code, 0, 0, locals);
hashset(_globals, moduleName, locals); hashset(_globals, moduleName, locals);
} }
@ -845,7 +845,7 @@ bool FGNasalSys::handleCommand(const SGPropertyNode* arg)
// code doesn't need it. // code doesn't need it.
_cmdArg = (SGPropertyNode*)arg; _cmdArg = (SGPropertyNode*)arg;
call(code, locals); call(code, 0, 0, locals);
return true; return true;
} }
@ -889,7 +889,7 @@ void FGNasalSys::setTimer(naContext c, int argc, naRef* args)
void FGNasalSys::handleTimer(NasalTimer* t) void FGNasalSys::handleTimer(NasalTimer* t)
{ {
call(t->handler, naNil()); call(t->handler, 0, 0, naNil());
gcRelease(t->gcKey); gcRelease(t->gcKey);
} }
@ -944,9 +944,9 @@ naRef FGNasalSys::setListener(naContext c, int argc, naRef* args)
return naNil(); 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, FGNasalListener *nl = new FGNasalListener(node, handler, this,
gcSave(handler), _listenerId, persistent); gcSave(handler), _listenerId, type);
bool initial = argc > 2 && naTrue(args[2]); bool initial = argc > 2 && naTrue(args[2]);
node->addChangeListener(nl, initial); node->addChangeListener(nl, initial);
@ -984,17 +984,16 @@ naRef FGNasalSys::removeListener(naContext c, int argc, naRef* args)
// FGNasalListener class. // FGNasalListener class.
FGNasalListener::FGNasalListener(SGPropertyNode_ptr node, naRef handler, FGNasalListener::FGNasalListener(SGPropertyNode_ptr node, naRef handler,
FGNasalSys* nasal, int key, int id, FGNasalSys* nasal, int key, int id, int type) :
bool persistent) :
_node(node), _node(node),
_handler(handler), _handler(handler),
_gcKey(key), _gcKey(key),
_id(id), _id(id),
_nas(nasal), _nas(nasal),
_type(type),
_active(0), _active(0),
_dead(false), _dead(false),
_first_call(true), _first_call(true),
_persistent(persistent),
_last_int(0L), _last_int(0L),
_last_float(0.0) _last_float(0.0)
{ {
@ -1006,21 +1005,50 @@ FGNasalListener::~FGNasalListener()
_nas->gcRelease(_gcKey); _nas->gcRelease(_gcKey);
} }
void FGNasalListener::valueChanged(SGPropertyNode* node) void FGNasalListener::call(SGPropertyNode* cmdarg, int argc, naRef* args)
{ {
// drop recursive listener calls
if(_active || _dead) if(_active || _dead)
return; return;
if(_persistent || changed(node) || _first_call) { SG_LOG(SG_NASAL, SG_DEBUG, "trigger listener #" << _id);
SG_LOG(SG_NASAL, SG_DEBUG, "trigger listener #" << _id); _active++;
_active++; _nas->_cmdArg = cmdarg;
_nas->_cmdArg = node; _nas->call(_handler, argc, args, naNil());
_nas->call(_handler, naNil()); _active--;
_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; _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) bool FGNasalListener::changed(SGPropertyNode* node)
{ {
SGPropertyNode::Type type = node->getType(); SGPropertyNode::Type type = node->getType();

View file

@ -58,7 +58,7 @@ public:
void deleteModule(const char* moduleName); void deleteModule(const char* moduleName);
naRef call(naRef code, naRef locals); naRef call(naRef code, int argc, naRef* args, naRef locals);
private: private:
friend class FGNasalScript; friend class FGNasalScript;
@ -132,23 +132,27 @@ private:
class FGNasalListener : public SGPropertyChangeListener { class FGNasalListener : public SGPropertyChangeListener {
public: public:
FGNasalListener(SGPropertyNode_ptr node, naRef handler, FGNasalListener(SGPropertyNode_ptr node, naRef handler,
FGNasalSys* nasal, int key, int id, bool persistent); FGNasalSys* nasal, int key, int id, int type);
~FGNasalListener(); ~FGNasalListener();
void valueChanged(SGPropertyNode* node); void valueChanged(SGPropertyNode* node);
bool changed(SGPropertyNode* node); void childAdded(SGPropertyNode* parent, SGPropertyNode* child);
void childRemoved(SGPropertyNode* parent, SGPropertyNode* child);
private: private:
bool changed(SGPropertyNode* node);
void call(SGPropertyNode* cmdarg, int argc, naRef* args);
friend class FGNasalSys; friend class FGNasalSys;
SGPropertyNode_ptr _node; SGPropertyNode_ptr _node;
naRef _handler; naRef _handler;
int _gcKey; int _gcKey;
int _id; int _id;
FGNasalSys* _nas; FGNasalSys* _nas;
int _type;
unsigned int _active; unsigned int _active;
bool _dead; bool _dead;
bool _first_call; bool _first_call;
bool _persistent;
long _last_int; long _last_int;
double _last_float; double _last_float;
string _last_string; string _last_string;