Commit 8999ae82 authored by Guilhem Saurel's avatar Guilhem Saurel
Browse files

Merge branch 'cpp11' into release/3.6.0

parents 5b30c6f8 c573696d
......@@ -30,6 +30,8 @@ PROJECT(${PROJECT_NAME} ${PROJECT_ARGS})
FINDPYTHON()
ADD_PROJECT_DEPENDENCY(dynamic-graph REQUIRED PKG_CONFIG_REQUIRES dynamic-graph)
ADD_PROJECT_DEPENDENCY(eigenpy REQUIRED PKG_CONFIG_REQUIRES eigenpy)
ADD_PROJECT_DEPENDENCY(eigenpy REQUIRED PKG_CONFIG_REQUIRES eigenpy)
SET(BOOST_COMPONENTS filesystem system thread program_options unit_test_framework python)
SEARCH_FOR_BOOST()
......@@ -39,9 +41,8 @@ SET(${PROJECT_NAME}_HEADERS
include/${CUSTOM_HEADER_DIR}/api.hh
include/${CUSTOM_HEADER_DIR}/convert-dg-to-py.hh
include/${CUSTOM_HEADER_DIR}/dynamic-graph-py.hh
include/${CUSTOM_HEADER_DIR}/exception.hh
include/${CUSTOM_HEADER_DIR}/exception-python.hh
include/${CUSTOM_HEADER_DIR}/interpreter.hh
include/${CUSTOM_HEADER_DIR}/module.hh
include/${CUSTOM_HEADER_DIR}/python-compat.hh
include/${CUSTOM_HEADER_DIR}/signal-wrapper.hh
)
......@@ -49,14 +50,16 @@ SET(${PROJECT_NAME}_HEADERS
SET(${PROJECT_NAME}_SOURCES
src/interpreter.cc
src/dynamic_graph/python-compat.cc
src/dynamic_graph/entity-py.cc
src/dynamic_graph/convert-dg-to-py.cc
)
ADD_LIBRARY(${PROJECT_NAME} SHARED
${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_HEADERS})
TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} SYSTEM PUBLIC ${PYTHON_INCLUDE_DIRS})
TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC $<INSTALL_INTERFACE:include>)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${Boost_LIBRARIES}
${PYTHON_LIBRARY} ${Boost_PYTHON_LIBRARIES} dynamic-graph::dynamic-graph)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PUBLIC ${Boost_LIBRARIES}
${PYTHON_LIBRARY} Boost::python dynamic-graph::dynamic-graph)
IF(SUFFIX_SO_VERSION)
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION})
......
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include <boost/python.hpp>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/value.h>
#include <dynamic-graph/python/exception-python.hh>
namespace dynamicgraph {
namespace python {
namespace convert {
command::Value pythonToValue(PyObject* pyObject, const command::Value::Type& valueType);
PyObject* vectorToPython(const Vector& vector);
PyObject* matrixToPython(const ::dynamicgraph::Matrix& matrix);
PyObject* matrix4dToPython(const Eigen::Matrix4d& matrix);
PyObject* valueToPython(const ::dynamicgraph::command::Value& value);
command::Value toValue(boost::python::object o, const command::Value::Type& type);
boost::python::object fromValue(const command::Value& value);
} // namespace convert
} // namespace python
......
......@@ -4,189 +4,70 @@
#include <iostream>
#include <sstream>
#include <boost/python.hpp>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/signal-base.h>
#include "dynamic-graph/python/signal-wrapper.hh"
namespace bp = boost::python;
namespace dynamicgraph {
namespace python {
template <typename Iterator>
inline bp::list to_py_list(Iterator begin, Iterator end) {
typedef typename Iterator::value_type T;
bp::list lst;
std::for_each(begin, end, [&](const T& t) { lst.append(t); });
return lst;
}
template <typename Iterator>
inline bp::tuple to_py_tuple(Iterator begin, Iterator end) {
return bp::tuple(to_py_list(begin, end));
}
template <typename T>
inline std::vector<T> to_std_vector(const bp::object& iterable) {
return std::vector<T>(bp::stl_input_iterator<T>(iterable), bp::stl_input_iterator<T>());
}
void exposeSignals();
// Declare functions defined in other source files
namespace signalBase {
PyObject* create(PyObject* self, PyObject* args);
PyObject* createSignalWrapper(PyObject* self, PyObject* args);
PyObject* getTime(PyObject* self, PyObject* args);
PyObject* setTime(PyObject* self, PyObject* args);
PyObject* getName(PyObject* self, PyObject* args);
PyObject* getClassName(PyObject* self, PyObject* args);
PyObject* display(PyObject* self, PyObject* args);
PyObject* displayDependencies(PyObject* self, PyObject* args);
PyObject* getValue(PyObject* self, PyObject* args);
PyObject* setValue(PyObject* self, PyObject* args);
PyObject* recompute(PyObject* self, PyObject* args);
PyObject* unplug(PyObject* self, PyObject* args);
PyObject* isPlugged(PyObject* self, PyObject* args);
PyObject* getPlugged(PyObject* self, PyObject* args);
SignalBase<int>* createSignalWrapper(const char* name, const char* type, bp::object object);
} // namespace signalBase
namespace entity {
PyObject* create(PyObject* self, PyObject* args);
PyObject* display(PyObject* self, PyObject* args);
PyObject* display(PyObject* self, PyObject* args);
PyObject* getName(PyObject* self, PyObject* args);
PyObject* getClassName(PyObject* self, PyObject* args);
PyObject* hasSignal(PyObject* self, PyObject* args);
PyObject* getSignal(PyObject* self, PyObject* args);
PyObject* listSignals(PyObject* self, PyObject* args);
PyObject* executeCommand(PyObject* self, PyObject* args);
PyObject* listCommands(PyObject* self, PyObject* args);
PyObject* getCommandDocstring(PyObject* self, PyObject* args);
PyObject* getDocString(PyObject* self, PyObject* args);
PyObject* setLoggerVerbosityLevel(PyObject* self, PyObject* args);
PyObject* getLoggerVerbosityLevel(PyObject* self, PyObject* args);
PyObject* setTimeSample(PyObject* self, PyObject* args);
PyObject* getTimeSample(PyObject* self, PyObject* args);
PyObject* setStreamPrintPeriod(PyObject* self, PyObject* args);
PyObject* getStreamPrintPeriod(PyObject* self, PyObject* args);
/// \param obj an Entity object
void addCommands(boost::python::object obj);
void addSignals(boost::python::object obj);
Entity* create(const char* type, const char* name);
bp::object executeCmd(bp::tuple args, bp::dict);
} // namespace entity
namespace factory {
PyObject* getEntityClassList(PyObject* self, PyObject* args);
}
namespace signalCaster {
PyObject* getSignalTypeList(PyObject* self, PyObject* args);
bp::tuple getEntityClassList();
}
namespace pool {
PyObject* writeGraph(PyObject* self, PyObject* args);
PyObject* getEntityList(PyObject* self, PyObject* args);
void writeGraph(const char* filename);
bp::list getEntityList();
const std::map<std::string, Entity*>* getEntityMap();
} // namespace pool
namespace debug {
PyObject* addLoggerFileOutputStream(PyObject* self, PyObject* args);
PyObject* addLoggerCoutOutputStream(PyObject* self, PyObject* args);
PyObject* closeLoggerFileOutputStream(PyObject* self, PyObject* args);
PyObject* realTimeLoggerSpinOnce(PyObject* self, PyObject* args);
PyObject* realTimeLoggerDestroy(PyObject* self, PyObject* args);
PyObject* realTimeLoggerInstance(PyObject* self, PyObject* args);
void addLoggerFileOutputStream(const char* filename);
void addLoggerCoutOutputStream();
void closeLoggerFileOutputStream();
void realTimeLoggerSpinOnce();
void realTimeLoggerDestroy();
void realTimeLoggerInstance();
} // namespace debug
struct module_state {
PyObject* dgpyError;
};
PyObject* plug(PyObject* /*self*/, PyObject* args);
PyObject* enableTrace(PyObject* /*self*/, PyObject* args);
PyObject* error_out(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
);
/**
\brief List of python functions
*/
__attribute__((unused)) static PyMethodDef dynamicGraphMethods[] = {
{"w_plug", dynamicgraph::python::plug, METH_VARARGS, "plug an output signal into an input signal"},
{"enableTrace", dynamicgraph::python::enableTrace, METH_VARARGS, "Enable or disable tracing debug info in a file"},
// Signals
{"create_signal_base", dynamicgraph::python::signalBase::create, METH_VARARGS, "create a SignalBase C++ object"},
{"create_signal_wrapper", dynamicgraph::python::signalBase::createSignalWrapper, METH_VARARGS,
"create a SignalWrapper C++ object"},
{"signal_base_get_time", dynamicgraph::python::signalBase::getTime, METH_VARARGS, "Get time of a SignalBase"},
{"signal_base_set_time", dynamicgraph::python::signalBase::setTime, METH_VARARGS, "Set time of a SignalBase"},
{"signal_base_get_name", dynamicgraph::python::signalBase::getName, METH_VARARGS, "Get the name of a signal"},
{"signal_base_get_class_name", dynamicgraph::python::signalBase::getClassName, METH_VARARGS,
"Get the class name of a signal"},
{"signal_base_display", dynamicgraph::python::signalBase::display, METH_VARARGS, "Print the signal in a string"},
{"signal_base_display_dependencies", dynamicgraph::python::signalBase::displayDependencies, METH_VARARGS,
"Print the signal dependencies in a string"},
{"signal_base_get_value", dynamicgraph::python::signalBase::getValue, METH_VARARGS, "Read the value of a signal"},
{"signal_base_set_value", dynamicgraph::python::signalBase::setValue, METH_VARARGS, "Set the value of a signal"},
{"signal_base_recompute", dynamicgraph::python::signalBase::recompute, METH_VARARGS,
"Recompute the signal at given time"},
{"signal_base_unplug", dynamicgraph::python::signalBase::unplug, METH_VARARGS, "Unplug the signal"},
{"signal_base_isPlugged", dynamicgraph::python::signalBase::isPlugged, METH_VARARGS,
"Whether the signal is plugged"},
{"signal_base_getPlugged", dynamicgraph::python::signalBase::getPlugged, METH_VARARGS,
"To which signal the signal is plugged"},
// Entity
{"create_entity", dynamicgraph::python::entity::create, METH_VARARGS, "create an Entity C++ object"},
{"display_entity", dynamicgraph::python::entity::display, METH_VARARGS, "print an Entity C++ object"},
{"entity_get_name", dynamicgraph::python::entity::getName, METH_VARARGS, "get the name of an Entity"},
{"entity_get_class_name", dynamicgraph::python::entity::getClassName, METH_VARARGS,
"get the class name of an Entity"},
{"entity_has_signal", dynamicgraph::python::entity::hasSignal, METH_VARARGS,
"return True if the entity has a signal with the given name"},
{"entity_get_signal", dynamicgraph::python::entity::getSignal, METH_VARARGS, "get signal by name from an Entity"},
{"entity_list_signals", dynamicgraph::python::entity::listSignals, METH_VARARGS,
"Return the list of signals of an entity."},
{"entity_execute_command", dynamicgraph::python::entity::executeCommand, METH_VARARGS, "execute a command"},
{"entity_list_commands", dynamicgraph::python::entity::listCommands, METH_VARARGS,
"list the commands of an entity"},
{"entity_get_command_docstring", dynamicgraph::python::entity::getCommandDocstring, METH_VARARGS,
"get the docstring of an entity command"},
{"entity_get_docstring", dynamicgraph::python::entity::getDocString, METH_VARARGS,
"get the doc string of an entity type"},
{"factory_get_entity_class_list", dynamicgraph::python::factory::getEntityClassList, METH_VARARGS,
"return the list of entity classes"},
{"signal_caster_get_type_list", dynamicgraph::python::signalCaster::getSignalTypeList, METH_VARARGS,
"return the list of signal type names"},
{"writeGraph", dynamicgraph::python::pool::writeGraph, METH_VARARGS, "Write the graph of entities in a filename."},
{"get_entity_list", 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"},
{"addLoggerFileOutputStream", dynamicgraph::python::debug::addLoggerFileOutputStream, METH_VARARGS,
"add a output file stream to the logger by filename"},
{"addLoggerCoutOutputStream", dynamicgraph::python::debug::addLoggerCoutOutputStream, METH_VARARGS,
"add std::cout as output stream to the logger"},
{"closeLoggerFileOutputStream", dynamicgraph::python::debug::closeLoggerFileOutputStream, METH_VARARGS,
"close all the loggers file output streams."},
{"entity_set_time_sample", dynamicgraph::python::entity::setTimeSample, METH_VARARGS,
"set the time sample for printing debugging information"},
{"entity_get_time_sample", dynamicgraph::python::entity::getTimeSample, METH_VARARGS,
"get the time sample for printing debugging information"},
{"entity_set_stream_print_period", dynamicgraph::python::entity::setStreamPrintPeriod, METH_VARARGS,
"set the period at which debugging information are printed"},
{"entity_get_stream_print_period", dynamicgraph::python::entity::getStreamPrintPeriod, METH_VARARGS,
"get the period at which debugging information are printed"},
{"real_time_logger_destroy", dynamicgraph::python::debug::realTimeLoggerDestroy, METH_VARARGS,
"Destroy the real time logger."},
{"real_time_logger_spin_once", dynamicgraph::python::debug::realTimeLoggerSpinOnce, METH_VARARGS,
"Destroy the real time logger."},
{"real_time_logger_instance", dynamicgraph::python::debug::realTimeLoggerInstance, METH_VARARGS,
"Starts the real time logger."},
{"error_out", (PyCFunction)dynamicgraph::python::error_out, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL} /* Sentinel */
};
#if PY_MAJOR_VERSION >= 3
__attribute__((unused)) static struct PyModuleDef dynamicGraphModuleDef = {
PyModuleDef_HEAD_INIT,
"wrap",
NULL,
sizeof(struct dynamicgraph::python::module_state),
dynamicGraphMethods,
NULL,
NULL,
NULL,
NULL};
#define GETSTATE(m) ((struct dynamicgraph::python::module_state*)PyModule_GetState(m))
#define DGPYERROR(m) GETSTATE(m)->dgpyError
#define INITERROR return NULL
#else
__attribute__((unused)) static struct module_state _state;
#define GETSTATE(m) (&dynamicgraph::python::_state)
#define DGPYERROR(m) dynamicgraph::python::dgpyError
#define INITERROR return
#endif
} // namespace python
} // namespace dynamicgraph
......
// -*- mode: c++ -*-
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
#ifndef DYNAMIC_GRAPH_PYTHON_EXCEPTION_PYTHON_H
#define DYNAMIC_GRAPH_PYTHON_EXCEPTION_PYTHON_H
#include <dynamic-graph/fwd.hh>
#include <dynamic-graph/exception-abstract.h>
#include "dynamic-graph/python/python-compat.hh"
// Depending on whether one is building or using the
// library define DLLAPI to import or export.
#if defined(WIN32)
#if defined(wrap_EXPORTS)
#define WRAP_DLLAPI __declspec(dllexport)
#else
#define WRAP_DLLAPI __declspec(dllimport)
#endif
#else
#define WRAP_DLLAPI
#endif
namespace dynamicgraph {
namespace python {
/// \ingroup error
///
/// \brief Generic error class.
class WRAP_DLLAPI ExceptionPython : public ExceptionAbstract {
public:
enum ErrorCodeEnum { GENERIC, VALUE_PARSING, VECTOR_PARSING, MATRIX_PARSING, CLASS_INCONSISTENT };
static const std::string EXCEPTION_NAME;
explicit ExceptionPython(const ExceptionPython::ErrorCodeEnum& errcode, const std::string& msg = "");
ExceptionPython(const ExceptionPython::ErrorCodeEnum& errcode, const std::string& msg, const char* format, ...);
virtual ~ExceptionPython() throw() {}
virtual const std::string& getExceptionName() const { return ExceptionPython::EXCEPTION_NAME; }
};
} // end of namespace python
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_PYTHON_EXCEPTION_PYTHON_H
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#ifndef DYNAMIC_GRAPH_PYTHON_EXCEPTION
#define DYNAMIC_GRAPH_PYTHON_EXCEPTION
#include "dynamic-graph/python/dynamic-graph-py.hh"
/// \brief Catch all exceptions which may be sent when C++ code is
/// called.
#define CATCH_ALL_EXCEPTIONS(m) \
catch (const std::exception& exc) { \
PyErr_SetString(DGPYERROR(m), exc.what()); \
return NULL; \
} \
catch (const char* s) { \
PyErr_SetString(DGPYERROR(m), s); \
return NULL; \
} \
catch (...) { \
PyErr_SetString(DGPYERROR(m), "Unknown exception"); \
return NULL; \
} \
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
#endif //! DYNAMIC_GRAPH_PYTHON_EXCEPTION
#ifndef DYNAMIC_GRAPH_PYTHON_MODULE_HH
#define DYNAMIC_GRAPH_PYTHON_MODULE_HH
#include <boost/python.hpp>
#include <boost/mpl/for_each.hpp>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/python/dynamic-graph-py.hh>
namespace dynamicgraph {
namespace python {
constexpr int AddSignals = 1;
constexpr int AddCommands = 2;
namespace internal {
template <typename T, int Options = AddCommands | AddSignals>
bp::object makeEntity1(const char* name) {
Entity* ent = entity::create(T::CLASS_NAME.c_str(), name);
assert(dynamic_cast<T*>(ent) != NULL);
bp::object obj(bp::ptr(static_cast<T*>(ent)));
if (Options & AddCommands) entity::addCommands(obj);
if (Options & AddSignals) entity::addSignals(obj);
return obj;
}
template <typename T, int Options = AddCommands | AddSignals>
bp::object makeEntity2() {
return makeEntity1<T, Options>("");
}
} // namespace internal
/// \tparam Options by default, all the signals and commands are added as
/// attribute to the Python object. This behaviour works fine for
/// entities that have static commands and signals.
/// If some commands or signals are added or removed dynamiccally, then
/// it is better to disable the default behaviour and handle it
/// specifically.
template <typename T, typename bases = boost::python::bases<dynamicgraph::Entity>,
int Options = AddCommands | AddSignals>
inline auto exposeEntity() {
// std::string hiddenClassName ("_" + T::CLASS_NAME);
std::string hiddenClassName(T::CLASS_NAME);
namespace bp = boost::python;
bp::class_<T, bases, boost::noncopyable> obj(hiddenClassName.c_str(), bp::init<std::string>());
/* TODO at the moment, I couldn't easily find a way to define a Python constructor
* that would create the entity via the factory and then populate the
* python object with its commands.
* This is achieved with a factory function of the same name.
obj.def ("__init__", bp::raw_function(+[](bp::object args, bp::dict) {
if (bp::len(args) != 2)
throw std::length_error("Expected 2 arguments.");
bp::object self = args[0];
self.attr("__init__")(bp::extract<std::string>(args[1]));
Entity* ent = entity::create(T::CLASS_NAME.c_str(), name);
if (dynamic_cast<T*>(ent) == NULL)
std::cout << "foo" << std::endl;
assert(dynamic_cast<T*>(ent) != NULL);
self = bp::object(bp::ptr(static_cast<T*>(ent)));
//dynamicgraph::Entity& unused = bp::extract<dynamicgraph::Entity&>(self);
//entity::addCommands(self);
})
;
*/
bp::def(T::CLASS_NAME.c_str(), &internal::makeEntity1<T, Options>);
bp::def(T::CLASS_NAME.c_str(), &internal::makeEntity2<T, Options>);
return obj;
}
} // namespace python
} // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_PYTHON_MODULE_HH
......@@ -4,6 +4,8 @@
#ifndef DGPY_SIGNAL_WRAPPER
#define DGPY_SIGNAL_WRAPPER
#include <boost/python.hpp>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/entity.h>
......@@ -11,22 +13,12 @@
namespace dynamicgraph {
namespace python {
namespace signalWrapper {
void convert(PyObject* o, int& v);
void convert(PyObject* o, bool& v);
void convert(PyObject* o, float& v);
void convert(PyObject* o, double& v);
// void convert (PyObject* o, std::string& v);
void convert(PyObject* o, Vector& v);
// void convert (PyObject* o, Eigen::MatrixXd& v);
// void convert (PyObject* o, Eigen::Matrix4d& v);
} // namespace signalWrapper
class PythonSignalContainer : public Entity {
DYNAMIC_GRAPH_ENTITY_DECL();
public:
PythonSignalContainer(const std::string& name);
using Entity::Entity;
void signalRegistration(const SignalArray<int>& signals);
......@@ -37,17 +29,17 @@ template <class T, class Time>
class SignalWrapper : public Signal<T, Time> {
public:
typedef Signal<T, Time> parent_t;
typedef boost::python::object pyobject;
static bool checkCallable(PyObject* c, std::string& error);
static bool checkCallable(pyobject c, std::string& error);
SignalWrapper(std::string name, PyObject* _callable) : parent_t(name), callable(_callable) {
SignalWrapper(std::string name, pyobject callable) : parent_t(name), callable(callable) {
typedef boost::function2<T&, T&, Time> function_t;
Py_INCREF(callable);
function_t f = boost::bind(&SignalWrapper::call, this, _1, _2);
this->setFunction(f);
}
virtual ~SignalWrapper() { Py_DECREF(callable); };
virtual ~SignalWrapper(){};
private:
T& call(T& value, Time t) {
......@@ -56,18 +48,12 @@ class SignalWrapper : public Signal<T, Time> {
if (PyGILState_GetThisThreadState() == NULL) {
dgDEBUG(10) << "python thread not initialized" << std::endl;
}
char format[] = "i";
PyObject* obj = PyObject_CallFunction(callable, format, t);
if (obj == NULL) {
dgERROR << "Could not call callable" << std::endl;
} else {
signalWrapper::convert(obj, value);
Py_DECREF(obj);
}
pyobject obj = callable(t);
value = boost::python::extract<T>(obj);
PyGILState_Release(gstate);
return value;
}
PyObject* callable;
pyobject callable;
};
} // namespace python
......
......@@ -16,6 +16,8 @@ FOREACH(source ${PYTHON_SOURCES})
ENDFOREACH(source)
# --- ADD the wrap on the dg modules
DYNAMIC_GRAPH_PYTHON_MODULE("tracer" dynamic-graph::tracer tracer-wrap)
DYNAMIC_GRAPH_PYTHON_MODULE("tracer_real_time" dynamic-graph::tracer-real-time
tracer_real_time-wrap)
LINK_DIRECTORIES(${DYNAMIC_GRAPH_PLUGINDIR})
DYNAMIC_GRAPH_PYTHON_MODULE("tracer" dynamic-graph::tracer tracer-wrap
SOURCE_PYTHON_MODULE ${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/tracer/wrap.cc)
DYNAMIC_GRAPH_PYTHON_MODULE("tracer_real_time" dynamic-graph::tracer-real-time tracer_real_time-wrap
SOURCE_PYTHON_MODULE ${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/tracer_real_time/wrap.cc)
......@@ -3,22 +3,18 @@
SET(PYTHON_MODULE wrap)
ADD_LIBRARY(${PYTHON_MODULE} MODULE
convert-dg-to-py.cc
debug-py.cc
dynamic-graph-py.cc
entity-py.cc
exception-python.cc
factory-py.cc
pool-py.cc
python-compat.cc
signal-base-py.cc
signal-caster-py.cc
signal-wrapper.cc
)
TARGET_INCLUDE_DIRECTORIES(${PYTHON_MODULE} SYSTEM PUBLIC ${PYTHON_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PYTHON_MODULE} ${PYTHON_LIBRARY}
dynamic-graph::dynamic-graph)
dynamic-graph::dynamic-graph Boost::python ${PROJECT_NAME}
eigenpy::eigenpy)
# Remove prefix lib
SET_TARGET_PROPERTIES(${PYTHON_MODULE} PROPERTIES PREFIX "")
......
......@@ -10,26 +10,4 @@ import sys
from . import entity # noqa
from . import signal_base # noqa
try:
from DLFCN import RTLD_NOW, RTLD_GLOBAL
except ModuleNotFoundError: # Python 3
from os import RTLD_NOW, RTLD_GLOBAL
flags = sys.getdlopenflags()
# Import C++ symbols in a global scope
# This is necessary for signal compiled in different modules to be compatible
sys.setdlopenflags(RTLD_NOW | RTLD_GLOBAL)
from .wrap import * # noqa
# Recover previous flags
sys.setdlopenflags(flags)
def plug(signalOut, signalIn):
"""
Plug an output signal into an input signal
"""