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