]> git.mxchange.org Git - flightgear.git/commitdiff
- assign unique id to listeners
authormfranz <mfranz>
Tue, 28 Feb 2006 14:55:37 +0000 (14:55 +0000)
committermfranz <mfranz>
Tue, 28 Feb 2006 14:55:37 +0000 (14:55 +0000)
- let setlistener return id
- add removelistener(id) command

src/Scripting/NasalSys.cxx
src/Scripting/NasalSys.hxx

index 9acfedca62588d9fc1bb355293643367d3b34718..2415d5f9ad51ef5cdec4c0d87b6f31f1d817024e 100644 (file)
@@ -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;
 }
 
index d6209ee96ad1032c20c1d8d276eb4f84712d4c69..ec9b8d3d00d4029573f31c3d49abb69b1d39b8df 100644 (file)
@@ -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;