signal-wrapper.hh 2.07 KB
Newer Older
1
2
3
// Copyright (c) 2018, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)

Guilhem Saurel's avatar
Guilhem Saurel committed
4
5
6
#ifndef DGPY_SIGNAL_WRAPPER
#define DGPY_SIGNAL_WRAPPER

7
8
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/signal.h>
9
#include <dynamic-graph/entity.h>
10
#include "dynamic-graph/python/python-compat.hh"
11
12

namespace dynamicgraph {
Guilhem Saurel's avatar
format    
Guilhem Saurel committed
13
14
15
16
17
18
19
20
21
22
23
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
24

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
25
26
class PythonSignalContainer : public Entity {
  DYNAMIC_GRAPH_ENTITY_DECL();
27

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
28
29
 public:
  PythonSignalContainer(const std::string& name);
30

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
31
  void signalRegistration(const SignalArray<int>& signals);
32

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
33
34
  void rmSignal(const std::string& name);
};
35

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
36
37
38
39
template <class T, class Time>
class SignalWrapper : public Signal<T, Time> {
 public:
  typedef Signal<T, Time> parent_t;
40

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
41
  static bool checkCallable(PyObject* c, std::string& error);
42

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
43
44
45
46
47
48
  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);
  }
49

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
50
  virtual ~SignalWrapper() { Py_DECREF(callable); };
51

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 private:
  T& call(T& value, Time t) {
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
    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);
    }
    PyGILState_Release(gstate);
    return value;
  }
  PyObject* callable;
};
72

Guilhem Saurel's avatar
format    
Guilhem Saurel committed
73
74
}  // namespace python
}  // namespace dynamicgraph
Guilhem Saurel's avatar
Guilhem Saurel committed
75
#endif