From abd1a6c49c2a94427cc66dd4f2ded29341f53ff3 Mon Sep 17 00:00:00 2001
From: Joseph Mirabel <jmirabel@laas.fr>
Date: Thu, 15 Feb 2018 16:50:01 +0100
Subject: [PATCH] Add entity PythonSignalContainer

* as a container of the signals created with create_signal_wrapper.
* This makes them available to other entities via the pool.
---
 src/signal-base-py.cc | 43 +++++++++++++++++++++++++++++++++++++++----
 src/signal-wrapper.cc |  7 +++++--
 src/signal-wrapper.hh | 14 ++++++++++++++
 3 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/src/signal-base-py.cc b/src/signal-base-py.cc
index 6cf5fd7..a37ecc2 100644
--- a/src/signal-base-py.cc
+++ b/src/signal-base-py.cc
@@ -22,6 +22,8 @@
 #include <dynamic-graph/signal-ptr.h>
 #include <dynamic-graph/signal-caster.h>
 #include <dynamic-graph/linear-algebra.h>
+#include <dynamic-graph/pool.h>
+#include <dynamic-graph/factory.h>
 
 #include "convert-dg-to-py.hh"
 #include "exception.hh"
@@ -57,7 +59,7 @@ namespace dynamicgraph {
 	return PyCObject_FromVoidPtr((void*)obj, destroy);
       }
 
-      template <class T> void* createSignalWrapperTpl (const char* name, PyObject* o, std::string& error)
+      template <class T> SignalWrapper<T, int>* createSignalWrapperTpl (const char* name, PyObject* o, std::string& error)
       {
         typedef SignalWrapper<T, int> SignalWrapper_t;
         if (!SignalWrapper_t::checkCallable (o, error)) {
@@ -65,7 +67,33 @@ namespace dynamicgraph {
         }
 
         SignalWrapper_t* obj = new SignalWrapper_t(name, o);
-        return (void*) obj;
+        return obj;
+      }
+
+      PythonSignalContainer* getPythonSignalContainer ()
+      {
+        const std::string instanceName = "python_signals";
+        const std::string className = "PythonSignalContainer";
+        Entity* obj;
+        if( PoolStorage::getInstance()->existEntity(instanceName, obj))
+        {
+          if( obj->getClassName()!=className ) {
+            std::string msg ("Found an object named "
+                + std::string(instanceName)
+                + ",\n""but this object is of type "
+                + std::string(obj->getClassName())
+                + " and not "
+                + std::string(className));
+            PyErr_SetString(dgpyError, msg.c_str());
+            return NULL;
+          }
+        } else {
+          try {
+            obj = FactoryStorage::getInstance()->newEntity
+              (std::string(className), std::string(instanceName));
+          } CATCH_ALL_EXCEPTIONS();
+        }
+        return dynamic_cast<PythonSignalContainer*>(obj);
       }
 
 #define SIGNAL_WRAPPER_TYPE(IF, Enum, Type)                             \
@@ -79,6 +107,10 @@ namespace dynamicgraph {
       */
       PyObject* createSignalWrapper(PyObject* /*self*/, PyObject* args)
       {
+        PythonSignalContainer* psc = getPythonSignalContainer();
+        if (psc == NULL)
+          return NULL;
+
 	char *name = NULL;
 	char *type = NULL;
 	PyObject* object = NULL;
@@ -86,7 +118,7 @@ namespace dynamicgraph {
 	if (!PyArg_ParseTuple(args, "ssO", &name, &type, &object))
 	  return NULL;
 
-        void* obj = NULL;
+        SignalBase<int>* obj = NULL;
         std::string error;
         SIGNAL_WRAPPER_TYPE(     if, BOOL     ,bool)
         // SIGNAL_WRAPPER_TYPE(else if, UNSIGNED ,bool)
@@ -105,8 +137,11 @@ namespace dynamicgraph {
           PyErr_SetString(dgpyError, error.c_str());
           return NULL;
         }
+        // Register signal into the python signal container
+        psc->signalRegistration(*obj);
+
 	// Return the pointer
-	return PyCObject_FromVoidPtr(obj, destroy);
+	return PyCObject_FromVoidPtr((void*)obj, destroy);
       }
 
       /**
diff --git a/src/signal-wrapper.cc b/src/signal-wrapper.cc
index 2e80a9a..53dfcd9 100644
--- a/src/signal-wrapper.cc
+++ b/src/signal-wrapper.cc
@@ -14,10 +14,11 @@
 // received a copy of the GNU Lesser General Public License along with
 // dynamic-graph-python. If not, see <http://www.gnu.org/licenses/>.
 
-#include <Python.h>
-
 #include <signal-wrapper.hh>
 
+#include <Python.h>
+#include <dynamic-graph/factory.h>
+
 namespace dynamicgraph {
   namespace python {
     namespace signalWrapper {
@@ -33,6 +34,8 @@ namespace dynamicgraph {
       }
     }
 
+    DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(PythonSignalContainer, "PythonSignalContainer");
+
     template <class T, class Time>
     bool SignalWrapper<T,Time>::checkCallable (PyObject* c, std::string& error)
     {
diff --git a/src/signal-wrapper.hh b/src/signal-wrapper.hh
index d37d345..8dcc9f7 100644
--- a/src/signal-wrapper.hh
+++ b/src/signal-wrapper.hh
@@ -18,6 +18,7 @@
 
 #include <dynamic-graph/linear-algebra.h>
 #include <dynamic-graph/signal.h>
+#include <dynamic-graph/entity.h>
 
 namespace dynamicgraph {
   namespace python {
@@ -32,6 +33,19 @@ namespace dynamicgraph {
       // void convert (PyObject* o, Eigen::Matrix4d& v);
     }
 
+    class PythonSignalContainer : public Entity
+    {
+      DYNAMIC_GRAPH_ENTITY_DECL();
+
+      public:
+        PythonSignalContainer (const std::string& name) : Entity (name) {};
+
+        void signalRegistration (const SignalArray<int>& signals)
+        {
+          Entity::signalRegistration (signals);
+        }
+    };
+
     template <class T, class Time>
     class SignalWrapper : public Signal<T, Time>
     {
-- 
GitLab