Skip to content
Snippets Groups Projects
Commit db1c58f5 authored by Guilhem Saurel's avatar Guilhem Saurel
Browse files

Merge branch 'coverage' into 'devel'

Merge Coverage into devel

See merge request !2
parents 982a0e0e 6bde0edb
No related branches found
No related tags found
1 merge request!2Merge Coverage into devel
Pipeline #5288 passed
Showing
with 866 additions and 1059 deletions
......@@ -4,7 +4,7 @@
They are several ways to perform debugging in dynamic-graph depending on your needs or situation:
- Programmatically inside the entity in C++ will write inside a buffer in a different thread and output in a stream
(either std::cout or a file). It is detailed in \subpage subp_debug_rt_logger.
- Programmatically inside the entity in C++ using a member of the entities and the previous real-time mechanism.
- Programmatically inside the entity in C++ using a member of the entities and the previous real-time mechanism.
It provides 4 levels of messags :(DEBUG,INFO, WARNING, ERROR). It is described in details here:
\subpage subp_logger
- Programmatically in C++ to avoid overhead with macros and handling level as an int: \subpage subp_dbg_trace
......
......@@ -66,7 +66,7 @@ Here is some example on how to display or record some information.
logger_.countdown();
\endcode
Specifying the file with __FILE__ and the line inside the file by __LINE__ are necessary for the
STREAM messages. Indeed they are indexed using the two values. As the default value are "" and 0
Specifying the file with __FILE__ and the line inside the file by __LINE__ are necessary for the
STREAM messages. Indeed they are indexed using the two values. As the default value are "" and 0
the counting will be confused.
*/
/**
/**
\page subp_debug_rt_logger Real-time Logger
It is intended to be used like this:
\code
#define ENABLE_RT_LOG
#include <dynamic-graph/real-time-logger.h>
// Somewhere in the main function of your executable
int main (int argc, char** argv) {
dgADD_OSTREAM_TO_RTLOG (std::cout);
}
// Somewhere in your library
dgRTLOG() << "your message. Prefer to use \n than std::endl."
\endcode
\note Thread safety. This class expects to have:
- only one reader: the one who take the log entries and write them somewhere.
- one writer at a time. Writing to the logs is **never** a blocking
......
......@@ -2,9 +2,9 @@
\page subp_dbg_trace Debugging with macros and level
\section subp_dbg_trace_intro Introduction
The idea of this class and collection of MACROS is to specify
a level for a message, and record the message in a stream according to this level.
In addition there are mechanisms allowing that no time
The idea of this class and collection of MACROS is to specify
a level for a message, and record the message in a stream according to this level.
In addition there are mechanisms allowing that no time
is wasted in condition test. You can therefore let the debugging messages
inside the code without impact on performances.
......@@ -42,7 +42,7 @@ It will generate the following output:
\code
/path_to/dynamic-graph/tests/debug-trace.cpp: testDebugTrace(#46) :# In {
\endcode
The output displays the name of the source file, the name of the method,
The output displays the name of the source file, the name of the method,
the line where is the macro, and the message itself.
When going out of the method:
......
......@@ -6,27 +6,25 @@
\image html entity.png
Despite the fact that it looks very similar to a ROS node or a CORBA/OpenRTM server, an entity is simply a C++ object.
The main idea is that this entity is providing mostly a data-driven functionnality working at very high rate (\f$ 200 Hz\f$ or \f$ 1 kHz \f$)
and should have a minimal computational time foot-print.
For this \subpage subp_signals (or ports to use a more classical terminology) are providing a time dependency between data.
To implement this, an output signal is linked with a method of the entity. The method calls input signals or use other means
to get the needed data.
It might be provided by the connection with remote computers through a middleware, or specific protocols,
but in general the external data is based upon the sensor values provided by a "Device" entity.
For this reason the signal evaluations are realized through the cascade of dependencies and start from the evaluation of an input
signal of a periodic node (in general the device). This is realized inside a \b real-time thread.
To add flexibility to a node, it is possible to add command with arguments to modify the internal behavior of the entity
or get information from the entity.
As a command is in general asynchronous and rare with respect to the data-flow scheme for the signals the command is in general
executed in a \b none-real-time thread.
The main idea is that this entity is providing mostly a data-driven functionnality working at very high rate (\f$ 200
Hz\f$ or \f$ 1 kHz \f$) and should have a minimal computational time foot-print.
For this \subpage subp_signals (or ports to use a more classical terminology) are providing a time dependency between
data. To implement this, an output signal is linked with a method of the entity. The method calls input signals or use
other means to get the needed data. It might be provided by the connection with remote computers through a middleware,
or specific protocols, but in general the external data is based upon the sensor values provided by a "Device" entity.
For this reason the signal evaluations are realized through the cascade of dependencies and start from the evaluation
of an input signal of a periodic node (in general the device). This is realized inside a \b real-time thread.
To add flexibility to a node, it is possible to add command with arguments to modify the internal behavior of the
entity or get information from the entity. As a command is in general asynchronous and rare with respect to the
data-flow scheme for the signals the command is in general executed in a \b none-real-time thread.
\subsection entity_classes Entity class
Entities are implemented as C++ classes and compiled as dynamic libraries. They can be loaded and instancied dynamically.
It is therefore necessary to specify the location of their dynamical libraries.
However given the time it might take to load the library, it is not advised to do that during a control-law computation.
Entity instanciation also implies memory allocation which is also time consuming and thus not advised inside a real-time thread.
Entities are implemented as C++ classes and compiled as dynamic libraries. They can be loaded and instancied
dynamically. It is therefore necessary to specify the location of their dynamical libraries. However given the time it
might take to load the library, it is not advised to do that during a control-law computation. Entity instanciation
also implies memory allocation which is also time consuming and thus not advised inside a real-time thread.
The entities will be placed in ${PREFIX}/lib/plugin (since this may change, it is advised to
check the install log or the CMakeLists.txt file to check the installation path).
......@@ -42,9 +40,10 @@ enable creation of this entity through the factory.
\subsection specific_semantics Specific semantics with entities
It is possible to derive classes and apply specific semantic for the entities. In our case we are interested in specific control semantics:
\li Tasks (more information <a href="http://stack-of-tasks.github.io/sot-core/doxygen/HEAD/a00089.html">here</a>)
\li Features (more information <a href="http://stack-of-tasks.github.io/sot-core/doxygen/HEAD/a00030.html">here</a>)
\li Solver (more information <a href="http://stack-of-tasks.github.io/sot-core/doxygen/HEAD/a00078.html">here</a>)
It is possible to derive classes and apply specific semantic for the entities. In our case we are interested in
specific control semantics: \li Tasks (more information <a
href="http://stack-of-tasks.github.io/sot-core/doxygen/HEAD/a00089.html">here</a>) \li Features (more information <a
href="http://stack-of-tasks.github.io/sot-core/doxygen/HEAD/a00030.html">here</a>) \li Solver (more information <a
href="http://stack-of-tasks.github.io/sot-core/doxygen/HEAD/a00078.html">here</a>)
*/
......@@ -11,8 +11,8 @@ Objects, which are derived from Entities (base class dynamicgraph::Entity), can
declared within the code and compiled as shared libraries (.so/.dll files).
These libraries can be loaded at run-time using the PluginLoader methods,
and at the same time register their class names to the Factory (see the
examples in the <a href="http://projects.laas.fr/gepetto/doc/stack-of-tasks/sot-core/master/doxygen-html">sot-core documentation</a>
for advanced control examples).
examples in the <a href="http://projects.laas.fr/gepetto/doc/stack-of-tasks/sot-core/master/doxygen-html">sot-core
documentation</a> for advanced control examples).
The Factory can then create instances of these objects and subsequently
register them in the Pool. From the pool they can be listed, accessed, and acted upon
......@@ -40,19 +40,19 @@ When writing entities you might use some macros which are very useful to write y
\subsection subsec_howto_typedef Entity helpers
The header <b>entity-helper.h</b> is defining a type called EntityClassName
The header <b>entity-helper.h</b> is defining a type called EntityClassName
\section sec_howto_macros_helpers Macro helpers
\subsection subsec_howto_macros_helpers_ent Preprocessing macros for entities
<ul>
<ul>
<li> <b>DYNAMIC_GRAPH_ENTITY_DECL()</b>:
This macro creates a method <b>getClassName()</b> which returns the class name.</li>
This macro <b>should</b> be used in the declaration of the class.
</li>
</li>
<li> <b>DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(classtype,classname)</b>
This macros creates the methods necessary to have a factory building the C++ class
This macros creates the methods necessary to have a factory building the C++ class
<b>classtype</b> from the string <b>classname</b>.
This macro <b>should</b> be used in the implementation of the class.
</li>
......@@ -101,7 +101,7 @@ The header <b>entity-helper.h</b> is defining a type called EntityClassName
<li> <b>DEFINE_SIGNAL_OUT_FUNCTION(signal_name, type)</b>:
This macro is used when implementing the method specific to the output signal.
It is used in the main body of the entity class to declare the header of the method
It is used in the main body of the entity class to declare the header of the method
with the following pattern:
\code
type EntityClassName::signal_nameSOUT_function(type &, int iter)
......@@ -109,7 +109,7 @@ The header <b>entity-helper.h</b> is defining a type called EntityClassName
</li>
</ul>
<li>
<li>
</li> Inner signals
<ul>
<li> <b> DECLARE_SIGNAL_INNER(signal_name,type)</b>
......@@ -123,8 +123,8 @@ The header <b>entity-helper.h</b> is defining a type called EntityClassName
type & EntityClassName::nameSINNER_function(signal_name)(type &, int)
\endcode
</li>
<li> <b>DEFINE_SIGNAL_INNER_FUNCTION(signal_name,type)</b>
This macro is used to implement the method related to signal_name. More precisely
<li> <b>DEFINE_SIGNAL_INNER_FUNCTION(signal_name,type)</b>
This macro is used to implement the method related to signal_name. More precisely
it provides the header of the member function(i.e. method) declaration.
</li>
<li><b>DECLARE_SIGNAL_INNER_FUNCTION(signal_name,type)</b>
......
......@@ -2,5 +2,6 @@
\page subp_factory Factory
\section sec_factory Factory
The class \ref dynamicgraph::FactoryStorage is a singleton which register the entity classes and which is allowing the instancation of such classes.
The class \ref dynamicgraph::FactoryStorage is a singleton which register the entity classes and which is allowing the
instancation of such classes.
*/
......@@ -7,10 +7,11 @@ In this package, the graph considered are directed graphs.
In dynamic-graph a graph is build with:
- computational nodes which are entities \subpage subpage_entities.
- directed edges which are created by connecting input and output signals \subpage subp_signals.
- managing the nodes is done through a factory \subpage subp_factory providing classes and a way to create instances from this list of classes.
- managing the nodes is done through a factory \subpage subp_factory providing classes and a way to create instances
from this list of classes.
- the instances of node are handled through a pool \subpage subp_pool
We strongly recommend to use a scripting language such as Python to
We strongly recommend to use a scripting language such as Python to
manage the graph.
See <c>dynamic-graph-python</c> for more information on binding dynamic-graph with Python.
......
......@@ -2,7 +2,7 @@
\page subp_pool Pool
\section pool Pool
The class \ref dynamicgraph::PoolStorage keeps track of the entities instanciated with the factory.
The entities are the graph nodes. Signals are constructed during the class instanciation, they do not live independently
from the entities. Signals are the directed edges of the graph.
The pool can write a file representing the graph of entities.
The entities are the graph nodes. Signals are constructed during the class instanciation, they do not live
independently from the entities. Signals are the directed edges of the graph. The pool can write a file representing
the graph of entities.
*/
/**
/**
\page subp_references References
\section sec_refer References
......@@ -7,7 +7,8 @@ Please when referencing the Stack-Of-Tasks use the following reference:
\anchor Mansard2009
<b> <a href="https://hal-lirmm.ccsd.cnrs.fr/lirmm-00796736/document">
"A versatile Generalized Inverted Kinematics implementation for collaborative working humanoid robots: The Stack Of Tasks"</a>
"A versatile Generalized Inverted Kinematics implementation for collaborative working humanoid robots: The Stack Of
Tasks"</a>
</b>,
<em>N. Mansard, O. Stasse, P. Evrard, A. Kheddar,</em>
Int. Conf. on Autonomous Robots, ICAR, 2009
......
......@@ -4,7 +4,7 @@
//
#ifndef DYNAMIC_GRAPH_ALL_COMMANDS_H
# define DYNAMIC_GRAPH_ALL_COMMANDS_H
#define DYNAMIC_GRAPH_ALL_COMMANDS_H
// Utility header files including all commands headers
......@@ -15,4 +15,4 @@
#include <dynamic-graph/command.h>
#include <dynamic-graph/command-setter.h>
#endif //! DYNAMIC_GRAPH_ALL_COMMANDS_H
#endif //! DYNAMIC_GRAPH_ALL_COMMANDS_H
......@@ -4,12 +4,12 @@
//
#ifndef DYNAMIC_GRAPH_ALL_SIGNALS_H
# define DYNAMIC_GRAPH_ALL_SIGNALS_H
#define DYNAMIC_GRAPH_ALL_SIGNALS_H
// Utility header files including all signal headers
# include <dynamic-graph/signal.h>
# include <dynamic-graph/signal-ptr.h>
# include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/signal-ptr.h>
#include <dynamic-graph/signal-time-dependent.h>
#endif //! DYNAMIC_GRAPH_ALL_SIGNALS_H
#endif //! DYNAMIC_GRAPH_ALL_SIGNALS_H
This diff is collapsed.
......@@ -20,42 +20,35 @@
/* --- GETTER --------------------------------------------------------- */
namespace dynamicgraph {
namespace command {
template <class E, typename T>
class DirectGetter
: public Command
{
public:
/// Pointer to method that sets parameter of type T
typedef T (E::*GetterMethod) () const;
/// Constructor
DirectGetter(E& entity,T* ptr,
const std::string& docString)
: Command(entity, std::vector<Value::Type>(), docString),
T_ptr(ptr) {}
protected:
virtual Value doExecute() { return Value(*T_ptr); }
private:
T* T_ptr;
};
template <class E, typename T>
DirectGetter<E,T>*
makeDirectGetter( E& entity,T* ptr,
const std::string& docString)
{ return new DirectGetter<E,T>(entity,ptr,docString); }
inline std::string docDirectGetter( const std::string& name,
const std::string& type )
{
return std::string("\nGet the ")+name+".\n\nNo input.\nReturn an "+type+".\n\n";
}
} // namespace command
} // namespace dynamicgraph
#endif // __dg_command_direct_getter_h__
namespace command {
template <class E, typename T>
class DirectGetter : public Command {
public:
/// Pointer to method that sets parameter of type T
typedef T (E::*GetterMethod)() const;
/// Constructor
DirectGetter(E& entity, T* ptr, const std::string& docString)
: Command(entity, std::vector<Value::Type>(), docString), T_ptr(ptr) {}
protected:
virtual Value doExecute() { return Value(*T_ptr); }
private:
T* T_ptr;
};
template <class E, typename T>
DirectGetter<E, T>* makeDirectGetter(E& entity, T* ptr, const std::string& docString) {
return new DirectGetter<E, T>(entity, ptr, docString);
}
inline std::string docDirectGetter(const std::string& name, const std::string& type) {
return std::string("\nGet the ") + name + ".\n\nNo input.\nReturn an " + type + ".\n\n";
}
} // namespace command
} // namespace dynamicgraph
#endif // __dg_command_direct_getter_h__
......@@ -20,45 +20,36 @@
/* --- SETTER --------------------------------------------------------- */
namespace dynamicgraph {
namespace command {
template <class E, typename T>
class DirectSetter
: public Command
{
public:
DirectSetter(E& entity,T* ptr,const std::string& docString)
:Command(entity, boost::assign::list_of(ValueHelper<T>::TypeID), docString)
,T_ptr(ptr)
{}
protected:
virtual Value doExecute()
{
const std::vector<Value>& values = getParameterValues();
T val = values[0].value();
(*T_ptr) = val;
return Value(); // void
}
private:
T* T_ptr;
};
template <class E, typename T>
DirectSetter<E,T>*
makeDirectSetter( E& entity,T* ptr,
const std::string& docString)
{ return new DirectSetter<E,T>(entity,ptr,docString); }
inline std::string docDirectSetter( const std::string& name,
const std::string& type )
{
return std::string("\nSet the ")+name+".\n\nInput:\n - a "
+type+".\nVoid return.\n\n";
}
} // namespace command
} // namespace dynamicgraph
#endif // __dg_command_direct_setter_h__
namespace command {
template <class E, typename T>
class DirectSetter : public Command {
public:
DirectSetter(E& entity, T* ptr, const std::string& docString)
: Command(entity, boost::assign::list_of(ValueHelper<T>::TypeID), docString), T_ptr(ptr) {}
protected:
virtual Value doExecute() {
const std::vector<Value>& values = getParameterValues();
T val = values[0].value();
(*T_ptr) = val;
return Value(); // void
}
private:
T* T_ptr;
};
template <class E, typename T>
DirectSetter<E, T>* makeDirectSetter(E& entity, T* ptr, const std::string& docString) {
return new DirectSetter<E, T>(entity, ptr, docString);
}
inline std::string docDirectSetter(const std::string& name, const std::string& type) {
return std::string("\nSet the ") + name + ".\n\nInput:\n - a " + type + ".\nVoid return.\n\n";
}
} // namespace command
} // namespace dynamicgraph
#endif // __dg_command_direct_setter_h__
......@@ -10,54 +10,53 @@
#include "dynamic-graph/command.h"
namespace dynamicgraph {
namespace command {
namespace command {
///
/// Command that calls a parameter getter function
///
/// This class is templated by a type E deriving from entity and
/// a type T of data.
///
/// Let us assume that class E has a private member of type T and a
/// public getter function for this member:
/// \code
/// class E : public Entity
/// {
/// public:
/// E (const std::string& inName) : Entity(inName) {}
/// T getParameter() const {return parameter_;}
/// private:
/// T parameter_;
/// };
/// \endcode
/// Then the command defined by:
/// \code
/// E entity("MyEntity");
/// Getter<E,T> command(entity, &E::getParameter)
/// \endcode
/// returns the value of <c>entity.parameter_</c> upon invocation.
///
/// \note
/// \li T should be a type supported by class Value,
/// \li prototype of E::getParameter should be exactly as specified in this
/// example.
template <class E, typename T>
class Getter : public Command {
public:
/// Pointer to method that sets parameter of type T
typedef T (E::*GetterMethod) () const;
/// Constructor
Getter(E& entity, GetterMethod getterMethod,
const std::string& docString);
///
/// Command that calls a parameter getter function
///
/// This class is templated by a type E deriving from entity and
/// a type T of data.
///
/// Let us assume that class E has a private member of type T and a
/// public getter function for this member:
/// \code
/// class E : public Entity
/// {
/// public:
/// E (const std::string& inName) : Entity(inName) {}
/// T getParameter() const {return parameter_;}
/// private:
/// T parameter_;
/// };
/// \endcode
/// Then the command defined by:
/// \code
/// E entity("MyEntity");
/// Getter<E,T> command(entity, &E::getParameter)
/// \endcode
/// returns the value of <c>entity.parameter_</c> upon invocation.
///
/// \note
/// \li T should be a type supported by class Value,
/// \li prototype of E::getParameter should be exactly as specified in this
/// example.
template <class E, typename T>
class Getter : public Command {
public:
/// Pointer to method that sets parameter of type T
typedef T (E::*GetterMethod)() const;
/// Constructor
Getter(E& entity, GetterMethod getterMethod, const std::string& docString);
protected:
virtual Value doExecute();
protected:
virtual Value doExecute();
private:
GetterMethod getterMethod_;
};
} // namespace command
} // namespace dynamicgraph
private:
GetterMethod getterMethod_;
};
} // namespace command
} // namespace dynamicgraph
#include "dynamic-graph/command-getter.t.cpp"
#endif //DYNAMIC_GRAPH_COMMAND_GETTER_H
#endif // DYNAMIC_GRAPH_COMMAND_GETTER_H
......@@ -10,25 +10,20 @@
#include <sstream>
namespace dynamicgraph {
class Entity;
namespace command {
class Entity;
namespace command {
template <class E, typename T>
Getter<E, T>::Getter(E& entity, GetterMethod getterMethod,
const std::string& docstring) :
Command(entity, std::vector<Value::Type>(), docstring),
getterMethod_(getterMethod)
{
}
template <class E, typename T>
Getter<E, T>::Getter(E& entity, GetterMethod getterMethod, const std::string& docstring)
: Command(entity, std::vector<Value::Type>(), docstring), getterMethod_(getterMethod) {}
template <class E, typename T>
Value Getter<E, T>::doExecute()
{
E& entity = static_cast<E&>(owner());
T value = (entity.*getterMethod_)();
return Value(value);
}
} // namespace command
} // namespace dynamicgraph
template <class E, typename T>
Value Getter<E, T>::doExecute() {
E& entity = static_cast<E&>(owner());
T value = (entity.*getterMethod_)();
return Value(value);
}
} // namespace command
} // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_COMMAND_GETTER_T_CPP
#endif // DYNAMIC_GRAPH_COMMAND_GETTER_T_CPP
......@@ -10,54 +10,53 @@
#include "dynamic-graph/command.h"
namespace dynamicgraph {
namespace command {
namespace command {
///
/// Command that calls a parameter setter function
///
/// This class is templated by a type E deriving from entity and
/// a type T of data.
///
/// Let us assume that class E has a private member of type T and a
/// public setter function for this member:
/// \code
/// class E : public Entity
/// {
/// public:
/// E (const std::string& inName) : Entity(inName) {}
/// void setParameter(const T& parameter) {parameter_ = parameter;}
/// private:
/// T parameter_;
/// };
/// \endcode
/// Then the command defined by:
/// \code
/// E entity("MyEntity");
/// Setter<E,T> command(entity, &E::getParameter)
/// \endcode
/// sets the value of <c>entity.parameter_</c> upon invocation.
///
/// \note
/// \li T should be a type supported by class Value,
/// \li prototype of E::setParameter should be exactly as specified in this
/// example.
template <class E, typename T>
class Setter : public Command {
public:
/// Pointer to method that sets parameter of type T
typedef void (E::*SetterMethod) (const T&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
///
/// Command that calls a parameter setter function
///
/// This class is templated by a type E deriving from entity and
/// a type T of data.
///
/// Let us assume that class E has a private member of type T and a
/// public setter function for this member:
/// \code
/// class E : public Entity
/// {
/// public:
/// E (const std::string& inName) : Entity(inName) {}
/// void setParameter(const T& parameter) {parameter_ = parameter;}
/// private:
/// T parameter_;
/// };
/// \endcode
/// Then the command defined by:
/// \code
/// E entity("MyEntity");
/// Setter<E,T> command(entity, &E::getParameter)
/// \endcode
/// sets the value of <c>entity.parameter_</c> upon invocation.
///
/// \note
/// \li T should be a type supported by class Value,
/// \li prototype of E::setParameter should be exactly as specified in this
/// example.
template <class E, typename T>
class Setter : public Command {
public:
/// Pointer to method that sets parameter of type T
typedef void (E::*SetterMethod)(const T&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
};
} // namespace command
} // namespace dynamicgraph
private:
SetterMethod setterMethod_;
};
} // namespace command
} // namespace dynamicgraph
#include "dynamic-graph/command-setter.t.cpp"
#endif //DYNAMIC_GRAPH_COMMAND_SETTER_H
#endif // DYNAMIC_GRAPH_COMMAND_SETTER_H
......@@ -12,314 +12,266 @@
#include "dynamic-graph/linear-algebra.h"
namespace dynamicgraph {
class Entity;
namespace command {
//
// Template specialization: bool
//
template <class E>
class Setter<E, bool> : public Command {
public:
/// Pointer to method that sets parameter of type bool
typedef void (E::*SetterMethod) (const bool&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, bool>::Setter(E& entity, SetterMethod setterMethod,
const std::string& docString) :
Command(entity, boost::assign::list_of(Value::BOOL), docString),
setterMethod_(setterMethod)
{
}
template <class E>
Value Setter<E, bool>::doExecute()
{
const std::vector<Value>& values = getParameterValues();
// Get parameter
bool value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: unsigned
//
template <class E>
class Setter<E, unsigned> : public Command {
public:
/// Pointer to method that sets parameter of type unsigned
typedef void (E::*SetterMethod) (const unsigned&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, unsigned>::Setter(E& entity, SetterMethod setterMethod,
const std::string& docString) :
Command(entity, boost::assign::list_of(Value::UNSIGNED), docString),
setterMethod_(setterMethod)
{
}
template <class E>
Value Setter<E, unsigned>::doExecute()
{
const std::vector<Value>& values = getParameterValues();
// Get parameter
unsigned value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: int
//
template <class E>
class Setter<E, int> : public Command {
public:
/// Pointer to method that sets parameter of type int
typedef void (E::*SetterMethod) (const int&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, int>::Setter(E& entity, SetterMethod setterMethod,
const std::string& docString) :
Command(entity, boost::assign::list_of(Value::INT), docString),
setterMethod_(setterMethod)
{
}
template <class E>
Value Setter<E, int>::doExecute()
{
const std::vector<Value>& values = getParameterValues();
// Get parameter
int value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: float
//
template <class E>
class Setter<E, float> : public Command {
public:
/// Pointer to method that sets parameter of type float
typedef void (E::*SetterMethod) (const float&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, float>::Setter(E& entity, SetterMethod setterMethod,
const std::string& docString) :
Command(entity, boost::assign::list_of(Value::FLOAT), docString),
setterMethod_(setterMethod)
{
}
template <class E>
Value Setter<E, float>::doExecute()
{
const std::vector<Value>& values = getParameterValues();
// Get parameter
float value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: double
//
template <class E>
class Setter<E, double> : public Command {
public:
/// Pointer to method that sets parameter of type double
typedef void (E::*SetterMethod) (const double&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, double>::Setter(E& entity, SetterMethod setterMethod,
const std::string& docString) :
Command(entity, boost::assign::list_of(Value::DOUBLE), docString),
setterMethod_(setterMethod)
{
}
template <class E>
Value Setter<E, double>::doExecute()
{
const std::vector<Value>& values = getParameterValues();
// Get parameter
double value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: std::string
//
template <class E>
class Setter<E, std::string> : public Command {
public:
/// Pointer to method that sets parameter of type std::string
typedef void (E::*SetterMethod) (const std::string&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, std::string>::Setter(E& entity, SetterMethod setterMethod,
const std::string& docString) :
Command(entity, boost::assign::list_of(Value::STRING), docString),
setterMethod_(setterMethod)
{
}
template <class E>
Value Setter<E, std::string>::doExecute()
{
const std::vector<Value>& values = getParameterValues();
// Get parameter
std::string value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: Vector
//
template <class E>
class Setter<E, Vector> : public Command {
public:
/// Pointer to method that sets parameter of type Vector
typedef void (E::*SetterMethod) (const Vector&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, Vector>::Setter(E& entity, SetterMethod setterMethod,
const std::string& docString) :
Command(entity, boost::assign::list_of(Value::VECTOR), docString),
setterMethod_(setterMethod)
{
}
template <class E>
Value Setter<E, Vector>::doExecute()
{
const std::vector<Value>& values = getParameterValues();
// Get parameter
Vector value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: Matrix
//
template <class E>
class Setter<E, Matrix> : public Command {
public:
/// Pointer to method that sets parameter of type Matrix
typedef void (E::*SetterMethod) (const Matrix&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod,
const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, Matrix>::Setter(E& entity, SetterMethod setterMethod,
const std::string& docString) :
Command(entity, boost::assign::list_of(Value::MATRIX), docString),
setterMethod_(setterMethod)
{
}
template <class E>
Value Setter<E, Matrix>::doExecute()
{
const std::vector<Value>& values = getParameterValues();
// Get parameter
Matrix value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
} // namespace command
} // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_COMMAND_SETTER_T_CPP
class Entity;
namespace command {
//
// Template specialization: bool
//
template <class E>
class Setter<E, bool> : public Command {
public:
/// Pointer to method that sets parameter of type bool
typedef void (E::*SetterMethod)(const bool&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, bool>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString)
: Command(entity, boost::assign::list_of(Value::BOOL), docString), setterMethod_(setterMethod) {}
template <class E>
Value Setter<E, bool>::doExecute() {
const std::vector<Value>& values = getParameterValues();
// Get parameter
bool value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: unsigned
//
template <class E>
class Setter<E, unsigned> : public Command {
public:
/// Pointer to method that sets parameter of type unsigned
typedef void (E::*SetterMethod)(const unsigned&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, unsigned>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString)
: Command(entity, boost::assign::list_of(Value::UNSIGNED), docString), setterMethod_(setterMethod) {}
template <class E>
Value Setter<E, unsigned>::doExecute() {
const std::vector<Value>& values = getParameterValues();
// Get parameter
unsigned value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: int
//
template <class E>
class Setter<E, int> : public Command {
public:
/// Pointer to method that sets parameter of type int
typedef void (E::*SetterMethod)(const int&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, int>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString)
: Command(entity, boost::assign::list_of(Value::INT), docString), setterMethod_(setterMethod) {}
template <class E>
Value Setter<E, int>::doExecute() {
const std::vector<Value>& values = getParameterValues();
// Get parameter
int value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: float
//
template <class E>
class Setter<E, float> : public Command {
public:
/// Pointer to method that sets parameter of type float
typedef void (E::*SetterMethod)(const float&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, float>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString)
: Command(entity, boost::assign::list_of(Value::FLOAT), docString), setterMethod_(setterMethod) {}
template <class E>
Value Setter<E, float>::doExecute() {
const std::vector<Value>& values = getParameterValues();
// Get parameter
float value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: double
//
template <class E>
class Setter<E, double> : public Command {
public:
/// Pointer to method that sets parameter of type double
typedef void (E::*SetterMethod)(const double&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, double>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString)
: Command(entity, boost::assign::list_of(Value::DOUBLE), docString), setterMethod_(setterMethod) {}
template <class E>
Value Setter<E, double>::doExecute() {
const std::vector<Value>& values = getParameterValues();
// Get parameter
double value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: std::string
//
template <class E>
class Setter<E, std::string> : public Command {
public:
/// Pointer to method that sets parameter of type std::string
typedef void (E::*SetterMethod)(const std::string&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, std::string>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString)
: Command(entity, boost::assign::list_of(Value::STRING), docString), setterMethod_(setterMethod) {}
template <class E>
Value Setter<E, std::string>::doExecute() {
const std::vector<Value>& values = getParameterValues();
// Get parameter
std::string value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: Vector
//
template <class E>
class Setter<E, Vector> : public Command {
public:
/// Pointer to method that sets parameter of type Vector
typedef void (E::*SetterMethod)(const Vector&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, Vector>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString)
: Command(entity, boost::assign::list_of(Value::VECTOR), docString), setterMethod_(setterMethod) {}
template <class E>
Value Setter<E, Vector>::doExecute() {
const std::vector<Value>& values = getParameterValues();
// Get parameter
Vector value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
//
// Template specialization: Matrix
//
template <class E>
class Setter<E, Matrix> : public Command {
public:
/// Pointer to method that sets parameter of type Matrix
typedef void (E::*SetterMethod)(const Matrix&);
/// Constructor
Setter(E& entity, SetterMethod setterMethod, const std::string& docString);
protected:
virtual Value doExecute();
private:
SetterMethod setterMethod_;
}; // Class Setter
template <class E>
Setter<E, Matrix>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString)
: Command(entity, boost::assign::list_of(Value::MATRIX), docString), setterMethod_(setterMethod) {}
template <class E>
Value Setter<E, Matrix>::doExecute() {
const std::vector<Value>& values = getParameterValues();
// Get parameter
Matrix value = values[0].value();
E& entity = static_cast<E&>(owner());
(entity.*setterMethod_)(value);
return Value();
}
} // namespace command
} // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_COMMAND_SETTER_T_CPP
......@@ -12,57 +12,58 @@
#include "dynamic-graph/dynamic-graph-api.h"
namespace dynamicgraph {
class Entity;
namespace command {
/// Abstract class for entity commands
///
/// This class provide a mean to control entities from external python script.
///
/// A command
/// \li is owned by an entity,
/// \li takes parameters of type Value,
/// \li return an instance of Value when calling Command::execute()
///
/// At construction, the prototype of the command is defined by providing
/// a vector of Value::Type.
///
/// Parameters are set by calling Command::setParameterValues with a
/// vector of Values the types of which should fit the vector specified
/// at construction.
class DYNAMIC_GRAPH_DLLAPI Command
{
public:
virtual ~Command();
/// Store the owner entity and a vector of value types
/// \param entity reference to Entity owning this command.
/// \param valueTypes vector specifying the number and types of parameters
/// \param docstring documentation of the command
Command(Entity& entity, const std::vector<Value::Type>& valueTypes,
const std::string& docstring);
/// Return the value type of all parameters
const std::vector<Value::Type>& valueTypes() const;
/// Set parameter values
void setParameterValues(const std::vector<Value>& values);
/// Get parameter values
const std::vector<Value>& getParameterValues() const;
/// Execute the command after checking parameters
Value execute();
/// Get a reference to the Entity owning this command
Entity& owner();
/// Get documentation string
std::string getDocstring() const;
protected:
/// Specific action performed by the command
virtual Value doExecute() = 0;
private:
Entity& owner_;
std::vector<Value::Type> valueTypeVector_;
std::vector<Value> valueVector_;
std::string docstring_;
public:
static const std::vector<Value::Type> EMPTY_ARG;
};
} // namespace command
} // namespace dynamicgraph
class Entity;
namespace command {
/// Abstract class for entity commands
///
/// This class provide a mean to control entities from external python script.
///
/// A command
/// \li is owned by an entity,
/// \li takes parameters of type Value,
/// \li return an instance of Value when calling Command::execute()
///
/// At construction, the prototype of the command is defined by providing
/// a vector of Value::Type.
///
/// Parameters are set by calling Command::setParameterValues with a
/// vector of Values the types of which should fit the vector specified
/// at construction.
class DYNAMIC_GRAPH_DLLAPI Command {
public:
virtual ~Command();
/// Store the owner entity and a vector of value types
/// \param entity reference to Entity owning this command.
/// \param valueTypes vector specifying the number and types of parameters
/// \param docstring documentation of the command
Command(Entity& entity, const std::vector<Value::Type>& valueTypes, const std::string& docstring);
/// Return the value type of all parameters
const std::vector<Value::Type>& valueTypes() const;
/// Set parameter values
void setParameterValues(const std::vector<Value>& values);
/// Get parameter values
const std::vector<Value>& getParameterValues() const;
/// Execute the command after checking parameters
Value execute();
/// Get a reference to the Entity owning this command
Entity& owner();
/// Get documentation string
std::string getDocstring() const;
#endif //DYNAMIC_GRAPH_COMMAND_H
protected:
/// Specific action performed by the command
virtual Value doExecute() = 0;
private:
Entity& owner_;
std::vector<Value::Type> valueTypeVector_;
std::vector<Value> valueVector_;
std::string docstring_;
public:
static const std::vector<Value::Type> EMPTY_ARG;
};
} // namespace command
} // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_COMMAND_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment