- assign unique id to listeners
- let setlistener return id - add removelistener(id) command
This commit is contained in:
parent
97b75a79bf
commit
55cde5f160
2 changed files with 63 additions and 14 deletions
|
@ -239,13 +239,20 @@ static naRef f_settimer(naContext c, naRef me, int argc, naRef* args)
|
|||
return naNil();
|
||||
}
|
||||
|
||||
// setlistener(func, property) extension function. Falls through to
|
||||
// setlistener(func, property, bool) extension function. Falls through to
|
||||
// FGNasalSys::setListener(). See there for docs.
|
||||
static naRef f_setlistener(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal");
|
||||
nasal->setListener(argc, args);
|
||||
return naNil();
|
||||
return nasal->setListener(argc, args);
|
||||
}
|
||||
|
||||
// removelistener(int) extension function. Falls through to
|
||||
// FGNasalSys::removeListener(). See there for docs.
|
||||
static naRef f_removelistener(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FGNasalSys* nasal = (FGNasalSys*)globals->get_subsystem("nasal");
|
||||
return nasal->removeListener(argc, args);
|
||||
}
|
||||
|
||||
// Returns a ghost handle to the argument to the currently executing
|
||||
|
@ -323,6 +330,7 @@ static struct { char* name; naCFunction func; } funcs[] = {
|
|||
{ "_fgcommand", f_fgcommand },
|
||||
{ "settimer", f_settimer },
|
||||
{ "_setlistener", f_setlistener },
|
||||
{ "removelistener", f_removelistener },
|
||||
{ "_cmdarg", f_cmdarg },
|
||||
{ "_interpolate", f_interpolate },
|
||||
{ "rand", f_rand },
|
||||
|
@ -594,22 +602,51 @@ void FGNasalSys::NasalTimer::timerExpired()
|
|||
delete this;
|
||||
}
|
||||
|
||||
// setlistener(property, func) extension function. The first argument
|
||||
int FGNasalSys::_listenerId = 0;
|
||||
|
||||
// setlistener(property, func, bool) extension function. The first argument
|
||||
// is either a ghost (SGPropertyNode_ptr*) or a string (global property
|
||||
// path), the second is a Nasal function.
|
||||
void FGNasalSys::setListener(int argc, naRef* args)
|
||||
// path), the second is a Nasal function, the optional third one a bool.
|
||||
// If the bool is true, then the listener is executed initially. The
|
||||
// setlistener() function returns a unique id number, that can be used
|
||||
// as argument to the removelistener() function.
|
||||
naRef FGNasalSys::setListener(int argc, naRef* args)
|
||||
{
|
||||
SGPropertyNode* node;
|
||||
SGPropertyNode_ptr node;
|
||||
naRef prop = argc > 0 ? args[0] : naNil();
|
||||
if(naIsString(prop)) node = fgGetNode(naStr_data(prop), true);
|
||||
else if(naIsGhost(prop)) node = *(SGPropertyNode_ptr*)naGhost_ptr(prop);
|
||||
else return;
|
||||
else return naNil();
|
||||
|
||||
naRef handler = argc > 1 ? args[1] : naNil();
|
||||
if(!(naIsCode(handler) || naIsCCode(handler) || naIsFunc(handler)))
|
||||
return;
|
||||
return naNil();
|
||||
|
||||
bool initial = argc > 2 && naTrue(args[2]);
|
||||
node->addChangeListener(new FGNasalListener(handler, this, gcSave(handler)), initial);
|
||||
|
||||
FGNasalListener *nl = new FGNasalListener(node, handler, this,
|
||||
gcSave(handler));
|
||||
_listener[_listenerId] = nl;
|
||||
node->addChangeListener(nl, initial);
|
||||
return naNum(_listenerId++);
|
||||
}
|
||||
|
||||
// removelistener(int) extension function. The argument is the id of
|
||||
// a listener as returned by the setlistener() function.
|
||||
naRef FGNasalSys::removeListener(int argc, naRef* args)
|
||||
{
|
||||
naRef id = argc > 0 ? args[0] : naNil();
|
||||
if(!naIsNum(id))
|
||||
return naNil();
|
||||
|
||||
int i = int(id.num);
|
||||
if (_listener.find(i) == _listener.end())
|
||||
return naNil();
|
||||
|
||||
FGNasalListener *nl = _listener[i];
|
||||
nl->_node->removeChangeListener(nl);
|
||||
_listener.erase(i);
|
||||
delete nl;
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/nasal/nasal.h>
|
||||
|
||||
#include <map>
|
||||
SG_USING_STD(map);
|
||||
|
||||
|
||||
class FGNasalScript;
|
||||
class FGNasalListener;
|
||||
|
||||
class FGNasalSys : public SGSubsystem
|
||||
{
|
||||
|
@ -37,7 +42,8 @@ public:
|
|||
void setTimer(int argc, naRef* args);
|
||||
|
||||
// Implementation of the setlistener extension function
|
||||
void setListener(int argc, naRef* args);
|
||||
naRef setListener(int argc, naRef* args);
|
||||
naRef removeListener(int argc, naRef* args);
|
||||
|
||||
// Returns a ghost wrapper for the current _cmdArg
|
||||
naRef cmdArgGhost();
|
||||
|
@ -64,6 +70,10 @@ private:
|
|||
FGNasalSys* nasal;
|
||||
};
|
||||
|
||||
// Listener
|
||||
map<int, FGNasalListener *> _listener;
|
||||
static int _listenerId;
|
||||
|
||||
void loadPropertyScripts();
|
||||
void hashset(naRef hash, const char* key, naRef val);
|
||||
void logError(naContext);
|
||||
|
@ -110,8 +120,9 @@ private:
|
|||
|
||||
class FGNasalListener : public SGPropertyChangeListener {
|
||||
public:
|
||||
FGNasalListener(naRef handler, FGNasalSys* nasal, int key)
|
||||
: _handler(handler), _gcKey(key), _nas(nasal) {}
|
||||
FGNasalListener(SGPropertyNode_ptr node, naRef handler,
|
||||
FGNasalSys* nasal, int key)
|
||||
: _node(node), _handler(handler), _gcKey(key), _nas(nasal) {}
|
||||
|
||||
~FGNasalListener() {
|
||||
_nas->gcRelease(_gcKey);
|
||||
|
@ -130,6 +141,7 @@ public:
|
|||
|
||||
private:
|
||||
friend class FGNasalSys;
|
||||
SGPropertyNode_ptr _node;
|
||||
naRef _handler;
|
||||
int _gcKey;
|
||||
FGNasalSys* _nas;
|
||||
|
|
Loading…
Add table
Reference in a new issue