Commit ff6fc7db authored by florent's avatar florent
Browse files

Implement bindings for Entity and SignalBase C++ classes.

	  * src/CMakeLists.txt,
	  * src/dynamic-graph-py.cc,
	  * src/dynamic_graph/__init__.py,
	  * src/dynamic_graph/entity.py: new,
	  * src/dynamic_graph/signal_base.py: new,
	  * src/entity-py.cc: new,
	  * src/signal-base-py.cc: new.
parent 25894620
......@@ -31,7 +31,10 @@ SET(PYTHON_MODULE wrap)
ADD_LIBRARY(${PYTHON_MODULE}
MODULE
dynamic-graph-py.cc)
dynamic-graph-py.cc
signal-base-py.cc
entity-py.cc
)
# Remove prefix lib
SET_TARGET_PROPERTIES(${PYTHON_MODULE}
......@@ -58,6 +61,8 @@ INSTALL(TARGETS ${PYTHON_MODULE}
SET (PYTHON_SOURCES
dynamic_graph/__init__.py
dynamic_graph/entity.py
dynamic_graph/signal_base.py
)
SET (PYTHON_SOURCES_FULLPATH "")
......
......@@ -8,40 +8,107 @@
#include <sstream>
#include <string>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/interpreter.h>
#include <dynamic-graph/shell-functions.h>
static PyObject* error;
namespace dynamicgraph {
namespace python {
static dynamicgraph::Interpreter interpreter;
// Declare functions defined in other source files
namespace signalBase {
extern PyObject* create(PyObject* self, PyObject* args);
extern PyObject* getTime(PyObject* self, PyObject* args);
}
namespace entity {
extern PyObject* create(PyObject* self, PyObject* args);
extern PyObject* getName(PyObject* self, PyObject* args);
extern PyObject* getSignal(PyObject* self, PyObject* args);
extern PyObject* displaySignals(PyObject* self, PyObject* args);
static PyObject*
plug(PyObject* self, PyObject* args)
{
char* out = NULL;
char* in = NULL;
if (!PyArg_ParseTuple(args,"ss", &out, &in))
return NULL;
std::stringstream ss;
std::ostringstream os;
ss << std::string(out) << " " << std::string(in);
std::istringstream cmdArg(ss.str());
try {
interpreter.cmdPlug(std::string("plug"), cmdArg, os);
} catch (dynamicgraph::ExceptionFactory& exc) {
PyErr_SetString(error, exc.getStringMessage().c_str());
return NULL;
}
}
PyObject* error;
static dynamicgraph::Interpreter interpreter;
/**
\brief plug a signal into another one.
*/
PyObject*
plug(PyObject* self, PyObject* args)
{
char* out = NULL;
char* in = NULL;
if (!PyArg_ParseTuple(args,"ss", &out, &in))
return NULL;
std::stringstream ss;
std::ostringstream os;
ss << std::string(out) << " " << std::string(in);
std::istringstream cmdArg(ss.str());
try {
interpreter.cmdPlug(std::string("plug"), cmdArg, os);
} catch (dynamicgraph::ExceptionFactory& exc) {
PyErr_SetString(error, exc.getStringMessage().c_str());
return NULL;
}
return Py_BuildValue("");
return Py_BuildValue("");
}
PyObject*
enableTrace(PyObject* self, PyObject* args)
{
char* trueFalse = NULL;
char* filename = NULL;
std::stringstream ss;
std::ostringstream os;
if (PyArg_ParseTuple(args,"ss", &trueFalse, &filename)) {
ss << std::string(trueFalse) << " " << std::string(filename);
} else if (PyArg_ParseTuple(args,"s", &trueFalse)) {
ss << std::string(trueFalse);
} else {
return NULL;
}
std::istringstream cmdArg(ss.str());
try {
ShellFunctions::cmdEnableTrace(std::string("debugtrace"), cmdArg, os);
} catch (dynamicgraph::ExceptionFactory& exc) {
PyErr_SetString(error, exc.getStringMessage().c_str());
return NULL;
}
return Py_BuildValue("");
}
}
}
/**
\brief List of python functions
*/
static PyMethodDef sotTutorialMethods[] = {
{"plug", plug, METH_VARARGS,
"plug an output signal into an input signal"},
static PyMethodDef dynamicGraphMethods[] = {
{"plug", dynamicgraph::python::plug, METH_VARARGS,
"plug an output signal into an input signal"},
{"debugtrace", 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"},
{"signalbase_get_time", dynamicgraph::python::signalBase::getTime,
METH_VARARGS, "Get time of a SignalBase"},
// Entity
{"create_entity", dynamicgraph::python::entity::create, METH_VARARGS,
"create an Entity C++ object"},
{"entity_get_name", dynamicgraph::python::entity::getName, METH_VARARGS,
"get the name of an Entity"},
{"entity_get_signal", dynamicgraph::python::entity::getSignal, METH_VARARGS,
"get signal by name from an Entity"},
{"entity_display_signals", dynamicgraph::python::entity::displaySignals,
METH_VARARGS,
"Display the list of signals of an entity in standard output"},
{NULL, NULL, 0, NULL} /* Sentinel */
};
......@@ -50,11 +117,12 @@ initwrap(void)
{
PyObject *m;
m = Py_InitModule("wrap", sotTutorialMethods);
m = Py_InitModule("wrap", dynamicGraphMethods);
if (m == NULL)
return;
error = PyErr_NewException("dynamic_graph.wrap.error", NULL, NULL);
Py_INCREF(error);
PyModule_AddObject(m, "error", error);
dynamicgraph::python::error =
PyErr_NewException("dynamic_graph.wrap.error", NULL, NULL);
Py_INCREF(dynamicgraph::python::error);
PyModule_AddObject(m, "error", dynamicgraph::python::error);
}
......@@ -4,3 +4,4 @@ Author: Florent Lamiraux
"""
import wrap
import entity, signal_base
"""
Copyright (C) 2010 CNRS
Author: Florent Lamiraux
"""
import wrap, signal_base
class Entity:
"""
This class binds dynamicgraph::Entity C++ class
"""
object = None
def __init__(self, name):
"""
Constructor: if not called by a child class, create and store a pointer
to a C++ Entity object.
"""
if not self.object :
self.object = wrap.create_entity(self, name)
@property
def name(self) :
return wrap.entity_get_name(self.object)
def get_signal (self, name) :
"""
Get a signal of the entity from signal name
"""
signalPt = wrap.entity_get_signal(self.object, name)
return signal_base.SignalBase("", signalPt)
def display_signals(self) :
"""
Write the list of signals into standard output: temporary.
"""
wrap.entity_display_signals(self.object)
"""
Copyright (C) 2010 CNRS
Author: Florent Lamiraux
"""
import wrap
class SignalBase:
"""
This class binds dynamicgraph::SignalBase<int> C++ class
"""
def __init__(self, name, object = None) :
"""
Constructor: create and store a pointer to a C++ Entity object if
- the constructor is not called by a child class and
- object parameter is not provided.
If object parameter is provided, the class wraps an already existing
C++ object.
"""
if object is None :
if not hasattr(self, "object") :
self.object = wrap.create_signal_base(name)
else :
self.object = object
@property
def time(self) :
"""
Get time of signal
"""
return wrap.signalBaseGetTime(self.object)
/*
* Copyright 2010 (C) CNRS
* Author: Florent Lamiraux
*/
#include <Python.h>
#include <iostream>
//#include <sstream>
//#include <string>
#include <dynamic-graph/entity.h>
using dynamicgraph::Entity;
using dynamicgraph::SignalBase;
using dynamicgraph::ExceptionAbstract;
namespace dynamicgraph {
namespace python {
extern PyObject* error;
namespace entity {
static void destroy (void* self);
/**
\brief Create an instance of Entity
*/
PyObject* create(PyObject* self, PyObject* args)
{
char *name = NULL;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
Entity* obj = NULL;
try {
obj = new Entity(name);
} catch (dynamicgraph::ExceptionFactory& exc) {
PyErr_SetString(error, exc.getStringMessage().c_str());
return NULL;
}
// Return the pointer as an integer
return PyCObject_FromVoidPtr((void*)obj, destroy);
}
/**
\brief Destroy an instance of Entity
*/
static void destroy (void* self)
{
Entity* obj = (Entity*)self;
delete obj;
}
/**
\brief Get name of entity
*/
PyObject* getName(PyObject* self, PyObject* args)
{
PyObject* object = NULL;
void* pointer = NULL;
std::string name;
if (!PyArg_ParseTuple(args, "O", &object))
return NULL;
if (!PyCObject_Check(object))
return NULL;
pointer = PyCObject_AsVoidPtr(object);
Entity* entity = (Entity*)pointer;
try {
name = entity->getName();
} catch(ExceptionAbstract& exc) {
PyErr_SetString(error, exc.getStringMessage().c_str());
return NULL;
}
return Py_BuildValue("s", name.c_str());
}
/**
\brief Get a signal by name
*/
PyObject* getSignal(PyObject* self, PyObject* args)
{
char *name = NULL;
PyObject* object = NULL;
void* pointer = NULL;
if (!PyArg_ParseTuple(args, "Os", &object, &name))
return NULL;
if (!PyCObject_Check(object))
return NULL;
pointer = PyCObject_AsVoidPtr(object);
Entity* entity = (Entity*)pointer;
SignalBase<int>* signal = NULL;
try {
signal = &(entity->getSignal(std::string(name)));
} catch(ExceptionAbstract& exc) {
PyErr_SetString(error, exc.getStringMessage().c_str());
return NULL;
}
// Return the pointer to the signal without destructor since the signal
// is not owned by the calling object but by the Entity.
return PyCObject_FromVoidPtr((void*)signal, NULL);
}
PyObject* displaySignals(PyObject* self, PyObject* args)
{
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object))
return NULL;
if (!PyCObject_Check(object))
return NULL;
pointer = PyCObject_AsVoidPtr(object);
Entity* entity = (Entity*)pointer;
try {
entity->displaySignalList(std::cout);
} catch(ExceptionAbstract& exc) {
PyErr_SetString(error, exc.getStringMessage().c_str());
return NULL;
}
return Py_BuildValue("");
}
}
}
}
/*
* Copyright 2010 (C) CNRS
* Author: Florent Lamiraux
*/
#include <Python.h>
#include <iostream>
//#include <sstream>
//#include <string>
#include <dynamic-graph/signal-base.h>
using dynamicgraph::SignalBase;
namespace dynamicgraph {
namespace python {
extern PyObject* error;
namespace signalBase {
static void destroy (void* self);
/**
\brief Create an instance of SignalBase
*/
PyObject* create(PyObject* self, PyObject* args)
{
char *name = NULL;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
SignalBase<int>* obj = NULL;
obj = new SignalBase<int>(std::string(name));
// Return the pointer
return PyCObject_FromVoidPtr((void*)obj, destroy);
}
/**
\brief Destroy an instance of InvertedPendulum
*/
static void destroy (void* self)
{
SignalBase<int>* obj = (SignalBase<int>*)self;
delete obj;
}
PyObject* getTime(PyObject* self, PyObject* args)
{
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args,"O", &object))
return NULL;
if (!PyCObject_Check(object))
return NULL;
pointer = PyCObject_AsVoidPtr(object);
SignalBase<int>* obj = (SignalBase<int>*)pointer;
int time = obj->getTime();
return Py_BuildValue("i", time);
}
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment