From: mfranz Date: Tue, 28 Feb 2006 14:55:37 +0000 (+0000) Subject: - assign unique id to listeners X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=55cde5f160ae98ea8a9dd743ee4e83f962410e8a;p=flightgear.git - assign unique id to listeners - let setlistener return id - add removelistener(id) command --- diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index 9acfedca6..2415d5f9a 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -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 }, @@ -554,7 +562,7 @@ void FGNasalSys::setTimer(int argc, naRef* args) naRef delta = argc > 1 ? args[1] : naNil(); if(naIsNil(delta)) return; - + bool simtime = (argc > 2 && naTrue(args[2])) ? false : true; // Generate and register a C++ timer handler @@ -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; } diff --git a/src/Scripting/NasalSys.hxx b/src/Scripting/NasalSys.hxx index d6209ee96..ec9b8d3d0 100644 --- a/src/Scripting/NasalSys.hxx +++ b/src/Scripting/NasalSys.hxx @@ -5,7 +5,12 @@ #include #include +#include +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 _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;