Newer
Older
"""
Copyright (C) 2010 CNRS
Author: Florent Lamiraux
"""
import wrap, signal_base, new

Nicolas Mansard
committed
from attrpath import setattrpath
entityClassNameList = []
if 'display' not in globals().keys():
def display(s):
print(s)
def commandMethod(name, docstring) :
return wrap.entity_execute_command(self.obj, name, arg)
method.__doc__ = docstring
def initEntity(self, name):
"""
Common constructor of Entity classes
"""
Entity.__init__(self, self.className, name)
if not self.__class__.commandCreated:
# Get list of commands of the Entity object
commands = wrap.entity_list_commands(self.obj)
# for each command, add a method with the name of the command
for command in commands:
docstring = wrap.entity_get_command_docstring(self.obj, command)

Nicolas Mansard
committed
setattrpath(self.__class__, command, commandMethod(command, docstring))
self.__class__.commandCreated = True
class PyEntityFactoryClass(type):
"""
The class build dynamically a new class type, and return the reference
on the class-type object. The class type is not added to any context.
"""
def __new__(factory, className ):
EntityClass = type.__new__(factory, className, (Entity,), {})
EntityClass.className = className
EntityClass.__init__ = initEntity
EntityClass.commandCreated = False
return EntityClass
def PyEntityFactory( className, context ):
"""
Build a new class type by calling the factory, and add it
to the given context.
"""
EntityClass = PyEntityFactoryClass( className )
context[ className ] = EntityClass
return EntityClass
def updateEntityClasses(dictionary):
"""
For all c++entity types that are not in the pyentity class list (entityClassNameList)
run the factory and store the new type in the given context (dictionary).
"""
cxx_entityList = wrap.factory_get_entity_class_list()
for e in filter(lambda x: not x in entityClassNameList, cxx_entityList):
# Store new class in dictionary with class name
# Store class name in local list
entityClassNameList.append(e)
class Entity (object) :
"""
This class binds dynamicgraph::Entity C++ class
"""
"""
Constructor: if not called by a child class, create and store a pointer
to a C++ Entity object.
"""
object.__setattr__(self, 'obj', wrap.create_entity(className, instanceName) )
@property
def name(self) :
def __str__(self) :
return wrap.display_entity(self.obj)
def signal (self, name) :
"""
Get a signal of the entity from signal name
"""
signalPt = wrap.entity_get_signal(self.obj, name)
return signal_base.SignalBase(name = "", obj = signalPt)
Print the list of signals into standard output: temporary.
Florent Lamiraux
committed
signals = self.signals()
display ("--- <" + self.name + "> signal list: ")
Florent Lamiraux
committed
for s in signals[:-1]:
display(" |-- <" + str(s))
display(" `-- <" + str(signals[-1]))
sl = wrap.entity_list_signals(self.obj)
return map(lambda pyObj: signal_base.SignalBase(obj=pyObj), sl)
def commands(self):
return wrap.entity_list_commands(self.obj)
def globalHelp(self):
"""
Print a short description of each command.
"""
for cstr in self.commands():
ctitle=cstr+':'
for i in range(len(cstr),15):
ctitle+=' '
for docstr in wrap.entity_get_command_docstring(self.obj,cstr).split('\n'):
if (len(docstr)>0) and (not docstr.isspace()):
break
def help( self,comm=None ):
"""
With no arg, print the global help. With arg the name of
a specific command, print the help associated to the command.
"""
if comm is None:
self.globalHelp()
else:
display(comm+":\n"+wrap.entity_get_command_docstring(self.obj,comm))
def __getattr__(self, name):
Florent Lamiraux
committed
return self.signal(name)
except:
object.__getattr__(self, name)
def boundNewCommand(self,cmdName):
"""
At construction, all existing commands are bound directly in the class.
This method enables to bound new commands dynamically. These new bounds
are not made with the class, but directly with the object instance.
"""
if (cmdName in self.__dict__) | (cmdName in self.__class__.__dict__):
print "Warning: command ",cmdName," will overwrite an object attribute."
docstring = wrap.entity_get_command_docstring(self.obj, cmdName)
cmd = commandMethod(cmdName,docstring)

Nicolas Mansard
committed
# Limitation (todo): does not handle for path attribute name (see setattrpath).
setattr(self,cmdName,new.instancemethod( cmd, self,self.__class__))
def boundAllNewCommands(self):
"""
For all commands that are not attribute of the object instance nor of the
class, a new attribute of the instance is created to bound the command.
"""
cmdList = wrap.entity_list_commands(self.obj)
cmdList = filter(lambda x: not x in self.__dict__, cmdList)
cmdList = filter(lambda x: not x in self.__class__.__dict__, cmdList)
for cmd in cmdList:
self.boundNewCommand( cmd )
# Script short-cuts: don't use this syntaxt in python coding,

Nicolas Mansard
committed
# use it for debuging online only!
@property
def sigs(self):
self.displaySignals()