From 2cac3dcd49837a6ce10e956ee86e236e534dd171 Mon Sep 17 00:00:00 2001
From: Olivier Stasse <ostasse@laas.fr>
Date: Thu, 11 Apr 2019 18:20:08 +0200
Subject: [PATCH] Adding setLoggerVerbosityLevel and getLoggerVerbosityLevel.

---
 src/dynamic-graph-py.cc           | 10 ++++
 src/dynamic_graph/entity.py       | 36 +++++++++++++
 src/entity-py.cc                  | 84 +++++++++++++++++++++++++++++++
 unitTesting/CMakeLists.txt        | 62 ++++++++++++++++++++++-
 unitTesting/custom_entity.cpp     | 61 ++++++++++++++++++++++
 unitTesting/test_custom_entity.py | 18 +++++++
 6 files changed, 269 insertions(+), 2 deletions(-)
 create mode 100644 unitTesting/custom_entity.cpp
 create mode 100644 unitTesting/test_custom_entity.py

diff --git a/src/dynamic-graph-py.cc b/src/dynamic-graph-py.cc
index ab7519b..bed4c26 100644
--- a/src/dynamic-graph-py.cc
+++ b/src/dynamic-graph-py.cc
@@ -58,6 +58,8 @@ namespace dynamicgraph {
       extern PyObject* listCommands(PyObject* self, PyObject* args);
       extern PyObject* getCommandDocstring(PyObject* self, PyObject* args);
       extern PyObject* getDocString(PyObject* self, PyObject* args);
+      extern PyObject* setLoggerVerbosityLevel(PyObject*self, PyObject *args);
+      extern PyObject* getLoggerVerbosityLevel(PyObject *self, PyObject *args);
     }
 
     namespace factory {
@@ -227,6 +229,14 @@ static PyMethodDef dynamicGraphMethods[] = {
    dynamicgraph::python::pool::getEntityList,
    METH_VARARGS,
    "return the list of instanciated entities"},
+  {"entity_set_logger_verbosity",
+   dynamicgraph::python::entity::setLoggerVerbosityLevel,
+   METH_VARARGS,
+   "set the verbosity level of the entity"},
+  {"entity_get_logger_verbosity",
+   dynamicgraph::python::entity::getLoggerVerbosityLevel,
+   METH_VARARGS,
+   "get the verbosity level of the entity"},  
   {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
diff --git a/src/dynamic_graph/entity.py b/src/dynamic_graph/entity.py
index ea4dd36..9872488 100644
--- a/src/dynamic_graph/entity.py
+++ b/src/dynamic_graph/entity.py
@@ -61,6 +61,17 @@ def updateEntityClasses(dictionary):
 # --- ENTITY -------------------------------------------------------------------
 # --- ENTITY -------------------------------------------------------------------
 
+from enum import Enum
+class VerbosityLevel(Enum):
+    """ 
+    Enum class for setVerbosityLevel
+    """
+    VERBOSITY_ALL =0
+    VERBOSITY_INFO_WARNING_ERROR = 1
+    VERBOSITY_WARNING_ERROR = 2
+    VERBOSITY_ERROR = 3 
+    VERBOSITY_NONE = 4
+
 class Entity (object) :
     """
     This class binds dynamicgraph::Entity C++ class
@@ -72,6 +83,8 @@ class Entity (object) :
     """
     entities = dict ()
 
+
+    
     def __init__(self, className, instanceName):
         """
         Constructor: if not called by a child class, create and store a pointer
@@ -191,6 +204,7 @@ class Entity (object) :
                             "It is not advised to set a new attribute of the same name.")
         object.__setattr__(self, name, value)
 
+
     # --- COMMANDS BINDER -----------------------------------------------------
     # List of all the entity classes from the c++ factory, that have been bound
     # bind the py factory.
@@ -241,3 +255,25 @@ class Entity (object) :
         cmdList = filter(lambda x: not x in self.__class__.__dict__, cmdList)
         for cmd in cmdList:
             self.boundNewCommand( cmd )
+
+    def setLoggerVerbosityLevel(self, verbosity):
+        """ 
+        Specify for the entity the verbosity level
+        """
+        #return
+        wrap.entity_set_logger_verbosity(self.obj,verbosity)
+
+    def getLoggerVerbosityLevel(self):
+        """ 
+        Returns the entity's verbosity level
+        """
+        r=wrap.entity_get_logger_verbosity(self.obj)
+        if r==0:
+            return VerbosityLevel.VERBOSITY_ALL
+        elif r==1:
+            return VerbosityLevel.VERBOSITY_INFO_WARNING_ERROR
+        elif r==2:
+            return VerbosityLevel.VERBOSITY_WARNING_ERROR
+        elif r==3:
+            return VerbosityLevel.VERBOSITY_ERROR
+        return VerbosityLevel.VERBOSITY_NONE
diff --git a/src/entity-py.cc b/src/entity-py.cc
index 0cdf8f4..ca890c7 100644
--- a/src/entity-py.cc
+++ b/src/entity-py.cc
@@ -1,3 +1,4 @@
+
 // Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
 //
 // This file is part of dynamic-graph-python.
@@ -413,6 +414,89 @@ namespace dynamicgraph {
 	/* Return the resulting string. */
 	return Py_BuildValue("s", oss.str().c_str());
       }
+
+
+      /**
+	 \brief Get verbosity Level
+      */
+      PyObject* getLoggerVerbosityLevel(PyObject* /*self*/, PyObject* args)
+      {
+	PyObject* object = NULL;
+	if (!PyArg_ParseTuple(args, "O", &object))
+	  return NULL;
+
+	// Retrieve the entity instance
+	if (!PyCObject_Check(object)) {
+	  PyErr_SetString(PyExc_TypeError,
+			  "first argument is not an object");
+	  return NULL;
+	}
+	
+	void *pointer = PyCObject_AsVoidPtr(object);
+	Entity* entity = (Entity*)pointer;
+
+	LoggerVerbosity alv ;
+	try {
+	  alv = entity->getLoggerVerbosityLevel();
+	} CATCH_ALL_EXCEPTIONS();
+
+	int ares= (int)alv;
+	return Py_BuildValue("i",ares);
+      }
+
+            /**
+	 \brief Set verbosity Level
+      */
+      PyObject* setLoggerVerbosityLevel(PyObject* /*self*/, PyObject*  /* args */)
+      {
+#if 0	
+	PyObject* object = NULL;
+	PyObject* objectVerbosityLevel = NULL;
+	if (!PyArg_ParseTuple(args, "OO", &object,&objectVerbosityLevel))
+	  return NULL;
+	
+	// Retrieve the entity instance
+	  if (!PyCObject_Check(object)) {
+	    PyErr_SetString(PyExc_TypeError,
+			    "First argument should be an object");
+	    return NULL;
+	  }
+	
+	void *pointer = PyCObject_AsVoidPtr(object);
+	Entity* entity = (Entity*)pointer;
+	
+	// Retrieve object verbosity level
+	PyObject* valueOfVerbosityLevel = PyObject_GetAttrString(objectVerbosityLevel, "value");
+	long verbosityLevel = PyLong_AsLong(valueOfVerbosityLevel);//*((int*) lpointer);
+	
+	try {
+	  switch(verbosityLevel)
+	    {
+	    case 0: entity->setLoggerVerbosityLevel(VERBOSITY_ALL);
+	      break;
+	    case 1: entity->setLoggerVerbosityLevel(VERBOSITY_INFO_WARNING_ERROR);
+	      break;
+	    case 2: entity->setLoggerVerbosityLevel(VERBOSITY_WARNING_ERROR);
+	      break;
+	    case 3: entity->setLoggerVerbosityLevel(VERBOSITY_ERROR);
+	      break;
+	    default: entity->setLoggerVerbosityLevel(VERBOSITY_NONE);
+	      break;
+	    }	  
+	} catch (const std::exception& exc) {							
+	  PyErr_SetString(dgpyError, exc.what());		
+	  return NULL;					
+	} catch (const char* s) {							
+	    PyErr_SetString(dgpyError, s);			
+	    return NULL;					
+	} catch (...) {					
+	    PyErr_SetString(dgpyError, "Unknown exception");	
+	    return NULL;						
+	}
+#endif
+	return NULL;
+      }
+
     }
   }
 }
diff --git a/unitTesting/CMakeLists.txt b/unitTesting/CMakeLists.txt
index 88ae862..13e5a13 100644
--- a/unitTesting/CMakeLists.txt
+++ b/unitTesting/CMakeLists.txt
@@ -9,7 +9,6 @@ INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
 INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
 LINK_DIRECTORIES(${Boost_LIBRARY_DIRS} ${PYTHON_LIBRARY_DIRS})
 
-
 ADD_DEFINITIONS(-DDEBUG=2)
 
 # provide path to library libdynamic-graph.so
@@ -45,6 +44,65 @@ ADD_CUSTOM_COMMAND(TARGET interpreter-test-runfile POST_BUILD
   ${CMAKE_BINARY_DIR}/unitTesting
   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/unitTesting/test_python-restart_interpreter.py
   ${CMAKE_BINARY_DIR}/unitTesting
-
 )
 
+#### Build entity library ####
+set(LIBRARY_NAME custom_entity)
+ADD_LIBRARY(${LIBRARY_NAME} SHARED ${LIBRARY_NAME}.cpp)
+
+#remove the "lib" prefix from the publig output name
+SET_TARGET_PROPERTIES(${LIBRARY_NAME} PROPERTIES PREFIX "")
+
+SET_TARGET_PROPERTIES(${LIBRARY_NAME}
+  PROPERTIES
+  SOVERSION ${PROJECT_VERSION}
+  INSTALL_RPATH ${DYNAMIC_GRAPH_PLUGINDIR})
+
+#add_dependencies(${LIBRARY_NAME} dynamic-graph)
+target_link_libraries(${LIBRARY_NAME} dynamic-graph)
+
+PKG_CONFIG_USE_DEPENDENCY(${LIBRARY_NAME} dynamic-graph)
+
+STRING(REPLACE - _ PYTHON_LIBRARY_NAME ${LIBRARY_NAME})
+MESSAGE(STATUS "dynamic_graph_plugindir: ${DYNAMIC_GRAPH_PLUGINDIR}")
+
+
+# Generates a local module in unitTesting
+FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dynamic_graph_tests/${LIBRARY_NAME}")
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/cmake/dynamic_graph/submodule/__init__.py.cmake
+  ${PROJECT_BINARY_DIR}/unitTesting/dynamic_graph_tests/${LIBRARY_NAME}/__init__.py
+  )
+FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dynamic_graph_tests/__init__.py
+  "")
+
+# Generates a local wrap.so library
+
+SET(SOURCE_PYTHON_MODULE "cmake/dynamic_graph/python-module-py.cc")
+
+SET(PYTHON_MODULE   ${PYTHON_LIBRARY_NAME}-wrap)
+CMAKE_POLICY(PUSH)
+IF(POLICY CMP0037)
+  CMAKE_POLICY(SET CMP0037 OLD)
+ENDIF()
+
+ADD_LIBRARY(${PYTHON_MODULE}
+  MODULE
+  ${PROJECT_SOURCE_DIR}/${SOURCE_PYTHON_MODULE})
+
+SET_TARGET_PROPERTIES(${PYTHON_MODULE}
+  PROPERTIES PREFIX ""
+  OUTPUT_NAME dynamic_graph_tests/${LIBRARY_NAME}/wrap
+  )
+
+CMAKE_POLICY(POP)
+
+TARGET_LINK_LIBRARIES(${PYTHON_MODULE} ${PUBLIC_KEYWORD} "-Wl,--no-as-needed")
+TARGET_LINK_LIBRARIES(${PYTHON_MODULE} ${PUBLIC_KEYWORD} ${LIBRARY_NAME} ${PYTHON_LIBRARY})
+
+INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
+
+FILE(COPY
+  ${CMAKE_SOURCE_DIR}/unitTesting/test_custom_entity.py DESTINATION
+  ${CMAKE_BINARY_DIR}/unitTesting/ )
+
diff --git a/unitTesting/custom_entity.cpp b/unitTesting/custom_entity.cpp
new file mode 100644
index 0000000..5f5aa33
--- /dev/null
+++ b/unitTesting/custom_entity.cpp
@@ -0,0 +1,61 @@
+/* Copyright 2010-2019 LAAS, CNRS
+ * Thomas Moulard.
+ *
+ */
+
+#define ENABLE_RT_LOG
+
+#include <sstream>
+#include <dynamic-graph/entity.h>
+#include <dynamic-graph/exception-factory.h>
+#include "dynamic-graph/factory.h"
+#include "dynamic-graph/pool.h"
+#include <dynamic-graph/real-time-logger.h>
+#include <dynamic-graph/signal-ptr.h>
+#include <dynamic-graph/signal-time-dependent.h>
+
+
+namespace dynamicgraph
+{
+  class CustomEntity : public Entity
+  {
+  public:
+    dynamicgraph::SignalPtr<double, int> m_sigdSIN;
+    dynamicgraph::SignalTimeDependent<double, int> m_sigdTimeDepSOUT;
+
+    static const std::string CLASS_NAME;
+    virtual const std::string& getClassName () const
+    {
+      return CLASS_NAME;
+    }
+    CustomEntity (const std::string n)
+      : Entity (n)
+      ,m_sigdSIN(NULL,"CustomEntity("+name+")::input(double)::in_double")
+      ,m_sigdTimeDepSOUT(boost::bind(&CustomEntity::update,this,_1,_2),
+			 m_sigdSIN,
+			 "CustomEntity("+name+")::input(double)::out_double")
+
+    {
+    }
+
+    void addSignal()
+    {
+      signalRegistration(m_sigdSIN << m_sigdTimeDepSOUT);
+    }
+
+    void rmValidSignal()
+    {
+      signalDeregistration("in_double");
+      signalDeregistration("out_double");
+    }
+
+    double & update(double &res, const int &inTime)
+    {
+      const double &aDouble = m_sigdSIN(inTime);
+      res = aDouble;
+      return res;
+    }
+
+  };
+  DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN (CustomEntity,"CustomEntity");
+}
diff --git a/unitTesting/test_custom_entity.py b/unitTesting/test_custom_entity.py
new file mode 100644
index 0000000..9c8e1f6
--- /dev/null
+++ b/unitTesting/test_custom_entity.py
@@ -0,0 +1,18 @@
+import sys, os
+# Put local python module at first priority
+sys.path.insert(0,os.getcwd()+'/../src')
+sys.path.insert(0,os.getcwd())
+
+print(os.getcwd())
+from dynamic_graph_tests.custom_entity import *
+from dynamic_graph.entity import VerbosityLevel
+
+aCustomEntity = CustomEntity("a_custom_entity")
+
+aCustomEntity.setLoggerVerbosityLevel(VerbosityLevel.VERBOSITY_WARNING_ERROR)
+
+
+
+print(aCustomEntity.getLoggerVerbosityLevel())
+
+
-- 
GitLab