dynamic-graph-py.cc 9.03 KB
Newer Older
Thomas Moulard's avatar
Thomas Moulard committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
//
// This file is part of dynamic-graph-python.
// dynamic-graph-python is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// dynamic-graph-python is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Lesser Public License for more details.  You should
// have received a copy of the GNU Lesser General Public License along
// with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
florent's avatar
florent committed
15
16
17

#include <Python.h>
#include <iostream>
florent's avatar
florent committed
18
#include <sstream>
florent's avatar
florent committed
19
20
#include <string>

21
#include <dynamic-graph/debug.h>
22
#include <dynamic-graph/exception-factory.h>
florent's avatar
florent committed
23
#include <dynamic-graph/signal-base.h>
florent's avatar
florent committed
24

25
26
#include "exception.hh"

27
28
namespace dynamicgraph {
  namespace python {
29

30
31
32
33
    // Declare functions defined in other source files
    namespace signalBase {
      extern PyObject* create(PyObject* self, PyObject* args);
      extern PyObject* getTime(PyObject* self, PyObject* args);
34
      extern PyObject* setTime(PyObject* self, PyObject* args);
35
      extern PyObject* getName(PyObject* self, PyObject* args);
36
      extern PyObject* getClassName(PyObject* self, PyObject* args);
37
      extern PyObject* display(PyObject* self, PyObject* args);
38
      extern PyObject* displayDependencies(PyObject* self, PyObject* args);
florent's avatar
florent committed
39
40
      extern PyObject* getValue(PyObject* self, PyObject* args);
      extern PyObject* setValue(PyObject* self, PyObject* args);
41
      extern PyObject* recompute(PyObject* self, PyObject* args);
42
      extern PyObject* unplug(PyObject* self, PyObject* args);
Florent Lamiraux's avatar
Florent Lamiraux committed
43
44
      extern PyObject* isPlugged(PyObject* self, PyObject* args);
      extern PyObject* getPlugged(PyObject* self, PyObject* args);
45
46
47
    }
    namespace entity {
      extern PyObject* create(PyObject* self, PyObject* args);
48
      extern PyObject* display(PyObject* self, PyObject* args);
49
      extern PyObject* display(PyObject* self, PyObject* args);
50
      extern PyObject* getName(PyObject* self, PyObject* args);
Joseph Mirabel's avatar
Joseph Mirabel committed
51
      extern PyObject* getClassName(PyObject* self, PyObject* args);
52
      extern PyObject* hasSignal(PyObject* self, PyObject* args);
53
      extern PyObject* getSignal(PyObject* self, PyObject* args);
54
      extern PyObject* listSignals(PyObject* self, PyObject* args);
florent's avatar
florent committed
55
      extern PyObject* executeCommand(PyObject* self, PyObject* args);
56
      extern PyObject* listCommands(PyObject* self, PyObject* args);
57
      extern PyObject* getCommandDocstring(PyObject* self, PyObject* args);
58
      extern PyObject* getDocString(PyObject* self, PyObject* args);
59
60
    }

florent's avatar
florent committed
61
    namespace factory {
62
      extern PyObject* getEntityClassList(PyObject* self, PyObject* args);
florent's avatar
florent committed
63
    }
64
    namespace signalCaster {
65
66
67
68
      extern PyObject* getSignalTypeList(PyObject* self, PyObject* args);
    }
    namespace pool {
      extern PyObject* writeGraph (PyObject* self, PyObject* args);
69
      extern PyObject* getEntityList(PyObject* self, PyObject* args);
70
71
    }

72
    PyObject* dgpyError;
73
74
75
76
77

    /**
       \brief plug a signal into another one.
    */
    PyObject*
Thomas Moulard's avatar
Thomas Moulard committed
78
    plug(PyObject* /*self*/, PyObject* args)
79
    {
florent's avatar
florent committed
80
81
82
83
84
85
86
87
      PyObject* objOut = NULL;
      PyObject* objIn = NULL;
      void* pObjOut;
      void* pObjIn;

      if (!PyArg_ParseTuple(args,"OO", &objOut, &objIn))
	return NULL;

88
89
90
91
      if (!PyCObject_Check(objOut)) {
	PyErr_SetString(PyExc_TypeError,
			"first argument should be a pointer to"
			" signalBase<int>.");
florent's avatar
florent committed
92
	return NULL;
93
94
95
96
97
      }
      if (!PyCObject_Check(objIn)) {
	PyErr_SetString(PyExc_TypeError,
			"second argument should be a pointer to"
			" signalBase<int>.");
98
	return NULL;
99
      }
100

florent's avatar
florent committed
101
102
103
104
      pObjIn = PyCObject_AsVoidPtr(objIn);
	SignalBase<int>* signalIn = (SignalBase<int>*)pObjIn;
      pObjOut = PyCObject_AsVoidPtr(objOut);
	SignalBase<int>* signalOut = (SignalBase<int>*)pObjOut;
105
      std::ostringstream os;
florent's avatar
florent committed
106

107
      try {
florent's avatar
florent committed
108
	signalIn->plug(signalOut);
109
      } CATCH_ALL_EXCEPTIONS();
110
111
112
113
      return Py_BuildValue("");
    }

    PyObject*
Thomas Moulard's avatar
Thomas Moulard committed
114
    enableTrace(PyObject* /*self*/, PyObject* args)
115
    {
116
      PyObject* boolean;
117
118
      char* filename = NULL;

119
120
121
122
123
124
125
      if (PyArg_ParseTuple(args,"Os", &boolean, &filename)) {
	if (!PyBool_Check(boolean)) {
	  PyErr_SetString(PyExc_TypeError, "enableTrace takes as first "
			  "argument True or False,\n""           and as "
			  "second argument a filename.");
	  return NULL;
	}
126
	if (PyObject_IsTrue(boolean)) {
127
128
	  try {
	    DebugTrace::openFile(filename);
129
	  } CATCH_ALL_EXCEPTIONS();
130
131
132
	} else {
	  try {
	    DebugTrace::closeFile(filename);
133
	  } CATCH_ALL_EXCEPTIONS();
134
	}
135
136
137
138
139
140
      } else {
	return NULL;
      }
      return Py_BuildValue("");
    }
  }
florent's avatar
florent committed
141
142
143
144
145
}

/**
   \brief List of python functions
*/
146
static PyMethodDef dynamicGraphMethods[] = {
florent's avatar
florent committed
147
  {"w_plug",  dynamicgraph::python::plug, METH_VARARGS,
148
   "plug an output signal into an input signal"},
149
  {"enableTrace",  dynamicgraph::python::enableTrace, METH_VARARGS,
150
151
152
153
   "Enable or disable tracing debug info in a file"},
  // Signals
  {"create_signal_base", dynamicgraph::python::signalBase::create, METH_VARARGS,
   "create a SignalBase C++ object"},
florent's avatar
florent committed
154
  {"signal_base_get_time", dynamicgraph::python::signalBase::getTime,
155
   METH_VARARGS, "Get time of  a SignalBase"},
156
157
  {"signal_base_set_time", dynamicgraph::python::signalBase::setTime,
   METH_VARARGS, "Set time of  a SignalBase"},
158
159
  {"signal_base_get_name", dynamicgraph::python::signalBase::getName,
   METH_VARARGS, "Get the name of a signal"},
160
161
  {"signal_base_get_class_name", dynamicgraph::python::signalBase::getClassName,
   METH_VARARGS, "Get the class name of a signal"},
162
163
  {"signal_base_display", dynamicgraph::python::signalBase::display,
   METH_VARARGS, "Print the signal in a string"},
164
165
  {"signal_base_display_dependencies", dynamicgraph::python::signalBase::displayDependencies,
   METH_VARARGS, "Print the signal dependencies in a string"},
florent's avatar
florent committed
166
  {"signal_base_get_value", dynamicgraph::python::signalBase::getValue,
167
   METH_VARARGS, "Read the value of a signal"}, 
168
  {"signal_base_set_value", dynamicgraph::python::signalBase::setValue,
florent's avatar
florent committed
169
   METH_VARARGS, "Set the value of a signal"},
170
171
  {"signal_base_recompute", dynamicgraph::python::signalBase::recompute,
   METH_VARARGS, "Recompute the signal at given time"},
172
173
  {"signal_base_unplug", dynamicgraph::python::signalBase::unplug,
   METH_VARARGS, "Unplug the signal"},
Florent Lamiraux's avatar
Florent Lamiraux committed
174
175
176
177
  {"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"},
178
179
180
  // Entity
  {"create_entity", dynamicgraph::python::entity::create, METH_VARARGS,
   "create an Entity C++ object"},
181
182
  {"display_entity", dynamicgraph::python::entity::display, METH_VARARGS,
   "print an Entity C++ object"},
183
184
  {"entity_get_name", dynamicgraph::python::entity::getName, METH_VARARGS,
   "get the name of an Entity"},
Joseph Mirabel's avatar
Joseph Mirabel committed
185
186
  {"entity_get_class_name", dynamicgraph::python::entity::getClassName, METH_VARARGS,
   "get the class name of an Entity"},
187
188
  {"entity_has_signal", dynamicgraph::python::entity::hasSignal, METH_VARARGS,
   "return True if the entity has a signal with the given name"},
189
190
  {"entity_get_signal", dynamicgraph::python::entity::getSignal, METH_VARARGS,
   "get signal by name from an Entity"},
191
192
193
  {"entity_list_signals", dynamicgraph::python::entity::listSignals,
   METH_VARARGS,
   "Return the list of signals of an entity."},
florent's avatar
florent committed
194
195
196
197
  {"entity_execute_command",
   dynamicgraph::python::entity::executeCommand,
   METH_VARARGS,
   "execute a command"},
198
199
200
201
  {"entity_list_commands",
   dynamicgraph::python::entity::listCommands,
   METH_VARARGS,
   "list the commands of an entity"},
202
203
204
205
  {"entity_get_command_docstring",
   dynamicgraph::python::entity::getCommandDocstring,
   METH_VARARGS,
   "get the docstring of an entity command"},
206
207
208
209
  {"entity_get_docstring",
   dynamicgraph::python::entity::getDocString,
   METH_VARARGS,
   "get the doc string of an entity type"},
florent's avatar
florent committed
210
211
212
213
  {"factory_get_entity_class_list",
   dynamicgraph::python::factory::getEntityClassList,
   METH_VARARGS,
   "return the list of entity classes"},
214
215
216
217
  {"signal_caster_get_type_list",
   dynamicgraph::python::signalCaster::getSignalTypeList,
   METH_VARARGS,
   "return the list of signal type names"},
218
219
220
221
  {"writeGraph",
   dynamicgraph::python::pool::writeGraph,
   METH_VARARGS,
   "Write the graph of entities in a filename."},
222
223
224
225
  {"get_entity_list",
   dynamicgraph::python::pool::getEntityList,
   METH_VARARGS,
   "return the list of instanciated entities"},
florent's avatar
florent committed
226
227
228
229
230
231
232
233
  {NULL, NULL, 0, NULL}        /* Sentinel */
};

PyMODINIT_FUNC
initwrap(void)
{
    PyObject *m;

234
    m = Py_InitModule("wrap", dynamicGraphMethods);
florent's avatar
florent committed
235
236
    if (m == NULL)
        return;
237

florent's avatar
florent committed
238
    std::string msg("dynamic_graph.error");
florent's avatar
florent committed
239

240
    dynamicgraph::python::dgpyError =
florent's avatar
florent committed
241
      PyErr_NewException(const_cast<char*>(msg.c_str()), NULL, NULL);
242
243
    Py_INCREF(dynamicgraph::python::dgpyError);
    PyModule_AddObject(m, "error", dynamicgraph::python::dgpyError);
florent's avatar
florent committed
244
}