- 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:
parent
02a813abde
commit
3a03671566
2 changed files with 56 additions and 24 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue