module.hh
Go to the documentation of this file.
1 #ifndef DYNAMIC_GRAPH_PYTHON_MODULE_HH
2 #define DYNAMIC_GRAPH_PYTHON_MODULE_HH
3 
4 #ifdef PINOCCHIO_WITH_URDFDOM
5 // If pinocchio is used, we have to include pinocchio header before boost mpl
6 #include <pinocchio/fwd.hpp>
7 #endif
8 
9 #include <boost/python.hpp>
10 #include <boost/mpl/for_each.hpp>
11 #include <boost/mpl/vector.hpp>
12 
13 #include <dynamic-graph/entity.h>
15 
16 namespace dynamicgraph {
17 namespace python {
18 
19 constexpr int AddSignals = 1;
20 constexpr int AddCommands = 2;
21 
22 namespace internal {
23 
24 template <typename T, int Options = AddCommands | AddSignals>
25 bp::object makeEntity1(const char* name) {
26  Entity* ent = entity::create(T::CLASS_NAME.c_str(), name);
27  assert(dynamic_cast<T*>(ent) != NULL);
28  bp::object obj(bp::ptr(static_cast<T*>(ent)));
29  if (Options & AddCommands) entity::addCommands(obj);
30  if (Options & AddSignals) entity::addSignals(obj);
31  return obj;
32 }
33 template <typename T, int Options = AddCommands | AddSignals>
34 bp::object makeEntity2() {
35  return makeEntity1<T, Options>("");
36 }
37 
38 } // namespace internal
39 
46 template <typename T, typename bases = boost::python::bases<dynamicgraph::Entity>,
47  int Options = AddCommands | AddSignals>
48 inline auto exposeEntity() {
49  // std::string hiddenClassName ("_" + T::CLASS_NAME);
50  std::string hiddenClassName(T::CLASS_NAME);
51  namespace bp = boost::python;
52  bp::class_<T, bases, boost::noncopyable> obj(hiddenClassName.c_str(), bp::init<std::string>());
53  /* TODO at the moment, I couldn't easily find a way to define a Python constructor
54  * that would create the entity via the factory and then populate the
55  * python object with its commands.
56  * This is achieved with a factory function of the same name.
57  obj.def ("__init__", bp::raw_function(+[](bp::object args, bp::dict) {
58  if (bp::len(args) != 2)
59  throw std::length_error("Expected 2 arguments.");
60  bp::object self = args[0];
61  self.attr("__init__")(bp::extract<std::string>(args[1]));
62  Entity* ent = entity::create(T::CLASS_NAME.c_str(), name);
63  if (dynamic_cast<T*>(ent) == NULL)
64  std::cout << "foo" << std::endl;
65  assert(dynamic_cast<T*>(ent) != NULL);
66  self = bp::object(bp::ptr(static_cast<T*>(ent)));
67  //dynamicgraph::Entity& unused = bp::extract<dynamicgraph::Entity&>(self);
68  //entity::addCommands(self);
69  })
70  ;
71  */
72  bp::def(T::CLASS_NAME.c_str(), &internal::makeEntity1<T, Options>);
73  bp::def(T::CLASS_NAME.c_str(), &internal::makeEntity2<T, Options>);
74  if (!(Options & AddCommands)) obj.def("add_commands", &entity::addCommands);
75  if (!(Options & AddSignals)) obj.def("add_signals", &entity::addSignals);
76  return obj;
77 }
78 
79 } // namespace python
80 } // namespace dynamicgraph
81 
82 #endif // DYNAMIC_GRAPH_PYTHON_MODULE_HH
dynamicgraph
Definition: convert-dg-to-py.hh:8
dynamicgraph::python::AddCommands
constexpr int AddCommands
Definition: module.hh:20
dynamicgraph::python::entity::addCommands
void addCommands(boost::python::object obj)
dynamic-graph-py.hh
dynamicgraph::python::entity::addSignals
void addSignals(boost::python::object obj)
dynamicgraph::python::entity::create
Entity * create(const char *type, const char *name)
Create an instance of Entity.
Definition: entity-py.cc:57
dynamicgraph::python::AddSignals
constexpr int AddSignals
Definition: module.hh:19
dynamicgraph::python::internal::makeEntity2
bp::object makeEntity2()
Definition: module.hh:34
dynamicgraph::python::internal::makeEntity1
bp::object makeEntity1(const char *name)
Definition: module.hh:25
dynamicgraph::python::exposeEntity
auto exposeEntity()
Definition: module.hh:48