Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cberge/dynamic-graph
  • ostasse/dynamic-graph
  • gsaurel/dynamic-graph
  • stack-of-tasks/dynamic-graph
4 results
Show changes
Showing
with 2234 additions and 2364 deletions
......@@ -10,9 +10,8 @@
#include <Eigen/Geometry>
namespace dynamicgraph {
typedef Eigen::MatrixXd Matrix;
typedef Eigen::VectorXd Vector;
}
typedef Eigen::MatrixXd Matrix;
typedef Eigen::VectorXd Vector;
} // namespace dynamicgraph
#endif //DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
#endif // DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
......@@ -12,215 +12,278 @@
/* --- API ------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
#if defined (WIN32)
# if defined (logger_EXPORTS)
# define LOGGER_EXPORT __declspec(dllexport)
# else
# define LOGGER_EXPORT __declspec(dllimport)
# endif
#if defined(WIN32)
#if defined(logger_EXPORTS)
#define LOGGER_EXPORT __declspec(dllexport)
#else
# define LOGGER_EXPORT
#define LOGGER_EXPORT __declspec(dllimport)
#endif
#else
#define LOGGER_EXPORT
#endif
namespace dynamicgraph {
/** Enum representing the different kind of messages.
*/
enum MsgType
{
MSG_TYPE_DEBUG =0,
MSG_TYPE_INFO =1,
MSG_TYPE_WARNING =2,
MSG_TYPE_ERROR =3,
MSG_TYPE_DEBUG_STREAM =4,
MSG_TYPE_INFO_STREAM =5,
MSG_TYPE_WARNING_STREAM =6,
MSG_TYPE_ERROR_STREAM =7
};
}
/** Enum representing the different kind of messages.
*/
enum MsgType {
MSG_TYPE_TYPE_BITS = 1 << 0 | 1 << 1 | 1 << 2 | 1 << 3, // 15
MSG_TYPE_STREAM_BIT = 1 << 4, // 16
MSG_TYPE_DEBUG = 1 << 3, // 1
MSG_TYPE_INFO = 1 << 2, // 2
MSG_TYPE_WARNING = 1 << 1, // 4
MSG_TYPE_ERROR = 1 << 0, // 8
MSG_TYPE_DEBUG_STREAM = MSG_TYPE_DEBUG | MSG_TYPE_STREAM_BIT, // 17
MSG_TYPE_INFO_STREAM = MSG_TYPE_INFO | MSG_TYPE_STREAM_BIT, // 18
MSG_TYPE_WARNING_STREAM = MSG_TYPE_WARNING | MSG_TYPE_STREAM_BIT, // 20
MSG_TYPE_ERROR_STREAM = MSG_TYPE_ERROR | MSG_TYPE_STREAM_BIT // 24
};
} // namespace dynamicgraph
/* --------------------------------------------------------------------- */
/* --- INCLUDE --------------------------------------------------------- */
/* --------------------------------------------------------------------- */
#include <map>
#include <iomanip> // std::setprecision
/// \todo These 3 headers should be removed.
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/real-time-logger-def.h>
#include <boost/assign.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <dynamic-graph/deprecated.hh>
#include <fstream>
#include <iomanip> // std::setprecision
#include <sstream>
#include "boost/assign.hpp"
#include <dynamic-graph/linear-algebra.h>
namespace dynamicgraph {
//#define LOGGER_VERBOSITY_INFO_WARNING_ERROR
#define LOGGER_VERBOSITY_ALL
#define SEND_MSG(msg,type) sendMsg(msg,type,__FILE__,__LINE__)
#define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_DEBUG_STREAM)
#define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_INFO_STREAM)
#define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_WARNING_STREAM)
#define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_ERROR_STREAM)
template<typename T>
std::string toString(const T& v, const int precision=3, const int width=-1)
{
std::stringstream ss;
if(width>precision)
ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v;
else
ss<<std::fixed<<std::setprecision(precision)<<v;
return ss.str();
#define SEND_MSG(msg, type) \
sendMsg(msg, type, __FILE__ ":" BOOST_PP_STRINGIZE(__LINE__))
#define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_DEBUG_STREAM)
#define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_INFO_STREAM)
#define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING_STREAM)
#define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR_STREAM)
#define _DYNAMIC_GRAPH_ENTITY_MSG(entity, type) \
(entity).logger().stream(type, __FILE__ BOOST_PP_STRINGIZE(__LINE__))
#define DYNAMIC_GRAPH_ENTITY_DEBUG(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_DEBUG)
#define DYNAMIC_GRAPH_ENTITY_INFO(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_INFO)
#define DYNAMIC_GRAPH_ENTITY_WARNING(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_WARNING)
#define DYNAMIC_GRAPH_ENTITY_ERROR(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_ERROR)
#define DYNAMIC_GRAPH_ENTITY_DEBUG_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_DEBUG_STREAM)
#define DYNAMIC_GRAPH_ENTITY_INFO_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_INFO_STREAM)
#define DYNAMIC_GRAPH_ENTITY_WARNING_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_WARNING_STREAM)
#define DYNAMIC_GRAPH_ENTITY_ERROR_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_ERROR_STREAM)
template <typename T>
std::string toString(const T &v, const int precision = 3,
const int width = -1) {
std::stringstream ss;
if (width > precision)
ss << std::fixed << std::setw(width) << std::setprecision(precision) << v;
else
ss << std::fixed << std::setprecision(precision) << v;
return ss.str();
}
template <typename T>
std::string toString(const std::vector<T> &v, const int precision = 3,
const int width = -1, const std::string separator = ", ") {
std::stringstream ss;
if (width > precision) {
for (unsigned int i = 0; i < v.size() - 1; i++)
ss << std::fixed << std::setw(width) << std::setprecision(precision)
<< v[i] << separator;
ss << std::fixed << std::setw(width) << std::setprecision(precision)
<< v[v.size() - 1];
} else {
for (unsigned int i = 0; i < v.size() - 1; i++)
ss << std::fixed << std::setprecision(precision) << v[i] << separator;
ss << std::fixed << std::setprecision(precision) << v[v.size() - 1];
}
return ss.str();
}
template <typename T>
std::string toString(const Eigen::MatrixBase<T> &v, const int precision = 3,
const int width = -1, const std::string separator = ", ") {
std::stringstream ss;
if (width > precision) {
for (unsigned int i = 0; i < v.size() - 1; i++)
ss << std::fixed << std::setw(width) << std::setprecision(precision)
<< v[i] << separator;
ss << std::fixed << std::setw(width) << std::setprecision(precision)
<< v[v.size() - 1];
} else {
for (unsigned int i = 0; i < v.size() - 1; i++)
ss << std::fixed << std::setprecision(precision) << v[i] << separator;
ss << std::setprecision(precision) << v[v.size() - 1];
}
return ss.str();
}
enum LoggerVerbosity {
VERBOSITY_ALL = MSG_TYPE_DEBUG,
VERBOSITY_INFO_WARNING_ERROR = MSG_TYPE_INFO,
VERBOSITY_WARNING_ERROR = MSG_TYPE_WARNING,
VERBOSITY_ERROR = MSG_TYPE_ERROR,
VERBOSITY_NONE = 0
};
/// \ingroup debug
///
/// \brief Class for logging messages
///
/// 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) {
/// std::ofstream of;
/// of.open("/tmp/dg-LOGS.txt",std::ofstream::out|std::ofstream::app);
/// dgADD_OSTREAM_TO_RTLOG (of);
/// }
///
/// // Somewhere in your library
/// dynamicgraph::LoggerVerbosity aLoggerVerbosityLevel =
/// VERBOSITY_WARNING_ERROR;
/// entity.setLoggerVerbosityLevel(aLoggerVerbosityLevel);
/// ...
/// // using macros
/// DYNAMIC_GRAPH_ENTITY_WARNING(entity) << "your message\n";
///
/// // or the equivalent code without macros:
/// // Please use '\n' instead of std::endl and flushing will have no effect
/// entity.logger.stream(dynamicgraph::MSG_TYPE_WARNING,
/// __FILE__ BOOST_PP_STRINGIZE(__LINE__))
/// << your message << '\n';
///
/// \endcode
///
/// \todo remove m_timeSample and streamPrintPeriod to rather use a simple
/// integer counting the number of calls. This will achieve exactly the
/// same behaviour without rouding numerical errors.
class Logger {
public:
/** Constructor */
Logger(double timeSample = 0.001, double streamPrintPeriod = 1.0);
/** Destructor */
~Logger();
/** Method to be called at every control iteration
* to decrement the internal Logger's counter. */
void countdown();
/** Get an output stream independently of the debug level.
*/
RTLoggerStream stream() {
return ::dynamicgraph::RealTimeLogger::instance().front();
}
template<typename T>
std::string toString(const std::vector<T>& v, const int precision=3, const int width=-1,
const std::string separator=", ")
{
std::stringstream ss;
if(width>precision)
{
for(int i=0; i<v.size()-1; i++)
ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v[i]<<separator;
ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v[v.size()-1];
}
else
{
for(int i=0; i<v.size()-1; i++)
ss<<std::fixed<<std::setprecision(precision)<<v[i]<<separator;
ss<<std::fixed<<std::setprecision(precision)<<v[v.size()-1];
}
return ss.str();
/** Print the specified message on standard output if the verbosity level
* allows it. The lineId is used to identify the point where sendMsg is
* called so that streaming messages are printed only every streamPrintPeriod
* iterations.
* \param type specifies the verbosity level, for instance MSG_TYPE_DEBUG
* \param lineId typically __FILE__ ":" BOOST_PP_STRINGIZE(__LINE__)
*/
RTLoggerStream stream(MsgType type, const std::string &lineId = "") {
RealTimeLogger &rtlogger = ::dynamicgraph::RealTimeLogger::instance();
if (acceptMsg(type, lineId)) return rtlogger.front();
return rtlogger.emptyStream();
}
// template<typename T, int N>
// std::string toString(const Eigen::Matrix<T, N, 1, 0, N, 1>& v, const std::string separator=", ",
// const int precision=3, const int width=-1)
template<typename T>
std::string toString(const Eigen::MatrixBase<T>& v,
const int precision=3, const int width=-1, const std::string separator=", ")
{
std::stringstream ss;
if(width>precision)
{
for(int i=0; i<v.size()-1; i++)
ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v[i]<<separator;
ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v[v.size()-1];
}
else
{
for(int i=0; i<v.size()-1; i++)
ss<<std::fixed<<std::setprecision(precision)<<v[i]<<separator;
ss<<std::setprecision(precision)<<v[v.size()-1];
}
return ss.str();
/** \deprecated instead, use
* \code
* stream(type, lineId) << msg << '\n';
* \endcode
*/
[[deprecated("use stream(type, lineId) << msg")]] void sendMsg(
std::string msg, MsgType type, const std::string &lineId = "");
/** \deprecated instead, use
* \code
* stream(type, lineId) << msg << '\n';
* \endcode
*/
[[deprecated("use stream(type, lineId) << msg")]] void sendMsg(
std::string msg, MsgType type, const std::string &file, int line);
/** Set the sampling time at which the method countdown()
* is going to be called. */
bool setTimeSample(double t);
/** Get the sampling time at which the method countdown()
* is going to be called. */
double getTimeSample();
/** Set the time period for printing of streaming messages. */
bool setStreamPrintPeriod(double s);
/** Get the time period for printing of streaming messages. */
double getStreamPrintPeriod();
/** Set the verbosity level of the logger. */
void setVerbosity(LoggerVerbosity lv);
/** Get the verbosity level of the logger. */
LoggerVerbosity getVerbosity();
protected:
LoggerVerbosity m_lv; /// verbosity of the logger
double m_timeSample;
/// specify the period of call of the countdown method
double m_streamPrintPeriod; /// specify the time period of the stream prints
double m_printCountdown;
/// every time this is < 0 (i.e. every _streamPrintPeriod sec) print stuff
typedef std::map<std::string, double> StreamCounterMap_t;
/** Pointer to the dynamic structure which holds
the collection of streaming messages */
StreamCounterMap_t m_stream_msg_counters;
inline bool isStreamMsg(MsgType m) { return (m & MSG_TYPE_STREAM_BIT); }
/** Check whether a message of type \p m and from \p c lineId should be
* accepted. \note If \p m is a stream type, the internal counter associated
* to \p lineId is updated.
*/
bool acceptMsg(MsgType m, const std::string &lineId) {
// If more verbose than the current verbosity level
if ((m & MSG_TYPE_TYPE_BITS) > m_lv) return false;
// if print is allowed by current verbosity level
if (isStreamMsg(m)) return checkStreamPeriod(lineId);
return true;
}
enum LoggerVerbosity
{
VERBOSITY_ALL,
VERBOSITY_INFO_WARNING_ERROR,
VERBOSITY_WARNING_ERROR,
VERBOSITY_ERROR,
VERBOSITY_NONE
};
/// \ingroup debug
///
/// \brief Class for logging messages
///
/// 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) {
/// std::ofstream of;
/// of.open("/tmp/dg-LOGS.txt",std::ofstream::out|std::ofstream::app);
/// dgADD_OSTREAM_TO_RTLOG (of);
/// }
///
/// // Somewhere in your library
/// dynamicgraph::LoggerVerbosity aLoggerVerbosityLevel = VERBOSITY_WARNING_ERROR;
/// entity.setLoggerVerbosityLevel(aLoggerVerbosityLevel);
/// ...
/// std::string aMsg=aBaseMsg+" WARNING";
/// entity.sendMsg(aMsg,dynamicgraph::MSG_TYPE_WARNING, __FILE__,__LINE__);
///
/// \endcode
///
///
class Logger
{
public:
/** Constructor */
Logger(double timeSample=0.001, double streamPrintPeriod=1.0);
/** Destructor */
~Logger();
/** Method to be called at every control iteration
* to decrement the internal Logger's counter. */
void countdown();
/** Print the specified message on standard output if the verbosity level
* allows it. The file name and the line number are used to identify
* the point where sendMsg is called so that streaming messages are
* printed only every streamPrintPeriod iterations.
*/
void sendMsg(std::string msg, MsgType type, const char* file="", int line=0);
/** Set the sampling time at which the method countdown()
* is going to be called. */
bool setTimeSample(double t);
/** Get the sampling time at which the method countdown()
* is going to be called. */
double getTimeSample();
/** Set the time period for printing of streaming messages. */
bool setStreamPrintPeriod(double s);
/** Get the time period for printing of streaming messages. */
double getStreamPrintPeriod();
/** Set the verbosity level of the logger. */
void setVerbosity(LoggerVerbosity lv);
/** Get the verbosity level of the logger. */
LoggerVerbosity getVerbosity();
protected:
LoggerVerbosity m_lv; /// verbosity of the logger
double m_timeSample; /// specify the period of call of the countdown method
double m_streamPrintPeriod; /// specify the time period of the stream prints
double m_printCountdown; /// every time this is < 0 (i.e. every _streamPrintPeriod sec) print stuff
/** Pointer to the dynamic structure which holds the collection of streaming messages */
std::map<std::string, double> m_stream_msg_counters;
bool isStreamMsg(MsgType m)
{ return m==MSG_TYPE_ERROR_STREAM || m==MSG_TYPE_DEBUG_STREAM || m==MSG_TYPE_INFO_STREAM || m==MSG_TYPE_WARNING_STREAM; }
bool isDebugMsg(MsgType m)
{ return m==MSG_TYPE_DEBUG_STREAM || m==MSG_TYPE_DEBUG; }
bool isInfoMsg(MsgType m)
{ return m==MSG_TYPE_INFO_STREAM || m==MSG_TYPE_INFO; }
bool isWarningMsg(MsgType m)
{ return m==MSG_TYPE_WARNING_STREAM || m==MSG_TYPE_WARNING; }
bool isErrorMsg(MsgType m)
{ return m==MSG_TYPE_ERROR_STREAM || m==MSG_TYPE_ERROR; }
};
} // namespace dynamicgraph
#endif // #ifndef __sot_torque_control_logger_H__
/** Check whether a message from \c lineId should be accepted.
* \note The internal counter associated to \c lineId is updated.
*/
bool checkStreamPeriod(const std::string &lineId);
};
} // namespace dynamicgraph
#endif // #ifndef __sot_torque_control_logger_H__
// Copyright 2010, Thomas Moulard, JRL, CNRS/AIST
//
#ifndef DYNAMIC_GRAPH_NULL_PTR_HH
# define DYNAMIC_GRAPH_NULL_PTR_HH
namespace dynamicgraph
{
const class
{
public:
template<class T>
operator T*() const
{
return 0;
}
template<class C, class T>
operator T C::*() const
{
return 0;
}
private:
void operator&() const;
} nullptr = {};
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_NULL_PTR_HH
......@@ -4,117 +4,115 @@
//
#ifndef DYNAMIC_GRAPH_POOL_H
# define DYNAMIC_GRAPH_POOL_H
# include <map>
# include <string>
# include <sstream>
#define DYNAMIC_GRAPH_POOL_H
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/signal-base.h>
#include <dynamic-graph/fwd.hh>
#include <map>
#include <sstream>
#include <string>
namespace dynamicgraph {
/*! @ingroup dgraph
\brief Singleton that keeps track of all the entities.
This class gives access to and remembers all the entities created
during its life.
This class provides the necessary operations to register, unregister each
instance of thoses classes.
As tasks and features derived from Entities, they should be registered
as such.
\note From the code it is not very clear why we should not unregister
from the tasks and the features...
*/
class DYNAMIC_GRAPH_DLLAPI PoolStorage {
public:
/*! \name Define types to simplify the writing
@{
*/
/*! \brief Sorted set of entities with unique key (name). */
typedef std::map<std::string, Entity *> Entities;
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/exception-factory.h>
# include <dynamic-graph/signal-base.h>
# include <dynamic-graph/dynamic-graph-api.h>
/// \brief Get unique instance of the class.
static PoolStorage *getInstance();
namespace dynamicgraph
{
/*! @ingroup dgraph
\brief Singleton that keeps track of all the entities.
/// \brief Destroy the unique instance of the class
static void destroy();
This class gives access to and remembers all the entities created
during its life.
/*! @} */
This class provides the necessary operations to register, unregister each
instance of thoses classes.
As tasks and features derived from Entities, they should be registered
as such.
/*! \brief Default destructor */
~PoolStorage();
\note From the code it is not very clear why we should not unregister
from the tasks and the features...
/*! \name Method related to the handling of entities.
@{
*/
/*! \brief Register an entity.
\par[in] entname: The name of the entity,
\par[in] ent: Pointer towards the entity.
*/
void registerEntity(const std::string &entname, Entity *ent);
/*! \brief Unregister an entity.
\par[in] entname: The name of the entity,
*/
class DYNAMIC_GRAPH_DLLAPI PoolStorage
{
public:
/*! \name Define types to simplify the writing
@{
*/
/*! \brief Sorted set of entities with unique key (name). */
typedef std::map< std::string,Entity* > Entities;
/// \brief Get unique instance of the class.
static PoolStorage *getInstance();
/// \brief Destroy the unique instance of the class
static void destroy();
/*! @} */
/*! \brief Default destructor */
~PoolStorage ();
/*! \name Method related to the handling of entities.
@{
*/
/*! \brief Register an entity.
\par[in] entname: The name of the entity,
\par[in] ent: Pointer towards the entity.
*/
void registerEntity (const std::string& entname, Entity* ent);
/*! \brief Unregister an entity.
\par[in] entname: The name of the entity,
*/
void deregisterEntity (const std::string& entname);
/*! \brief Unregister an entity.
\par[in] entity: iterator in the map,
*/
void deregisterEntity( const Entities::iterator& entity );
/*! \brief Get an entity.
\par[in] entname: The name of the entity,
\return Pointer towards the entity.
*/
Entity& getEntity (const std::string& name);
/// Const access to entity map
const Entities& getEntityMap () const;
/*! \brief Test if the entity exists. */
bool existEntity (const std::string& name);
/*! \brief Test if the entity exists. If it does, return a pointer on it. */
bool existEntity (const std::string& name, Entity*& ptr);
/*! \brief Disallocate an entity.
\par[in] entname: The name of the entity,
*/
void clearPlugin (const std::string& name);
/*! @} */
///
/// \brief Get a signal by name
///
/// \param sigpath stream containing a string of the form "entity.signal"
SignalBase<int>& getSignal( std::istringstream& sigpath );
/*! \brief This method write a graph description on the file named
FileName. */
void writeGraph (const std::string& aFileName);
void writeCompletionList (std::ostream& os);
protected:
/*! \name Fields of the class to manage the three entities.
Also the name is singular, those are true sets.
@{
*/
/*! \brief Set of basic objects of the SoT */
Entities entityMap;
private:
PoolStorage () {}
static PoolStorage* instance_;
};
inline PoolStorage& g_pool() { return *PoolStorage::getInstance(); }
void deregisterEntity(const std::string &entname);
/*! \brief Unregister an entity.
\par[in] entity: iterator in the map,
*/
void deregisterEntity(const Entities::iterator &entity);
/*! \brief Get an entity.
\par[in] entname: The name of the entity,
\return Pointer towards the entity.
*/
Entity &getEntity(const std::string &name);
/// Const access to entity map
const Entities &getEntityMap() const;
/*! \brief Test if the entity exists. */
bool existEntity(const std::string &name);
/*! \brief Test if the entity exists. If it does, return a pointer on it. */
bool existEntity(const std::string &name, Entity *&ptr);
/*! \brief Disallocate an entity.
\par[in] entname: The name of the entity,
*/
void clearPlugin(const std::string &name);
/*! @} */
///
/// \brief Get a signal by name
///
/// \param sigpath stream containing a string of the form "entity.signal"
SignalBase<int> &getSignal(std::istringstream &sigpath);
/*! \brief This method write a graph description on the file named
FileName. */
void writeGraph(const std::string &aFileName);
void writeCompletionList(std::ostream &os);
protected:
/*! \name Fields of the class to manage the three entities.
Also the name is singular, those are true sets.
@{
*/
/*! \brief Set of basic objects of the SoT */
Entities entityMap;
private:
PoolStorage() {}
static PoolStorage *instance_;
};
inline PoolStorage &g_pool() { return *PoolStorage::getInstance(); }
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_POOL_H
#endif //! DYNAMIC_GRAPH_POOL_H
/* Copyright LAAS, CNRS
* Author: O. Stasse, 2019
* See LICENSE file in the root directory of this repository.
*/
#ifndef DYNAMIC_GRAPH_PROCESS_LIST_H_
#define DYNAMIC_GRAPH_PROCESS_LIST_H_
#include <dynamic-graph/dynamic-graph-api.h>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <dynamic-graph/fwd.hh>
namespace dynamicgraph {
namespace CPU {
class DYNAMIC_GRAPH_DLLAPI ProcessData {};
class DYNAMIC_GRAPH_DLLAPI ProcessList {
public:
ProcessList();
};
/// This class gather information on a specific CPU.
///
class DYNAMIC_GRAPH_DLLAPI CPUData {
public:
CPUData();
int cpu_id_;
inline unsigned long long int computePeriod(unsigned long long int &a,
unsigned long long int &b) {
return (a > b) ? a - b : 0;
}
/// \brief Various classes of time spend by the CPU
/// @{
/// Total time
unsigned long long int total_time_;
/// Time spend in user mode
unsigned long long int user_mode_time_;
/// Time spend in user mode with low priority (nice mode)
unsigned long long int nice_time_;
/// Time spend in system mode
unsigned long long int system_time_;
/// Time spend in system mode
unsigned long long int system_all_time_;
/// Time spend in doing nothing.
unsigned long long int idle_time_;
/// Time spend in doing nothing.
unsigned long long int idle_all_time_;
/// Time spend in waiting an input/output to complete.
unsigned long long int iowait_time_;
/// Time spend in servicing hardware interrupts.
unsigned long long int irq_time_;
/// Time spend in servicing software interrupts.
unsigned long long int softirq_time_;
/// Time spend in other operating systems in a virtualized environments
/// Never doing this for control !
unsigned long long int steal_time_;
/// Time spend running a virtual CPU for guest operating systems
/// under the control of the Linux kernel
unsigned long long int guest_time_;
/// Time spent running a niced guest
/// (virtual CPU for guest operating systems under the
/// control of the Linux kernel)
unsigned long long int guest_nice_time_;
/// @}
/// \brief Various classes of time spend by the CPU by period
/// @{
/// Total time
unsigned long long int total_period_;
/// Time spend in user mode
unsigned long long int user_mode_period_;
/// Time spend in user mode with low priority (nice mode)
unsigned long long int nice_period_;
/// Time spend in system mode
unsigned long long int system_period_;
/// Time spend in all system mode
unsigned long long int system_all_period_;
/// Time spend in doing nothing.
unsigned long long int idle_period_;
/// Time spend in doing nothing.
unsigned long long int idle_all_period_;
/// Time spend in waiting an input/output to complete.
unsigned long long int iowait_period_;
/// Time spend in servicing hardware interrupts.
unsigned long long int irq_period_;
/// Time spend in servicing software interrupts.
unsigned long long int softirq_period_;
/// Time spend in other operating systems in a virtualized environments
/// Never doing this for control !
unsigned long long int steal_period_;
/// Time spend running a virtual CPU for guest operating systems
/// under the control of the Linux kernel
unsigned long long int guest_period_;
/// @}
double percent_;
void ProcessLine(std::istringstream &aCPULine);
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar &version;
ar &total_time_;
ar &user_mode_time_;
ar &nice_time_;
ar &system_time_;
ar &system_all_time_;
ar &idle_time_;
ar &idle_all_time_;
ar &iowait_time_;
ar &irq_time_;
ar &softirq_time_;
ar &steal_time_;
ar &guest_time_;
ar &guest_nice_time_;
ar &percent_;
}
};
/// This class gathers information on a computer.
/// This includes a list of CPU
class DYNAMIC_GRAPH_DLLAPI System {
private:
bool init_;
public:
System();
/// Read /proc/state file to extract CPU count.
void init();
/// Update CPU data information from /proc/stat
void readProcStat();
/// Friend class for serialization.
friend class boost::serialization::access;
/// Number of CPU.
unsigned int cpuNb_;
void ProcessCPULine(unsigned int cpunb, std::istringstream &aCPULine);
/// \brief Vector of CPU informations.
std::vector<CPUData> vCPUData_;
/// \brief Global CPU information.
CPUData gCPUData_;
template <class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar &version;
ar &cpuNb_;
ar &gCPUData_;
ar &vCPUData_;
}
};
} // namespace CPU
} // namespace dynamicgraph
#endif /* DYNAMIC_GRAPH_PROCESS_LIST_H_ */
// -*- mode: c++ -*-
// Copyright 2018, Joseph Mirabel LAAS-CNRS
//
#ifndef DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
#define DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <dynamic-graph/config.hh>
#include <sstream>
#include <vector>
namespace dynamicgraph {
/// \ingroup debug
///
/// \brief Stream for the real-time logger.
///
/// You should inherit from this class in order to redirect the logs where you
/// want.
/// \sa LoggerIOStream
class LoggerStream {
public:
virtual void write(const char *c) = 0;
};
/// Write to an ostream object.
///
/// The easieast is to use the macro dgADD_OSTREAM_TO_RTLOG(ostr) where
/// `ostr` can be `std::cout` or an std::ofstream...
class LoggerIOStream : public LoggerStream {
public:
LoggerIOStream(std::ostream &os) : os_(os) {}
virtual ~LoggerIOStream() {}
virtual void write(const char *c) { os_ << c; }
private:
std::ostream &os_;
};
typedef boost::shared_ptr<LoggerStream> LoggerStreamPtr_t;
class RealTimeLogger;
/// \cond DEVEL
/// \brief write entries to intenal buffer.
///
/// The entry starts when an instance is created and ends when is is deleted.
/// This class is only used by RealTimeLogger.
class RTLoggerStream {
public:
inline RTLoggerStream(RealTimeLogger *logger, std::ostream &os)
: ok_(logger != NULL), logger_(logger), os_(os) {}
template <typename T>
inline RTLoggerStream &operator<<(T t) {
if (ok_) os_ << t;
return *this;
}
inline RTLoggerStream &operator<<(std::ostream &(*pf)(std::ostream &)) {
if (ok_) os_ << pf;
return *this;
}
inline ~RTLoggerStream();
inline bool isNull() { return !ok_; }
private:
const bool ok_;
RealTimeLogger *logger_;
std::ostream &os_;
};
/// \endcond DEVEL
/// \ingroup debug
///
/// \brief Main class of the 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
/// operation. If the resource is busy, the log entry is discarded.
class DYNAMIC_GRAPH_DLLAPI RealTimeLogger {
public:
static RealTimeLogger &instance();
static void destroy();
/// \todo add an argument to preallocate the internal string
/// to a given size.
RealTimeLogger(const std::size_t &bufferSize);
inline void clearOutputStreams() { outputs_.clear(); }
inline void addOutputStream(const LoggerStreamPtr_t &os) {
outputs_.push_back(os);
}
/// Write next message to output.
/// It does nothing if the buffer is empty.
/// \return true if it wrote something
bool spinOnce();
/// Return an object onto which a real-time thread can write.
/// The message is considered finished when the object is destroyed.
RTLoggerStream front();
/// Return an empty stream object.
RTLoggerStream emptyStream() { return RTLoggerStream(NULL, oss_); }
inline void frontReady() {
backIdx_ = (backIdx_ + 1) % buffer_.size();
wmutex.unlock();
}
inline bool empty() const { return frontIdx_ == backIdx_; }
inline bool full() const {
return ((backIdx_ + 1) % buffer_.size()) == frontIdx_;
}
inline std::size_t size() const {
if (frontIdx_ <= backIdx_)
return backIdx_ - frontIdx_;
else
return backIdx_ + buffer_.size() - frontIdx_;
}
inline std::size_t getBufferSize() { return buffer_.size(); }
~RealTimeLogger();
private:
struct Data {
std::stringbuf buf;
};
std::vector<LoggerStreamPtr_t> outputs_;
std::vector<Data *> buffer_;
/// Index of the next value to be read.
std::size_t frontIdx_;
/// Index of the slot where to write next value
/// (does not contain valid data).
std::size_t backIdx_;
std::ostream oss_;
/// The writer mutex.
boost::mutex wmutex;
std::size_t nbDiscarded_;
struct thread;
static RealTimeLogger *instance_;
static thread *thread_;
};
RTLoggerStream::~RTLoggerStream() {
if (ok_) {
os_ << std::ends;
logger_->frontReady();
}
}
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
......@@ -3,170 +3,24 @@
//
#ifndef DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
# define DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
# include <sstream>
# include <vector>
# include <boost/circular_buffer.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/thread/mutex.hpp>
# include <dynamic-graph/config.hh>
# include <dynamic-graph/debug.h>
namespace dynamicgraph
{
/// \ingroup debug
///
/// \brief Stream for the real-time logger.
///
/// You should inherit from this class in order to redirect the logs where you
/// want.
/// \sa LoggerIOStream
class LoggerStream
{
public:
virtual void write (const char* c) = 0;
};
/// Write to an ostream object.
///
/// The easieast is to use the macro \ref dgADD_OSTREAM_TO_RTLOG(ostr) where
/// `ostr` can be `std::cout` or an std::ofstream...
class LoggerIOStream : public LoggerStream
{
public:
LoggerIOStream (std::ostream& os) : os_ (os) {}
virtual void write (const char* c) { os_ << c; }
private:
std::ostream& os_;
};
typedef boost::shared_ptr <LoggerStream> LoggerStreamPtr_t;
class RealTimeLogger;
/// \cond DEVEL
/// \brief write entries to intenal buffer.
///
/// The entry starts when an instance is created and ends when is is deleted.
/// This class is only used by RealTimeLogger.
class RTLoggerStream
{
public:
RTLoggerStream (RealTimeLogger* logger, std::ostream& os) : logger_(logger), os_ (os) {}
template <typename T> inline RTLoggerStream& operator<< (T t) { if (logger_!=NULL) os_ << t; return *this; }
inline RTLoggerStream& operator<< (std::ostream& (*pf)(std::ostream&)) { if (logger_!=NULL) os_ << pf; return *this; }
~RTLoggerStream();
private:
RealTimeLogger* logger_;
std::ostream& os_;
};
/// \endcond DEVEL
/// \ingroup debug
///
/// \brief Main class of the 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
/// operation. If the resource is busy, the log entry is discarded.
class DYNAMIC_GRAPH_DLLAPI RealTimeLogger
{
public:
static RealTimeLogger& instance();
static void destroy();
/// \todo add an argument to preallocate the internal string to a given size.
RealTimeLogger (const std::size_t& bufferSize);
inline void clearOutputStreams () { outputs_.clear(); }
inline void addOutputStream (const LoggerStreamPtr_t& os) { outputs_.push_back(os); }
/// Write next message to output.
/// It does nothing if the buffer is empty.
/// \return true if it wrote something
bool spinOnce ();
/// Return an object onto which a real-time thread can write.
/// The message is considered finished when the object is destroyed.
RTLoggerStream front();
inline void frontReady() { backIdx_ = (backIdx_+1) % buffer_.size(); wmutex.unlock(); }
inline bool empty () const
{
return frontIdx_ == backIdx_;
}
inline bool full () const
{
return ((backIdx_ + 1) % buffer_.size()) == frontIdx_;
}
inline std::size_t size () const
{
if (frontIdx_ <= backIdx_)
return backIdx_ - frontIdx_;
else
return backIdx_ + buffer_.size() - frontIdx_;
}
inline std::size_t getBufferSize () { return buffer_.size(); }
~RealTimeLogger ();
private:
struct Data {
std::stringbuf buf;
};
std::vector<LoggerStreamPtr_t> outputs_;
std::vector<Data*> buffer_;
/// Index of the next value to be read.
std::size_t frontIdx_;
/// Index of the slot where to write next value (does not contain valid data).
std::size_t backIdx_;
std::ostream oss_;
/// The writer mutex.
boost::mutex wmutex;
std::size_t nbDiscarded_;
struct thread;
static RealTimeLogger* instance_;
static thread* thread_;
};
} // end of namespace dynamicgraph
#define DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
#ifdef ENABLE_RT_LOG
# define dgADD_OSTREAM_TO_RTLOG(ostr) ::dynamicgraph::RealTimeLogger::instance() \
.addOutputStream(::dynamicgraph::LoggerStreamPtr_t(new ::dynamicgraph::LoggerIOStream(ostr)))
# define dgRTLOG() ::dynamicgraph::RealTimeLogger::instance().front()
#else // ENABLE_RT_LOG
# define dgADD_OSTREAM_TO_RTLOG(ostr) struct __end_with_semicolon
# define dgRTLOG() if (1) ; else __null_stream()
#define dgADD_OSTREAM_TO_RTLOG(ostr) \
::dynamicgraph::RealTimeLogger::instance().addOutputStream( \
::dynamicgraph::LoggerStreamPtr_t( \
new ::dynamicgraph::LoggerIOStream(ostr)))
#define dgRTLOG() ::dynamicgraph::RealTimeLogger::instance().front()
#else // ENABLE_RT_LOG
#define dgADD_OSTREAM_TO_RTLOG(ostr) struct __end_with_semicolon
#define dgRTLOG() \
if (1) \
; \
else \
__null_stream()
#endif
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
#include <dynamic-graph/real-time-logger-def.h>
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
......@@ -4,188 +4,151 @@
//
#ifndef DYNAMIC_GRAPH_SIGNAL_ARRAY_H
# define DYNAMIC_GRAPH_SIGNAL_ARRAY_H
# include <dynamic-graph/signal-base.h>
# include <dynamic-graph/dynamic-graph-api.h>
# include <vector>
#define DYNAMIC_GRAPH_SIGNAL_ARRAY_H
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/signal-base.h>
#include <stdio.h>
namespace dynamicgraph
{
/// \ingroup dgraph
///
/// \brief TODO
template<class Time>
class SignalArray_const
{
public:
static const int DEFAULT_SIZE = 20;
protected:
std::vector< const SignalBase<Time>* > const_array;
unsigned int size,rank;
public:
SignalArray_const<Time> (const unsigned int& sizeARG = DEFAULT_SIZE)
: const_array (sizeARG),
size (sizeARG),
rank (0)
{}
SignalArray_const<Time> (const SignalBase<Time>& sig)
: const_array (DEFAULT_SIZE),
size (DEFAULT_SIZE),
rank (0)
{
addElmt(&sig);
}
SignalArray_const<Time> (const SignalArray<Time>& siga)
: const_array (siga.getSize()),
size (siga.getSize ()),
rank (siga.getSize ())
{
for (unsigned int i = 0; i < rank; ++i)
const_array[i] = &siga[i];
}
SignalArray_const<Time> (const SignalArray_const<Time>& siga)
: const_array(siga.getSize ()),
size(siga.getSize ()),
rank(siga.getSize ())
{
for (unsigned int i = 0; i < rank; ++i)
const_array[i] = &siga[i];
}
#include <vector>
virtual ~SignalArray_const<Time> (){}
namespace dynamicgraph {
protected:
/// \ingroup dgraph
///
/// \brief TODO
template <class Time>
class SignalArray_const {
public:
static const int DEFAULT_SIZE = 20;
void addElmt (const SignalBase<Time>* el)
{
if (rank >= size)
{
size += DEFAULT_SIZE;
const_array.resize(size);
}
const_array[rank++] = el;
}
protected:
std::vector<const SignalBase<Time> *> const_array;
unsigned int size, rank;
public:
virtual SignalArray_const<Time>& operator<< (const SignalBase<Time>& sig)
{
addElmt (&sig);
return *this;
}
public:
virtual const SignalBase<Time>& operator[] (const unsigned int& idx) const
{
return *const_array[idx];
}
virtual unsigned int getSize () const
{
return rank;
}
};
public:
SignalArray_const<Time>(const unsigned int &sizeARG = DEFAULT_SIZE)
: const_array(sizeARG), size(sizeARG), rank(0) {}
SignalArray_const<Time>(const SignalBase<Time> &sig)
: const_array(DEFAULT_SIZE), size(DEFAULT_SIZE), rank(0) {
addElmt(&sig);
}
template<class Time>
SignalArray_const<Time> operator<< (const SignalBase<Time>& sig1,
const SignalBase<Time>& sig2)
{
SignalArray_const<Time> res(sig1);
res<<sig2;
return res;
SignalArray_const<Time>(const SignalArray<Time> &siga)
: const_array(siga.getSize()),
size(siga.getSize()),
rank(siga.getSize()) {
for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i];
}
/// \ingroup dgraph
///
/// \brief TODO
template<class Time>
class SignalArray : public SignalArray_const<Time>
{
public:
using SignalArray_const<Time>::DEFAULT_SIZE;
using SignalArray_const<Time>::size;
using SignalArray_const<Time>::rank;
protected:
mutable std::vector< SignalBase<Time>* > array;
public:
SignalArray<Time> (const unsigned int& sizeARG = DEFAULT_SIZE)
: SignalArray_const<Time> (0),
array(sizeARG)
{
size=sizeARG;
}
SignalArray_const<Time>(const SignalArray_const<Time> &siga)
: const_array(siga.getSize()),
size(siga.getSize()),
rank(siga.getSize()) {
for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i];
}
SignalArray<Time> (SignalBase<Time>& sig)
: SignalArray_const<Time> (0),
array(DEFAULT_SIZE)
{
size=DEFAULT_SIZE;
addElmt(&sig);
}
virtual ~SignalArray_const<Time>() {}
SignalArray<Time> (const SignalArray<Time>& siga)
: SignalArray_const<Time> (siga.getSize()),
array (siga.getSize())
{
rank = siga.getSize ();
for (unsigned int i = 0; i < rank; ++i)
array[i]=&siga[i];
protected:
void addElmt(const SignalBase<Time> *el) {
if (rank >= size) {
size += DEFAULT_SIZE;
const_array.resize(size);
}
const_array[rank++] = el;
}
virtual ~SignalArray<Time> (){}
public:
virtual SignalArray_const<Time> &operator<<(const SignalBase<Time> &sig) {
addElmt(&sig);
return *this;
}
protected:
public:
virtual const SignalBase<Time> &operator[](const unsigned int &idx) const {
return *const_array[idx];
}
virtual unsigned int getSize() const { return rank; }
};
template <class Time>
SignalArray_const<Time> operator<<(const SignalBase<Time> &sig1,
const SignalBase<Time> &sig2) {
SignalArray_const<Time> res(sig1);
res << sig2;
return res;
}
/// \ingroup dgraph
///
/// \brief TODO
template <class Time>
class SignalArray : public SignalArray_const<Time> {
public:
using SignalArray_const<Time>::DEFAULT_SIZE;
using SignalArray_const<Time>::size;
using SignalArray_const<Time>::rank;
protected:
mutable std::vector<SignalBase<Time> *> array;
public:
SignalArray<Time>(const unsigned int &sizeARG = DEFAULT_SIZE)
: SignalArray_const<Time>(0), array(sizeARG) {
size = sizeARG;
}
void addElmt (SignalBase<Time>* el)
{
if (rank >= size)
{
size += DEFAULT_SIZE;
array.resize(size);
}
array[rank++] = el;
}
SignalArray<Time>(SignalBase<Time> &sig)
: SignalArray_const<Time>(0), array(DEFAULT_SIZE) {
size = DEFAULT_SIZE;
addElmt(&sig);
}
public:
virtual SignalArray<Time>& operator<< (SignalBase<Time>& sig)
{
addElmt(&sig);
return *this;
}
SignalArray<Time>(const SignalArray<Time> &siga)
: SignalArray_const<Time>(siga.getSize()), array(siga.getSize()) {
rank = siga.getSize();
for (unsigned int i = 0; i < rank; ++i) array[i] = &siga[i];
}
virtual SignalArray_const<Time>
operator<< (const SignalBase<Time>& sig) const
{
SignalArray_const<Time> res (*this);
res << sig;
return res;
}
virtual ~SignalArray<Time>() {}
virtual SignalBase<Time>& operator[] (const unsigned int& idx) const
{
return *array[idx];
protected:
void addElmt(SignalBase<Time> *el) {
if (rank >= size) {
size += DEFAULT_SIZE;
array.resize(size);
}
};
array[rank++] = el;
}
public:
virtual SignalArray<Time> &operator<<(SignalBase<Time> &sig) {
addElmt(&sig);
return *this;
}
template<class Time>
SignalArray<Time> operator<< (SignalBase<Time>& sig1,
SignalBase<Time>& sig2)
{
SignalArray<Time> res (sig1);
res << sig2;
virtual SignalArray_const<Time> operator<<(
const SignalBase<Time> &sig) const {
SignalArray_const<Time> res(*this);
res << sig;
return res;
}
DYNAMIC_GRAPH_DLLAPI extern SignalArray<int> sotNOSIGNAL;
virtual SignalBase<Time> &operator[](const unsigned int &idx) const {
return *array[idx];
}
};
template <class Time>
SignalArray<Time> operator<<(SignalBase<Time> &sig1, SignalBase<Time> &sig2) {
SignalArray<Time> res(sig1);
res << sig2;
return res;
}
DYNAMIC_GRAPH_DLLAPI extern SignalArray<int> sotNOSIGNAL;
} // end of namespace dynamicgraph.
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_ARRAY_H
#endif //! DYNAMIC_GRAPH_SIGNAL_ARRAY_H
// -*- mode: c++ -*-
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
// LAAS, CNRS
//
#ifndef DYNAMIC_GRAPH_SIGNAL_BASE_H
# define DYNAMIC_GRAPH_SIGNAL_BASE_H
# include <string>
# include <sstream>
# include <typeinfo>
# include <boost/noncopyable.hpp>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/exception-signal.h>
namespace dynamicgraph
{
/** \brief The base class for signals: not to be used as such.
Signal values can be accessed programmatically using the access
() or accessCopy () methods; the former directly accesses the
value of the signal, which can involve an extra computation,
while the latter accesses a cached value, or 'copy'.
*/
template<class Time>
class SignalBase : public boost::noncopyable
{
public:
explicit SignalBase(std::string name = "")
: name (name),
signalTime (0),
ready (false)
{}
virtual ~SignalBase ()
{}
/// \name Time
/// \{
virtual const Time& getTime () const
{
return signalTime;
}
#define DYNAMIC_GRAPH_SIGNAL_BASE_H
#include <dynamic-graph/exception-signal.h>
virtual void setTime (const Time& t)
{
signalTime = t;
}
#include <boost/noncopyable.hpp>
#include <dynamic-graph/fwd.hh>
#include <sstream>
#include <string>
#include <typeinfo>
const bool& getReady () const
{
return ready;
}
namespace dynamicgraph {
const std::string& getName () const
{
return name;
}
/** \brief The base class for signals: not to be used as such.
void getClassName(std::string & aClassName) const
{ aClassName = typeid(this).name(); }
Signal values can be accessed programmatically using the access
() or accessCopy () methods; the former directly accesses the
value of the signal, which can involve an extra computation,
while the latter accesses a cached value, or 'copy'.
*/
template <class Time>
class SignalBase : public boost::noncopyable {
public:
explicit SignalBase(std::string name = "")
: name(name), signalTime(0), ready(false) {}
virtual void setPeriodTime (const Time&)
{}
virtual ~SignalBase() {}
virtual Time getPeriodTime () const
{
return 1;
}
/// \name Time
/// \{
virtual const Time &getTime() const { return signalTime; }
/// \}
virtual void setTime(const Time &t) { signalTime = t; }
/// \name Dependencies
/// \{
const bool &getReady() const { return ready; }
virtual void addDependency (const SignalBase<Time>&)
{}
const std::string &getName() const { return name; }
virtual void removeDependency (const SignalBase<Time>&)
{}
void getClassName(std::string &aClassName) const {
aClassName = typeid(this).name();
}
virtual void clearDependencies ()
{}
virtual void setPeriodTime(const Time &) {}
virtual bool needUpdate (const Time&) const
{
return ready;
}
virtual Time getPeriodTime() const { return 1; }
inline void setReady (const bool sready = true)
{
ready = sready;
}
/// \}
virtual std::ostream&
writeGraph (std::ostream& os ) const
{
return os;
}
/// \name Dependencies
/// \{
virtual std::ostream&
displayDependencies (std::ostream& os,
const int = -1,
std::string space = "",
std::string next1 = "",
std::string = "" ) const
{
os << space << next1 << "-- ";
display(os);
return os;
}
virtual void addDependency(const SignalBase<Time> &) {}
/// \}
/// \name Plug
/// \{
/* Plug the arg-signal on the <this> object. Plug-in is always
* a descending operation (the actual <this> object will call the arg-signal
* and not the opposite).
*/
virtual void plug (SignalBase<Time>* sigarg)
{
DG_THROW ExceptionSignal
(ExceptionSignal::PLUG_IMPOSSIBLE,
"Plug-in operation not possible with this signal. ",
"(while trying to plug %s on %s).",
sigarg->getName ().c_str (),
this->getName ().c_str () );
}
virtual void removeDependency(const SignalBase<Time> &) {}
virtual void unplug ()
{
DG_THROW ExceptionSignal
(ExceptionSignal::PLUG_IMPOSSIBLE,
"Plug-in operation not possible with this signal. ",
"(while trying to unplug %s).",this->getName ().c_str ());
}
virtual void clearDependencies() {}
virtual bool isPlugged () const
{
return false;
}
virtual bool needUpdate(const Time &) const { return ready; }
virtual SignalBase<Time>* getPluged () const
{
return NULL;
}
inline void setReady(const bool sready = true) { ready = sready; }
virtual void setConstantDefault ()
{
DG_THROW ExceptionSignal
(ExceptionSignal::PLUG_IMPOSSIBLE,
"Plug-in operation not possible with this signal. ",
"(while trying to save %s).",
this->getName ().c_str ());
}
virtual std::ostream &writeGraph(std::ostream &os) const { return os; }
/// \}
/// \name Set
/// \{
/* Generic set function. Should be reimplemented by the specific
* Signal. Sets a signal value
*/
virtual void set (std::istringstream&)
{
DG_THROW ExceptionSignal
(ExceptionSignal::SET_IMPOSSIBLE,
"Set operation not possible with this signal. ",
"(while trying to set %s).",
this->getName ().c_str () );
}
virtual std::ostream &displayDependencies(std::ostream &os, const int = -1,
std::string space = "",
std::string next1 = "",
std::string = "") const {
os << space << next1 << "-- ";
display(os);
return os;
}
virtual void get (std::ostream&) const
{
DG_THROW ExceptionSignal
(ExceptionSignal::SET_IMPOSSIBLE,
"Get operation not possible with this signal. ",
"(while trying to get %s).",
this->getName ().c_str ());
}
/// \}
/// \name Plug
/// \{
/* Plug the arg-signal on the <this> object. Plug-in is always
* a descending operation (the actual <this> object will call the arg-signal
* and not the opposite).
*/
virtual void plug(SignalBase<Time> *sigarg) {
DG_THROW ExceptionSignal(
ExceptionSignal::PLUG_IMPOSSIBLE,
"Plug-in operation not possible with this signal. ",
"(while trying to plug %s on %s).", sigarg->getName().c_str(),
this->getName().c_str());
}
virtual inline void recompute (const Time &)
{
DG_THROW ExceptionSignal
(ExceptionSignal::SET_IMPOSSIBLE,
"Recompute operation not possible with this signal. ",
"(while trying to recompute %s).",
this->getName ().c_str ());
}
virtual void unplug() {
DG_THROW ExceptionSignal(
ExceptionSignal::PLUG_IMPOSSIBLE,
"Plug-in operation not possible with this signal. ",
"(while trying to unplug %s).", this->getName().c_str());
}
virtual void trace (std::ostream&) const
{
DG_THROW ExceptionSignal
(ExceptionSignal::SET_IMPOSSIBLE,
"Trace operation not possible with this signal. ",
"(while trying to trace %s).",
this->getName ().c_str () );
}
virtual bool isPlugged() const { return false; }
/// \}
virtual SignalBase<Time> *getPluged() const { return NULL; }
/// \name Display
/// \{
virtual void setConstantDefault() {
DG_THROW ExceptionSignal(
ExceptionSignal::PLUG_IMPOSSIBLE,
"Plug-in operation not possible with this signal. ",
"(while trying to save %s).", this->getName().c_str());
}
virtual std::ostream& display (std::ostream& os) const
{
os << "Sig:" << name;
return os;
}
/// \}
std::string shortName () const
{
std::istringstream iss (name);
const int SIZE = 128;
char buffer[SIZE];
while (iss.good ())
{
iss.getline(buffer,SIZE,':');
}
const std::string res (buffer);
return res;
}
/// \}
/// \name Information providers
/// \{
virtual void ExtractNodeAndLocalNames (std::string& LocalName,
std::string & NodeName) const
{
std::string fullname = this->getName ();
size_t IdxPosLocalName = fullname.rfind (":");
LocalName = fullname.substr (IdxPosLocalName + 1,
fullname.length () - IdxPosLocalName + 1);
size_t IdxPosNodeNameStart = fullname.find ("(");
size_t IdxPosNodeNameEnd = fullname.find (")");
NodeName = fullname.substr (IdxPosNodeNameStart + 1,
IdxPosNodeNameEnd - IdxPosNodeNameStart - 1);
}
/// \name Set
/// \{
/* Generic set function. Should be reimplemented by the specific
* Signal. Sets a signal value
*/
virtual void set(std::istringstream &) {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
"Set operation not possible with this signal. ",
"(while trying to set %s).",
this->getName().c_str());
}
virtual void get(std::ostream &) const {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
"Get operation not possible with this signal. ",
"(while trying to get %s).",
this->getName().c_str());
}
virtual inline void recompute(const Time &) {
DG_THROW ExceptionSignal(
ExceptionSignal::SET_IMPOSSIBLE,
"Recompute operation not possible with this signal. ",
"(while trying to recompute %s).", this->getName().c_str());
}
virtual void trace(std::ostream &) const {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
"Trace operation not possible with this signal. ",
"(while trying to trace %s).",
this->getName().c_str());
}
/// \}
/// \name Display
/// \{
/// \}
/// \name Test
/// \{
virtual void checkCompatibility ()
{
DG_THROW ExceptionSignal
(ExceptionSignal::PLUG_IMPOSSIBLE,
"Abstract signal not compatible with anything.",
"(while trying to plug <%s>).",
this->getName ().c_str ());
virtual std::ostream &display(std::ostream &os) const {
os << "Sig:" << name;
return os;
}
std::string shortName() const {
std::istringstream iss(name);
const int SIZE = 128;
char buffer[SIZE];
while (iss.good()) {
iss.getline(buffer, SIZE, ':');
}
/// \}
protected:
std::string name;
Time signalTime;
bool ready;
};
/// Forward to a virtual fonction.
template<class Time>
std::ostream& operator<< (std::ostream& os, const SignalBase<Time>& sig)
{
return sig.display(os);
const std::string res(buffer);
return res;
}
/// \}
/// \name Information providers
/// \{
virtual void ExtractNodeAndLocalNames(std::string &LocalName,
std::string &NodeName) const {
std::string fullname = this->getName();
size_t IdxPosLocalName = fullname.rfind(":");
LocalName = fullname.substr(IdxPosLocalName + 1,
fullname.length() - IdxPosLocalName + 1);
size_t IdxPosNodeNameStart = fullname.find("(");
size_t IdxPosNodeNameEnd = fullname.find(")");
NodeName = fullname.substr(IdxPosNodeNameStart + 1,
IdxPosNodeNameEnd - IdxPosNodeNameStart - 1);
}
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_BASE_H
/// \}
/// \name Test
/// \{
virtual void checkCompatibility() {
DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE,
"Abstract signal not compatible with anything.",
"(while trying to plug <%s>).",
this->getName().c_str());
}
/// \}
protected:
std::string name;
Time signalTime;
bool ready;
};
/// Forward to a virtual fonction.
template <class Time>
std::ostream &operator<<(std::ostream &os, const SignalBase<Time> &sig) {
return sig.display(os);
}
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_BASE_H
// -*- c++-mode -*-
// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse, Nicolas Mansard
// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse,
// Nicolas Mansard
//
#ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
# define DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
# include <map>
# include <typeinfo>
# include <vector>
# include <boost/any.hpp>
# include <boost/format.hpp>
# include <boost/function/function1.hpp>
# include <boost/function/function2.hpp>
# include <boost/lexical_cast.hpp>
# include <boost/tuple/tuple.hpp>
#include <dynamic-graph/eigen-io.h>
# include <dynamic-graph/dynamic-graph-api.h>
# include "dynamic-graph/exception-signal.h"
# include "dynamic-graph/signal-caster.h"
namespace dynamicgraph
{
/* --- NON GENERIC CASTER ------------------------------------------------- */
/// This class can be used to register default casts, i.e. casts
/// already supported by the object to an std::iostream through the
/// operators >> and << .
template<typename T>
class DefaultCastRegisterer : public SignalCastRegisterer
{
public:
DefaultCastRegisterer ()
: SignalCastRegisterer (typeid(T), disp, cast, trace)
{}
static boost::any cast (std::istringstream& iss);
static void disp (const boost::any& object, std::ostream& os)
{
os << boost::any_cast<T> (object) << std::endl;
}
static void trace (const boost::any& object, std::ostream& os)
{
disp(object,os);
}
};
/// A default version of the caster, to serialize directly from
/// std::in.
template <typename T>
boost::any
DefaultCastRegisterer<T>::cast (std::istringstream& iss)
{
T inst;
iss >> inst;
if (iss.fail ())
{
boost::format fmt ("failed to serialize %s ");
fmt % iss.str ();
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str ());
}
return inst;
}
/* --- GENERIC CASTER ----------------------------------------------------- */
/*!
* This class is only used to group together static functions who differ by
* a template parameter. It is never actually instanced (the private constructor
* makes sure of that).
* Typical use of this class is to add the caster in the dg graph:
* dynamicgraph::SignalCastRegisterer sotCastRegisterer_TYPE
* (typeid(TYPE),
* SignalCast<TYPE>::disp_,
* SignalCast<TYPE>::cast_,
* SignalCast<TYPE>::trace_);
* NMSD: I don't really understand the use of this additional class. IMHO
* (comme on dit), it should be possible to rewrite the same-spec macros
* using specialization of the template class DefaultCastRegisterer. No?
*/
template< class T >
class SignalCast
{
public:
static T cast( std::istringstream& ) { throw 1;}
static void disp( const T&,std::ostream&) { throw 1; }
static void trace( const T& t,std::ostream& os ) { disp(t,os); }
public:
// adapter functions for SignalCast
static boost::any cast_( std::istringstream& stringValue ) {
return boost::any_cast<T>(cast(stringValue));
}
static void disp_( const boost::any& t,std::ostream& os ) {
disp(boost::any_cast<T>(t), os);
}
static void trace_( const boost::any& t,std::ostream& os ) {
trace(boost::any_cast<T>(t),os);
}
private:
SignalCast() {}
};
} // namespace dynamicgraph
/* -------------------------------------------------------------------------- */
/* --- MACROS --------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Declaration macro: one instance of each class needs to be present in
* order for casts to be registered.
*/
#define DG_SIGNAL_CAST_DECLARATION(TYPE) \
::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##TYPE \
(typeid(TYPE), \
SignalCast<TYPE>::disp_, \
SignalCast<TYPE>::cast_, \
SignalCast<TYPE>::trace_)
#define DG_SIGNAL_CAST_DECLARATION_NAMED(TYPE,NAME) \
::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##NAME \
(typeid(TYPE), \
SignalCast<TYPE>::disp_, \
SignalCast<TYPE>::cast_, \
SignalCast<TYPE>::trace_)
/* Standard definition macros: the three functions can be specified
* in the macros. To define then in the cpp, just put ';' in the args.
*/
#define DG_SIGNAL_CAST_FULL_DEFINITION(TYPE,CAST,DISP,TRACE) \
template<> \
class SignalCast<TYPE> \
{ \
public: \
static TYPE cast( std::istringstream& iss ) CAST \
static void disp( TYPE const& t,std::ostream& os ) DISP \
static void trace( TYPE const& t,std::ostream& os ) TRACE \
public: \
static boost::any cast_( std::istringstream& stringValue ) { \
return boost::any_cast<TYPE>(cast(stringValue)); \
} \
static void disp_( const boost::any& t,std::ostream& os ) { \
disp(boost::any_cast<TYPE>(t), os); \
} \
static void trace_( const boost::any& t,std::ostream& os ) { \
trace(boost::any_cast<TYPE>(t),os); \
} \
}
/* Standard definition macros: the functions <cast> and <disp> have
* to be implemented in the cpp files. The function <trace> is
* implemented as a proxy on <disp>.
*/
#define DG_SIGNAL_CAST_DEFINITION_HPP(TYPE) \
DG_SIGNAL_CAST_FULL_DEFINITION(TYPE,;,;,{ disp(t,os); })
/* Lazy definition: <cast> and <disp> are to proxys on the standard
* std input (>>) and output (<<). The function <trace> has to be
* implemented in the cpp.
*/
#define DG_SIGNAL_CAST_DEFINITION_TRACE_HPP(TYPE,TRACE) \
DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
{TYPE res; iss >> res; return res; }, \
{ os << t <<std::endl; }, \
TRACE )
/* Lazy lazy definition: the three functions are implemented as
* proxys on std::io operation.
*/
#define DG_SIGNAL_CAST_DEFINITION(TYPE) \
DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
{TYPE res; iss >> res; return res; }, \
{ os << t <<std::endl; }, \
{ disp(t,os); })
/* Lazy definition of <cast> and <disp> with implementation of
* <trace> in the cpp.
*/
#define DG_SIGNAL_CAST_DEFINITION_TRACE(TYPE) \
DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \
{TYPE res; iss >> res; return res; }, \
{ os << t <<std::endl; }, \
;)
/* Macro to add the define SignalCast in the dg graph. Typical use is:
* DG_ADD_CASTER( Matrix,matrix )
*/
#define DG_ADD_CASTER(TYPE,ID) \
::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##ID \
(typeid(TYPE), \
SignalCast<TYPE>::disp_, \
SignalCast<TYPE>::cast_, \
SignalCast<TYPE>::trace_)
#define DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
#pragma warning "This file is now useless"
#endif // #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
......@@ -3,127 +3,143 @@
//
#ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HH
# define DYNAMIC_GRAPH_SIGNAL_CASTER_HH
# include <map>
# include <typeinfo>
# include <vector>
# include <boost/any.hpp>
# include <boost/format.hpp>
# include <boost/function/function1.hpp>
# include <boost/function/function2.hpp>
# include <boost/lexical_cast.hpp>
# include <boost/tuple/tuple.hpp>
# include <dynamic-graph/dynamic-graph-api.h>
# include "dynamic-graph/exception-signal.h"
namespace dynamicgraph
{
/// This singleton class allows serialization of a number of objects into
/// (disp) and from (cast) std i/o streams.
///
/// The transformation is done at run-time, i.e. SignalCaster
/// doesn't know about the type of objects it casts to.
///
/// It also allows registering of user-defined casts. A cast is
/// identified by the compiler. The mapping from a type to a
/// serialization function is dynamic, hence it is more complex than
/// a typical template-based compile-time resolve. So disp, cast and
/// trace are costly functions and should be used as such.
class DYNAMIC_GRAPH_DLLAPI SignalCaster
{
public:
virtual ~SignalCaster ();
/// Destroy the unique instance.
static void destroy();
/// Typedef of displayer functions that take an encapsulated 'any'
/// object and displays, cast, or trace it on an output stream
/// (serialization).
typedef boost::function2<void, const boost::any&, std::ostream&>
displayer_type;
typedef boost::function1<boost::any, std::istringstream&> caster_type;
typedef boost::function2<void, const boost::any&, std::ostream&>
tracer_type;
/// Get a reference to the unique object of the class.
static SignalCaster* getInstance(void);
/// Displays an object using a registered displayer function.
void disp (const boost::any& object, std::ostream& os);
/// Traces an object using a registered trace function.
void trace (const boost::any& object, std::ostream& os);
/// Casts an object using a registered cast function.
boost::any cast (const std::type_info&, std::istringstream& iss);
/// Registers a cast.
void registerCast (const std::type_info& type, displayer_type displayer,
caster_type caster, tracer_type tracer);
/// Unregister a cast.
void unregisterCast (const std::type_info& type);
/// Checks if there is a displayer registered with type_name.
bool existsCast (const std::type_info& type) const;
/// Return the list of type names registered.
std::vector<std::string> listTypenames () const;
private:
/// Container for the three cast functions.
typedef boost::tuple<displayer_type, caster_type, tracer_type>
cast_functions_type;
/// \brief Retrieve cast structure from its name.
cast_functions_type& getCast (const std::string& type_name);
/// This map associates the typename of objects and the corresponding
/// using boost::function with 'compatible' syntax
std::map<std::string, cast_functions_type> functions_;
std::map<std::string, const std::type_info*> type_info_;
private:
explicit SignalCaster ();
/// Pointer to the unique instance of the class.
static SignalCaster* instance_;
};
///The SignalCast registerer class. Can be used to automatically
/// register a cast when instanced somewhere in a cpp file. Pass the
/// typeid () of the type you want to register a cast to as the first
/// argument. The code is provided here so the class does not need
/// to be exported.
class DYNAMIC_GRAPH_DLLAPI SignalCastRegisterer
{
public:
inline SignalCastRegisterer (const std::type_info& type,
SignalCaster::displayer_type displayer,
SignalCaster::caster_type caster,
SignalCaster::tracer_type tracer)
{
SignalCaster::getInstance()->registerCast(type, displayer,
caster, tracer);
#define DYNAMIC_GRAPH_SIGNAL_CASTER_HH
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/eigen-io.h>
#include <dynamic-graph/linear-algebra.h>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <map>
#include <vector>
#include "dynamic-graph/exception-signal.h"
namespace dynamicgraph {
/// Inherit from this class if you want to keep default implementation for some
/// functions.
template <typename T>
struct signal_io_base {
/// serialize a signal value.
inline static void disp(const T &value, std::ostream &os) { os << value; }
/// deserialize a signal value.
inline static T cast(std::istringstream &is) {
T inst;
is >> inst;
if (is.fail()) {
throw ExceptionSignal(ExceptionSignal::GENERIC,
"failed to serialize " + is.str());
}
};
return inst;
}
/// write a signal value to log file
inline static void trace(const T &value, std::ostream &os) { os << value; }
};
/// Inherit from this class if tracing is not implemented for a given type.
template <typename T>
struct signal_io_unimplemented {
inline static void disp(const T &, std::ostream &) {
throw std::logic_error("this disp is not implemented.");
}
inline static T cast(std::istringstream &) {
throw std::logic_error("this cast is not implemented.");
}
inline static void trace(const T &, std::ostream &) {
throw std::logic_error("this trace is not implemented.");
}
};
/// Class used for I/O operations in Signal<T,Time>
template <typename T>
struct signal_io : signal_io_base<T> {};
/// Template specialization of signal_disp for Eigen objects
template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
int _MaxCols>
struct signal_io<
Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>>
: signal_io_base<
Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> {
typedef Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
matrix_type;
inline static void disp(const matrix_type &value, std::ostream &os) {
static const Eigen::IOFormat row_format(
Eigen::StreamPrecision, Eigen::DontAlignCols, " ", " ", "", "", "", "");
os << value.format(row_format);
}
inline static void trace(const matrix_type &value, std::ostream &os) {
static const Eigen::IOFormat row_format(Eigen::StreamPrecision,
Eigen::DontAlignCols, "\t", "\t",
"", "", "", "");
os << value.format(row_format);
}
};
/// Global signal cast template (helper) functions
///
/// Using these avoid using the typeid () operator and keeps the
/// implementation details hidden.
template<typename T>
void signal_disp (const T& value, std::ostream& os)
{
SignalCaster::getInstance()->disp(value, os);
/// Template specialization of signal_io for Eigen quaternion objects
template <typename _Scalar, int _Options>
struct signal_io<Eigen::Quaternion<_Scalar, _Options>>
: signal_io_base<Eigen::Quaternion<_Scalar, _Options>> {
typedef Eigen::Quaternion<_Scalar, _Options> quat_type;
typedef Eigen::Matrix<_Scalar, 4, 1, _Options> matrix_type;
inline static void disp(const quat_type &value, std::ostream &os) {
signal_io<matrix_type>::disp(value.coeffs(), os);
}
template<typename T>
T signal_cast(std::istringstream& iss)
{
return boost::any_cast<T>(SignalCaster::getInstance()->cast(typeid(T),
iss));
inline static quat_type cast(std::istringstream &is) {
return quat_type(signal_io<matrix_type>::cast(is));
}
template<typename T>
void signal_trace (const T& value, std::ostream& os)
{
SignalCaster::getInstance()->trace(value, os);
inline static void trace(const quat_type &value, std::ostream &os) {
signal_io<matrix_type>::trace(value.coeffs(), os);
}
} // end of namespace dynamicgraph.
};
/// Template specialization of signal_io for std::string.
/// Do not print '\n' at the end.
template <>
struct signal_io<std::string> : signal_io_base<std::string> {
inline static std::string cast(std::istringstream &iss) { return iss.str(); }
};
/// Template specialization of signal_io for double
/// to workaround the limitations of the stream based approach.
///
/// When dealing with double: displaying a double on a stream
/// is *NOT* the opposite of reading a double from a stream.
///
/// In practice, it means that there is no way to read
/// a NaN, +inf, -inf from a stream!
///
/// To workaround this problem, parse special values manually
/// (the strings used are the one produces by displaying special
/// values on a stream).
template <>
struct signal_io<double> : signal_io_base<double> {
inline static double cast(std::istringstream &iss) {
std::string tmp(iss.str());
if (tmp == "nan")
return std::numeric_limits<double>::quiet_NaN();
else if (tmp == "inf" || tmp == "+inf")
return std::numeric_limits<double>::infinity();
else if (tmp == "-inf")
return -1. * std::numeric_limits<double>::infinity();
try {
return boost::lexical_cast<double>(tmp);
} catch (boost::bad_lexical_cast &) {
boost::format fmt("failed to serialize %s (to double)");
fmt % tmp;
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
}
}
};
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_CASTER_HH
#endif //! DYNAMIC_GRAPH_SIGNAL_CASTER_HH
......@@ -12,62 +12,71 @@
/* dg signals */
#include <dynamic-graph/entity.h>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/signal-ptr.h>
#include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/linear-algebra.h>
/* --- MACROS ---------------------------------------------------------- */
#define SIGNAL_OUT_FUNCTION_NAME(name) name##SOUT_function
#define DECLARE_SIGNAL( name,IO,type ) ::dynamicgraph::Signal<type,int> m_##name##S##IO
#define CONSTRUCT_SIGNAL( name,IO,type ) m_##name##S##IO( getClassName()+"("+getName()+")::"+#IO+"put("+#type+")::"+#name )
#define BIND_SIGNAL_TO_FUNCTION(name,IO,type) m_##name##S##IO.setFunction(boost::bind(&EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name),this,_1,_2));
#define DECLARE_SIGNAL(name, IO, type) \
::dynamicgraph::Signal<type, int> m_##name##S##IO
#define CONSTRUCT_SIGNAL(name, IO, type) \
m_##name##S##IO(getClassName() + "(" + getName() + ")::" + #IO + "put(" + \
#type + ")::" + #name)
#define BIND_SIGNAL_TO_FUNCTION(name, IO, type) \
m_##name##S##IO.setFunction(boost::bind( \
&EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name), this, _1, _2));
/**/
#define DECLARE_SIGNAL_IN( name,type ) ::dynamicgraph::SignalPtr<type,int> m_##name##SIN
#define CONSTRUCT_SIGNAL_IN( name,type ) m_##name##SIN( NULL,getClassName()+"("+getName()+")::input("+#type+")::"+#name )
#define DECLARE_SIGNAL_IN(name, type) \
::dynamicgraph::SignalPtr<type, int> m_##name##SIN
#define CONSTRUCT_SIGNAL_IN(name, type) \
m_##name##SIN(NULL, getClassName() + "(" + getName() + ")::input(" + #type + \
")::" + #name)
/**/
#define DECLARE_SIGNAL_OUT_FUNCTION(name,type) \
type& SIGNAL_OUT_FUNCTION_NAME(name)(type&,int)
#define DEFINE_SIGNAL_OUT_FUNCTION(name,type) \
type& EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name)(type& s,int iter)
#define DECLARE_SIGNAL_OUT_FUNCTION(name, type) \
type &SIGNAL_OUT_FUNCTION_NAME(name)(type &, int)
#define SIGNAL_OUT_FUNCTION( name ) name##SOUT_function
#define DEFINE_SIGNAL_OUT_FUNCTION(name, type) \
type &EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name)(type & s, int iter)
#define DECLARE_SIGNAL_OUT( name,type ) \
public: \
::dynamicgraph::SignalTimeDependent<type,int> m_##name##SOUT; \
protected: \
type& SIGNAL_OUT_FUNCTION(name)( type&,int )
#define CONSTRUCT_SIGNAL_OUT( name,type,dep ) \
m_##name##SOUT( boost::bind(& EntityClassName::name##SOUT_function,this,_1,_2), \
dep,getClassName()+"("+getName()+")::output("+#type+")::"+#name )
#define SIGNAL_OUT_FUNCTION(name) name##SOUT_function
#define DECLARE_SIGNAL_OUT(name, type) \
public: \
::dynamicgraph::SignalTimeDependent<type, int> m_##name##SOUT; \
\
protected: \
type &SIGNAL_OUT_FUNCTION(name)(type &, int)
#define CONSTRUCT_SIGNAL_OUT(name, type, dep) \
m_##name##SOUT( \
boost::bind(&EntityClassName::name##SOUT_function, this, _1, _2), dep, \
getClassName() + "(" + getName() + ")::output(" + #type + ")::" + #name)
/**************** INNER SIGNALS *******************/
#define SIGNAL_INNER_FUNCTION_NAME(name) name##SINNER_function
#define DECLARE_SIGNAL_INNER_FUNCTION(name,type) \
type& SIGNAL_INNER_FUNCTION_NAME(name)(type&,int)
#define DEFINE_SIGNAL_INNER_FUNCTION(name,type) \
type& EntityClassName::SIGNAL_INNER_FUNCTION_NAME(name)(type& s,int iter)
#define DECLARE_SIGNAL_INNER_FUNCTION(name, type) \
type &SIGNAL_INNER_FUNCTION_NAME(name)(type &, int)
#define DECLARE_SIGNAL_INNER(name,type) \
public: \
::dynamicgraph::SignalTimeDependent<type,int> m_##name##SINNER;\
protected: \
DECLARE_SIGNAL_INNER_FUNCTION(name,type)
#define DEFINE_SIGNAL_INNER_FUNCTION(name, type) \
type &EntityClassName::SIGNAL_INNER_FUNCTION_NAME(name)(type & s, int iter)
#define CONSTRUCT_SIGNAL_INNER( name,type,dep ) \
m_##name##SINNER( boost::bind(&EntityClassName::name##SINNER_function,this,_1,_2), \
dep,getClassName()+"("+getName()+")::inner("+#type+")::"+#name )
#define DECLARE_SIGNAL_INNER(name, type) \
public: \
::dynamicgraph::SignalTimeDependent<type, int> m_##name##SINNER; \
\
protected: \
DECLARE_SIGNAL_INNER_FUNCTION(name, type)
#define CONSTRUCT_SIGNAL_INNER(name, type, dep) \
m_##name##SINNER( \
boost::bind(&EntityClassName::name##SINNER_function, this, _1, _2), dep, \
getClassName() + "(" + getName() + ")::inner(" + #type + ")::" + #name)
#endif // __dynamic_graph_signal_helper_H__
#endif // __dynamic_graph_signal_helper_H__
......@@ -6,137 +6,138 @@
#ifndef DYNAMIC_GRAPH_SIGNAL_PTR_H
#define DYNAMIC_GRAPH_SIGNAL_PTR_H
# include <dynamic-graph/exception-signal.h>
# include <dynamic-graph/signal.h>
# include <dynamic-graph/deprecated.hh>
namespace dynamicgraph
{
/// \ingroup dgraph
///
/// \brief This is the only type of signal that can be plugged to,
/// using the plug () command.
///
/// In that sense, when plugged into, it acts as a "pointer" to the
/// input signal, hence the name. Operator -> is also overloaded and
/// can be used to access the pointed signal.
template<class T, class Time>
class SignalPtr : public virtual Signal<T,Time>
{
public:
using SignalBase<Time>::getName;
protected:
Signal<T,Time>* signalPtr;
bool modeNoThrow;
bool transmitAbstract;
SignalBase<Time> * abstractTransmitter;
T* transmitAbstractData;
inline bool autoref () const
{
return signalPtr == this;
}
public: /* --- CONSTRUCTORS --- */
SignalPtr (Signal<T,Time>* ptr, std::string name="")
: Signal<T,Time> (name),
signalPtr (ptr),
modeNoThrow (false),
transmitAbstract (false),
abstractTransmitter (NULL)
{}
virtual ~SignalPtr ()
{
signalPtr = NULL;
}
public: /* --- PLUG-IN OPERATION --- */
Signal<T,Time>* getPtr (); // throw
const Signal<T,Time>* getPtr () const; // throw
SignalBase<Time>* getAbstractPtr (); // throw
const SignalBase<Time>* getAbstractPtr () const; // throw
virtual void plug( SignalBase<Time>* ref );
virtual void unplug () { plug(NULL); }
virtual bool isPluged () const DYNAMIC_GRAPH_DEPRECATED {
return isPlugged ();
}
virtual bool isPlugged () const { return (NULL!=signalPtr); }
virtual SignalBase<Time>* getPluged () const { return signalPtr; }
virtual bool isAbstractPluged () const;
virtual const Time& getTime () const;
/* Equivalent operator-like definitions. */
inline Signal<T,Time>* operator-> () { return getPtr (); }
inline const Signal<T,Time>* operator-> () const { return getPtr (); }
inline Signal<T,Time>& operator* () { return *getPtr (); }
inline const Signal<T,Time>& operator* () const { return *getPtr (); }
inline operator bool () const { return isPlugged (); }
public: /* --- INHERITANCE --- */
virtual bool needUpdate( const Time& t ) const ;
virtual std::ostream& writeGraph(std::ostream& os) const;
virtual std::ostream& display( std::ostream& os ) const;
/* For compatibility, .access () is equivalent to ->access (). For explicit
* pointer dereference :
* Prefere -> () to ()
*/
virtual const T& operator ()( const Time & t );
/* Similarly, Prefere ->access to .access
*/
virtual const T& access( const Time & t );
virtual const T& accessCopy () const;
inline void setConstantDefault( const T& t )
{ Signal<T,Time>::setConstant(t); modeNoThrow = true; }
virtual inline void setConstantDefault ()
{ setConstantDefault( accessCopy () ); }
inline void unsetConstantDefault (){ modeNoThrow = false; }
virtual void checkCompatibility();
public: /* --- INHERITANCE --- */
/* SignalPtr could be used as a classical signal, through the normal
* setting functions. The behavior is to plugged the signalPtr on
* the classical mother Signal layer of the object.
*/
virtual void setConstant( const T& t )
{ plug(this); Signal<T,Time>::setConstant(t); }
virtual void setReference( const T* t,typename Signal<T,Time>::Mutex *m=NULL )
{ plug(this); Signal<T,Time>::setReference(t,m); }
virtual void setFunction( boost::function2<T&,T&,Time> t,typename Signal<T,Time>::Mutex *m=NULL )
{ plug(this); Signal<T,Time>::setFunction(t,m); }
/* template< class Provider > */
/* void setFunction( T& (Provider::*fun)(Time,T&),Provider& obj, */
/* boost::try_mutex *mutexref=NULL ) */
/* { plug(this); Signal<T,Time>::setFunction(fun,obj,mutexref); } */
virtual inline Signal<T,Time>& operator= ( const T& t )
{ setConstant( t ); return *this; }
virtual std::ostream& displayDependencies( std::ostream& os,const int depth=-1,
std::string space="",
std::string next1="",
std::string next2="" ) const;
protected: // Interdiction of the rest of the heritage
virtual void addDependency () {}
virtual void removeDependency () {}
virtual void clearDependencies () {}
};
} // end of namespace dynamicgraph
# include <dynamic-graph/signal-ptr.t.cpp>
#endif //! DYNAMIC_GRAPH_SIGNAL_PTR_H
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/signal.h>
namespace dynamicgraph {
/// \ingroup dgraph
///
/// \brief This is the only type of signal that can be plugged to,
/// using the plug () command.
///
/// In that sense, when plugged into, it acts as a "pointer" to the
/// input signal, hence the name. Operator -> is also overloaded and
/// can be used to access the pointed signal.
///
/// If the signal provided as a parameter of the plug operation
/// cannot be casted in type T, but is compatible then the class
/// holds a reference to an abstract object.
///
template <class T, class Time>
class SignalPtr : public virtual Signal<T, Time> {
public:
using SignalBase<Time>::getName;
protected:
Signal<T, Time> *signalPtr;
bool modeNoThrow;
bool transmitAbstract;
SignalBase<Time> *abstractTransmitter;
T *transmitAbstractData;
inline bool autoref() const { return signalPtr == this; }
public: /* --- CONSTRUCTORS --- */
SignalPtr(Signal<T, Time> *ptr, std::string name = "")
: Signal<T, Time>(name),
signalPtr(ptr),
modeNoThrow(false),
transmitAbstract(false),
abstractTransmitter(NULL) {}
virtual ~SignalPtr() { signalPtr = NULL; }
public:
/* --- PLUG-IN OPERATION --- */
Signal<T, Time> *getPtr(); // throw
const Signal<T, Time> *getPtr() const; // throw
SignalBase<Time> *getAbstractPtr(); // throw
const SignalBase<Time> *getAbstractPtr() const; // throw
virtual void plug(SignalBase<Time> *ref);
virtual void unplug() { plug(NULL); }
virtual bool isPlugged() const { return (NULL != signalPtr); }
virtual SignalBase<Time> *getPluged() const { return signalPtr; }
virtual bool isAbstractPluged() const;
virtual const Time &getTime() const;
/* Equivalent operator-like definitions. */
inline Signal<T, Time> *operator->() { return getPtr(); }
inline const Signal<T, Time> *operator->() const { return getPtr(); }
inline Signal<T, Time> &operator*() { return *getPtr(); }
inline const Signal<T, Time> &operator*() const { return *getPtr(); }
inline operator bool() const { return isPlugged(); }
public: /* --- INHERITANCE --- */
virtual bool needUpdate(const Time &t) const;
virtual std::ostream &writeGraph(std::ostream &os) const;
virtual std::ostream &display(std::ostream &os) const;
/* For compatibility, .access () is equivalent to ->access (). For explicit
* pointer dereference :
* Prefere -> () to ()
*/
virtual const T &operator()(const Time &t);
/* Similarly, Prefere ->access to .access
*/
virtual const T &access(const Time &t);
virtual const T &accessCopy() const;
inline void setConstantDefault(const T &t) {
Signal<T, Time>::setConstant(t);
modeNoThrow = true;
}
virtual inline void setConstantDefault() { setConstantDefault(accessCopy()); }
inline void unsetConstantDefault() { modeNoThrow = false; }
virtual void checkCompatibility();
public: /* --- INHERITANCE --- */
/* SignalPtr could be used as a classical signal, through the normal
* setting functions. The behavior is to plugged the signalPtr on
* the classical mother Signal layer of the object.
*/
virtual void setConstant(const T &t) {
plug(this);
Signal<T, Time>::setConstant(t);
}
virtual void setReference(const T *t,
typename Signal<T, Time>::Mutex *m = NULL) {
plug(this);
Signal<T, Time>::setReference(t, m);
}
virtual void setFunction(boost::function2<T &, T &, Time> t,
typename Signal<T, Time>::Mutex *m = NULL) {
plug(this);
Signal<T, Time>::setFunction(t, m);
}
/* template< class Provider > */
/* void setFunction( T& (Provider::*fun)(Time,T&),Provider& obj, */
/* boost::try_mutex *mutexref=NULL ) */
/* { plug(this); Signal<T,Time>::setFunction(fun,obj,mutexref); } */
virtual inline Signal<T, Time> &operator=(const T &t) {
setConstant(t);
return *this;
}
virtual std::ostream &displayDependencies(std::ostream &os,
const int depth = -1,
std::string space = "",
std::string next1 = "",
std::string next2 = "") const;
protected: // Interdiction of the rest of the heritage
using Signal<T, Time>::addDependency;
virtual void addDependency() {}
using Signal<T, Time>::removeDependency;
virtual void removeDependency() {}
virtual void clearDependencies() {}
};
} // end of namespace dynamicgraph
#include <dynamic-graph/signal-ptr.t.cpp>
#endif //! DYNAMIC_GRAPH_SIGNAL_PTR_H
......@@ -4,260 +4,226 @@
//
#ifndef DYNAMIC_GRAPH_SIGNAL_PTR_T_CPP
# define DYNAMIC_GRAPH_SIGNAL_PTR_T_CPP
# include <dynamic-graph/signal-ptr.h>
# undef VP_TEMPLATE_DEBUG_MODE
# define VP_TEMPLATE_DEBUG_MODE 0
# include <dynamic-graph/debug.h>
namespace dynamicgraph
{
template< class T,class Time >
bool SignalPtr<T,Time>::
isAbstractPluged () const
{
return ( (NULL!=signalPtr)||(abstractTransmitter) );
#define DYNAMIC_GRAPH_SIGNAL_PTR_T_CPP
#include <dynamic-graph/signal-ptr.h>
#undef VP_TEMPLATE_DEBUG_MODE
#define VP_TEMPLATE_DEBUG_MODE 0
#include <dynamic-graph/debug.h>
namespace dynamicgraph {
template <class T, class Time>
bool SignalPtr<T, Time>::isAbstractPluged() const {
return ((NULL != signalPtr) || (abstractTransmitter));
}
template <class T, class Time>
Signal<T, Time> *SignalPtr<T, Time>::getPtr() {
dgTDEBUGIN(25);
if (!isPlugged()) DG_THROW
ExceptionSignal(ExceptionSignal::NOT_INITIALIZED,
"In SignalPtr: SIN ptr not set.", " (in signal <%s>)",
getName().c_str());
dgTDEBUGOUT(25);
return signalPtr;
}
template <class T, class Time>
const Signal<T, Time> *SignalPtr<T, Time>::getPtr() const {
dgTDEBUGIN(25) << SignalBase<Time>::name << "(" << isPlugged() << ")" << this
<< "->" << signalPtr << std::endl;
dgTDEBUGIN(25);
if (!isPlugged()) {
DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED,
"In SignalPtr: SIN ptr not set.",
" (in signal <%s>)", getName().c_str());
}
template< class T,class Time >
Signal<T,Time>* SignalPtr<T,Time>::
getPtr ()
{
dgTDEBUGIN(25);
if(! isPlugged () )
DG_THROW ExceptionSignal( ExceptionSignal::NOT_INITIALIZED,
"In SignalPtr: SIN ptr not set.",
" (in signal <%s>)",getName ().c_str ());
dgTDEBUGOUT(25);
return signalPtr;
dgTDEBUGOUT(25);
return signalPtr;
}
template <class T, class Time>
SignalBase<Time> *SignalPtr<T, Time>::getAbstractPtr() {
if (!isAbstractPluged()) {
DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED,
"In SignalPtr: SIN ptr not set.",
" (in signal <%s>)", getName().c_str());
}
template< class T,class Time >
const Signal<T,Time>* SignalPtr<T,Time>::
getPtr () const
{
dgTDEBUGIN(25) << SignalBase<Time>::name <<"("<< isPlugged () <<")"
<< this << "->"<<signalPtr <<std::endl;
dgTDEBUGIN(25);
if(! isPlugged () )
{ DG_THROW ExceptionSignal( ExceptionSignal::NOT_INITIALIZED,
"In SignalPtr: SIN ptr not set.",
" (in signal <%s>)",getName ().c_str ()); }
dgTDEBUGOUT(25);
if (NULL != signalPtr)
return signalPtr;
else
return abstractTransmitter;
}
template <class T, class Time>
const SignalBase<Time> *SignalPtr<T, Time>::getAbstractPtr() const {
if (!isAbstractPluged()) {
DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED,
"In SignalPtr: SIN ptr not set.",
" (in signal <%s>)", getName().c_str());
}
template< class T,class Time >
SignalBase<Time>* SignalPtr<T,Time>::
getAbstractPtr ()
{
if(! isAbstractPluged () )
{ DG_THROW ExceptionSignal( ExceptionSignal::NOT_INITIALIZED,
"In SignalPtr: SIN ptr not set.",
" (in signal <%s>)",getName ().c_str ()); }
if( NULL!=signalPtr ) return signalPtr;
else return abstractTransmitter;
}
template< class T,class Time >
const SignalBase<Time>* SignalPtr<T,Time>::
getAbstractPtr () const
{
if(! isAbstractPluged () )
{ DG_THROW ExceptionSignal( ExceptionSignal::NOT_INITIALIZED,
"In SignalPtr: SIN ptr not set.",
" (in signal <%s>)",getName ().c_str ()); }
if( NULL!=signalPtr ) return signalPtr;
else return abstractTransmitter;
}
template< class T,class Time >
void SignalPtr<T,Time>::
plug( SignalBase<Time>* unknown_ref )
{
dgTDEBUGIN(5);
if(! unknown_ref )
{
signalPtr = NULL;
transmitAbstract = false;
dgTDEBUGOUT(5);
return;
}
dgTDEBUG(5) << "# In T = "<< getName () <<" ="
<<typeid( Signal<T,Time>::Tcopy1 ) .name () << "{ "<<std::endl;
Signal<T,Time> * ref = dynamic_cast< Signal<T,Time>* > (unknown_ref);
if( NULL==ref )
{
try {
unknown_ref->checkCompatibility ();
}
catch( T* t )
{
dgTDEBUG(25) << "Cast THROW ok."<< std::endl;
Signal<T,Time>::setReference( t );
transmitAbstract = true; abstractTransmitter = unknown_ref;
transmitAbstractData = t;
}
catch(...)
{
dgTDEBUG(25) << "Fatal error."<< std::endl;
transmitAbstract = false;
DG_THROW ExceptionSignal( ExceptionSignal::PLUG_IMPOSSIBLE,
"Compl. Uncompatible types for plugin.",
"(while trying to plug <%s> on <%s>)"
" with types <%s> on <%s>.",
unknown_ref->getName ().c_str (),
this->getName ().c_str (),
typeid(T).name(),
typeid(unknown_ref).name());
}
}
else
{
dgTDEBUG(25) << "Cast ok."<< std::endl;
transmitAbstract = false;
signalPtr = ref;
}
if (NULL != signalPtr)
return signalPtr;
else
return abstractTransmitter;
}
template <class T, class Time>
void SignalPtr<T, Time>::plug(SignalBase<Time> *unknown_ref) {
dgTDEBUGIN(5);
if (!unknown_ref) {
signalPtr = NULL;
transmitAbstract = false;
dgTDEBUGOUT(5);
return;
}
template< class T,class Time >
void SignalPtr<T,Time>::
checkCompatibility ()
{
if( isPlugged()&&(!autoref ()) )
{ getPtr()->checkCompatibility(); }
else if( isAbstractPluged()&&(!autoref ()) )
{ abstractTransmitter->checkCompatibility(); }
else Signal<T,Time>::checkCompatibility();
dgTDEBUG(5) << "# In T = " << getName() << " ="
<< typeid(Signal<T, Time>::Tcopy1).name() << "{ " << std::endl;
Signal<T, Time> *ref = dynamic_cast<Signal<T, Time> *>(unknown_ref);
if (NULL == ref) {
try {
unknown_ref->checkCompatibility();
} catch (T *t) {
dgTDEBUG(25) << "Cast THROW ok." << std::endl;
Signal<T, Time>::setReference(t);
transmitAbstract = true;
abstractTransmitter = unknown_ref;
transmitAbstractData = t;
} catch (...) {
dgTDEBUG(25) << "Fatal error." << std::endl;
transmitAbstract = false;
DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE,
"Compl. Uncompatible types for plugin.",
"(while trying to plug <%s> on <%s>)"
" with types <%s> on <%s>.",
unknown_ref->getName().c_str(),
this->getName().c_str(), typeid(T).name(),
typeid(unknown_ref).name());
}
} else {
dgTDEBUG(25) << "Cast ok." << std::endl;
transmitAbstract = false;
signalPtr = ref;
}
template< class T,class Time >
bool SignalPtr<T,Time>::
needUpdate( const Time& t ) const
{
if( (isAbstractPluged ())&&(!autoref ()) ){ return getAbstractPtr ()->needUpdate(t);}
else return Signal<T,Time>::needUpdate(t);
dgTDEBUGOUT(5);
}
template <class T, class Time>
void SignalPtr<T, Time>::checkCompatibility() {
if (isPlugged() && (!autoref())) {
getPtr()->checkCompatibility();
} else if (isAbstractPluged() && (!autoref())) {
abstractTransmitter->checkCompatibility();
} else
Signal<T, Time>::checkCompatibility();
}
template <class T, class Time>
bool SignalPtr<T, Time>::needUpdate(const Time &t) const {
if ((isAbstractPluged()) && (!autoref())) {
return getAbstractPtr()->needUpdate(t);
} else
return Signal<T, Time>::needUpdate(t);
}
template <class T, class Time>
const Time &SignalPtr<T, Time>::getTime() const {
if ((isAbstractPluged()) && (!autoref())) {
return getAbstractPtr()->getTime();
}
template< class T,class Time >
const Time& SignalPtr<T,Time>::getTime () const
{
if( (isAbstractPluged ())&&(!autoref ()) ){ return getAbstractPtr ()->getTime ();}
return Signal<T,Time>::getTime ();
return Signal<T, Time>::getTime();
}
template <class T, class Time>
const T &SignalPtr<T, Time>::operator()(const Time &t) {
return access(t);
}
template <class T, class Time>
const T &SignalPtr<T, Time>::access(const Time &t) {
dgTDEBUGIN(15);
if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit) {
dgTDEBUGOUT(15);
return Signal<T, Time>::accessCopy();
} else if (autoref()) {
dgTDEBUGOUT(15);
return Signal<T, Time>::access(t);
} else if (transmitAbstract) {
abstractTransmitter->recompute(t);
dgTDEBUGOUT(15);
return *transmitAbstractData;
} else {
dgTDEBUGOUT(15);
return getPtr()->access(t);
}
template< class T,class Time >
const T& SignalPtr<T,Time>::
operator ()( const Time & t )
{
return access(t);
}
template< class T,class Time >
const T& SignalPtr<T,Time>::
access( const Time & t )
{
dgTDEBUGIN(15);
if( modeNoThrow&&(! isPlugged ())&&Signal<T,Time>::copyInit )
{
dgTDEBUGOUT(15);
return Signal<T,Time>::accessCopy ();
}
else if( autoref () )
{
dgTDEBUGOUT(15);
return Signal<T,Time>::access(t);
}
else if( transmitAbstract )
{
abstractTransmitter->recompute(t);
dgTDEBUGOUT(15);
return *transmitAbstractData;
}
else
{
dgTDEBUGOUT(15);
return getPtr ()->access(t);
}
}
template <class T, class Time>
const T &SignalPtr<T, Time>::accessCopy() const {
if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit)
return Signal<T, Time>::accessCopy();
else if (autoref())
return Signal<T, Time>::accessCopy();
else if (transmitAbstract)
return *transmitAbstractData;
else
return getPtr()->accessCopy();
}
template <class T, class Time>
std::ostream &SignalPtr<T, Time>::writeGraph(std::ostream &os) const {
std::string LeaderLocalName;
std::string LeaderNodeName;
Signal<T, Time>::ExtractNodeAndLocalNames(LeaderLocalName, LeaderNodeName);
if (isAbstractPluged() && !autoref()) {
std::string itLocalName, itNodeName;
getAbstractPtr()->ExtractNodeAndLocalNames(itLocalName, itNodeName);
os << "\t\"" << itNodeName << "\" -> \"" << LeaderNodeName << "\""
<< std::endl
<< "\t [ headlabel = \"" << LeaderLocalName << "\" , taillabel = \""
<< itLocalName << "\", fontsize=7, fontcolor=red ]" << std::endl;
}
template< class T,class Time >
const T& SignalPtr<T,Time>::
accessCopy () const
{
if( modeNoThrow&&(! isPlugged ())&&Signal<T,Time>::copyInit )
return Signal<T,Time>::accessCopy ();
else if( autoref () ) return Signal<T,Time>::accessCopy ();
else if( transmitAbstract ) return *transmitAbstractData;
else return getPtr ()->accessCopy ();
}
template< class T, class Time>
std::ostream & SignalPtr<T,Time>::
writeGraph(std::ostream &os) const
{
std::string LeaderLocalName;
std::string LeaderNodeName;
Signal<T,Time>::ExtractNodeAndLocalNames(LeaderLocalName,LeaderNodeName);
if ( isAbstractPluged () && !autoref ())
{
std::string itLocalName,itNodeName;
getAbstractPtr ()->ExtractNodeAndLocalNames(itLocalName,itNodeName);
os << "\t\"" << itNodeName << "\" -> \"" << LeaderNodeName << "\"" << std::endl
<< "\t [ headlabel = \"" << LeaderLocalName
<< "\" , taillabel = \"" << itLocalName
<< "\", fontsize=7, fontcolor=red ]" << std::endl;
}
return os;
}
template< class T,class Time >
std::ostream& SignalPtr<T,Time>::
display( std::ostream& os ) const
{
dgTDEBUGIN(25) << SignalBase<Time>::name << this << "||" << isPlugged () << "||"<<signalPtr;
{ Signal<T,Time>::display(os); }
if( (isAbstractPluged ())&&(!autoref ()) )
{
// dgTDEBUG(25) << "Display pointed."<<std::endl;
// getPtr ()->display(os<<"PTR->");
os << " -->-- PLUGGED";
}
else
{
if(! isAbstractPluged ()) os << " UNPLUGGED";
else if(autoref ()) os << " AUTOPLUGGED";
}
dgTDEBUGOUT(25);
return os;
return os;
}
template <class T, class Time>
std::ostream &SignalPtr<T, Time>::display(std::ostream &os) const {
dgTDEBUGIN(25) << SignalBase<Time>::name << this << "||" << isPlugged()
<< "||" << signalPtr;
{ Signal<T, Time>::display(os); }
if ((isAbstractPluged()) && (!autoref())) {
os << " -->-- PLUGGED";
} else {
if (!isAbstractPluged())
os << " UNPLUGGED";
else if (autoref())
os << " AUTOPLUGGED";
}
template< class T,class Time >
std::ostream& SignalPtr<T,Time>::
displayDependencies( std::ostream& os,const int depth,
std::string space,
std::string next1,std::string next2 ) const
{
dgTDEBUGIN(25);
if( (isAbstractPluged ())&&(!autoref ()) )
{ getAbstractPtr ()->displayDependencies(os,depth,space,next1+"-- "
+SignalBase<Time>::name+" -->",next2); }
else
{
SignalBase<Time>::displayDependencies(os,depth,space,next1,next2);
}
dgTDEBUGOUT(25);
return os;
dgTDEBUGOUT(25);
return os;
}
template <class T, class Time>
std::ostream &SignalPtr<T, Time>::displayDependencies(std::ostream &os,
const int depth,
std::string space,
std::string next1,
std::string next2) const {
dgTDEBUGIN(25);
if ((isAbstractPluged()) && (!autoref())) {
getAbstractPtr()->displayDependencies(
os, depth, space, next1 + "-- " + SignalBase<Time>::name + " -->",
next2);
} else {
SignalBase<Time>::displayDependencies(os, depth, space, next1, next2);
}
dgTDEBUGOUT(25);
return os;
}
} // end of namespace dynamicgraph.
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_PTR_T_CPP
#endif //! DYNAMIC_GRAPH_SIGNAL_PTR_T_CPP
......@@ -4,139 +4,165 @@
//
#ifndef DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H
# define DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H
# include <dynamic-graph/signal.h>
# include <dynamic-graph/time-dependency.h>
namespace dynamicgraph
{
/*! \brief A type of signal that enforces a time dependency between other signals,
making sure its inputs are up to date on access, using a incrementing time tick as reference.
It works this way: for a given SignalTimeDependent S, the user manually adds dependent signals through the
use of the addDependency function. On access (calling the signal S operator () or access(Time) function),
if the dependent signals are not up-to-date, i.e. if their [last update] time is less than the
current time, their value will be access ()'ed to bring them up-to-date. Thus, the value of dependent
signals can be accessed \b quickly and \b repeatedly through the accessCopy () function.
*/
template< class T,class Time >
class SignalTimeDependent
: public virtual Signal<T,Time>
, public TimeDependency<Time>
{
//TimeDependency<Time> timeDependency;
#define DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H
#include <dynamic-graph/signal.h>
#include <dynamic-graph/time-dependency.h>
namespace dynamicgraph {
/*! \brief A type of signal that enforces a time dependency between other
signals,
making sure its inputs are up to date on access, using a incrementing time
tick as reference.
It works this way. For a given SignalTimeDependent S,
- the user manually adds dependent signals through the use of the
SignalTimeDependent::addDependency function.
- On access (calling the signal S SignalTimeDependent::operator()(const Time&)
or SignalTimeDependent::access(const Time&) function), if the dependent
signals are not up-to-date, i.e. if their [last update] time is less than the
current time, their value will be SignalTimeDependent::access ()'ed to bring
them up-to-date.
Thus, the value of dependent signals can be accessed \b quickly and
\b repeatedly through the Signal::accessCopy () function.
An example:
\code
class MyEntity : public Entity {
public:
SignalTimeDependent( std::string name = "" );
SignalTimeDependent( const SignalArray_const<Time> & arr
,std::string name = "" );
SignalTimeDependent( boost::function2<T&,T&,Time> t
,const SignalArray_const<Time> & sig
,std::string name = "" );
virtual ~SignalTimeDependent () {}
inline const T& operator () ( const Time& t1 ){ return access(t1); }
const T& access( const Time& t1 );
virtual void addDependency( const SignalBase<Time>& signal ) ;
virtual void removeDependency( const SignalBase<Time>& signal ) ;
virtual void clearDependencies ();
std::ostream& writeGraph(std::ostream &os) const
{ return os;}
std::ostream& displayDependencies( std::ostream& os,const int depth=-1,
std::string space="",
std::string next1="",std::string next2="" ) const
{ return TimeDependency<Time>::displayDependencies( os,depth,space,next1,next2 ); }
virtual bool needUpdate( const Time& t ) const;
virtual void setPeriodTime( const Time& p ) ;
virtual Time getPeriodTime () const;
};
/* -------------------------------------------- */
template < class T,class Time >
SignalTimeDependent<T,Time>::
SignalTimeDependent( std::string name )
:Signal<T,Time>(name)
,TimeDependency<Time>(this)
{}
template< class T,class Time>
SignalTimeDependent<T,Time>::
SignalTimeDependent( const SignalArray_const<Time> & arr
,std::string name )
:Signal<T,Time>(name)
,TimeDependency<Time>(this,arr)
{}
template< class T,class Time>
SignalTimeDependent<T,Time>::
SignalTimeDependent( boost::function2<T&,T&,Time> t
,const SignalArray_const<Time> & sig
,std::string name )
:Signal<T,Time>(name)
,TimeDependency<Time>(this,sig)
{ this->setFunction(t); }
template< class T,class Time>
const T& SignalTimeDependent<T,Time>::
access( const Time& t1 )
{
const bool up = TimeDependency<Time>::needUpdate(t1);
//SignalBase<Time>::setReady(false);
/* std::cout << "Time before: "<< signalTime << " -- " */
/* << t1<< " -> Up: "<<up <<std::endl ; */
if( up )
{
TimeDependency<Time>::lastAskForUpdate = false;
const T& Tres = Signal<T,Time>::access(t1);
SignalBase<Time>::setReady(false);
return Tres;
}
else { return Signal<T,Time>::accessCopy (); }
}
template< class T,class Time>
void SignalTimeDependent<T,Time>::
addDependency( const SignalBase<Time>& signal )
{ TimeDependency<Time>::addDependency(signal); }
template< class T,class Time>
void SignalTimeDependent<T,Time>::
removeDependency( const SignalBase<Time>& signal )
{ TimeDependency<Time>::removeDependency(signal); }
template< class T,class Time>
void SignalTimeDependent<T,Time>::
clearDependencies ()
{ TimeDependency<Time>::clearDependency (); }
template< class T,class Time>
bool SignalTimeDependent<T,Time>::
needUpdate( const Time& t ) const
{
return TimeDependency<Time>::needUpdate(t);
}
template< class T,class Time>
void SignalTimeDependent<T,Time>::
setPeriodTime( const Time& p )
{ TimeDependency<Time>::setPeriodTime( p ); }
template< class T,class Time>
Time SignalTimeDependent<T,Time>::
getPeriodTime () const
{ return TimeDependency<Time>::getPeriodTime (); }
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H
// Some signal dependencies
SignalPtr<T,int> dep1, dep2;
SignalTimeDependent<T,int> signal;
MyEntity (const std::string& name)
: Entity (name)
, signal (
// Set the function that computes the signal value
boost::bind (&Entity::computeSignal, this, _1, _2),
// Declare the dependencies
dep1 << dep2,
"signalname")
{}
T& computeSignal (T& res, int time)
{
// The accesses below update the signal if necessary.
dep1(time);
dep1.access(time);
dep1.recompute(time);
// If dep1 and dep2 are already up-to-date, for a faster access, use
dep1.accessCopy();
dep2.accessCopy();
// Compute res
return res;
}
\endcode
*/
template <class T, class Time>
class SignalTimeDependent : public virtual Signal<T, Time>,
public TimeDependency<Time> {
// TimeDependency<Time> timeDependency;
public:
SignalTimeDependent(std::string name = "");
SignalTimeDependent(const SignalArray_const<Time> &arr,
std::string name = "");
SignalTimeDependent(boost::function2<T &, T &, Time> t,
const SignalArray_const<Time> &sig,
std::string name = "");
virtual ~SignalTimeDependent() {}
inline const T &operator()(const Time &t1) { return access(t1); }
const T &access(const Time &t1);
virtual void addDependency(const SignalBase<Time> &signal);
virtual void removeDependency(const SignalBase<Time> &signal);
virtual void clearDependencies();
std::ostream &writeGraph(std::ostream &os) const { return os; }
std::ostream &displayDependencies(std::ostream &os, const int depth = -1,
std::string space = "",
std::string next1 = "",
std::string next2 = "") const {
return TimeDependency<Time>::displayDependencies(os, depth, space, next1,
next2);
}
virtual bool needUpdate(const Time &t) const;
virtual void setPeriodTime(const Time &p);
virtual Time getPeriodTime() const;
};
/* -------------------------------------------- */
template <class T, class Time>
SignalTimeDependent<T, Time>::SignalTimeDependent(std::string name)
: Signal<T, Time>(name), TimeDependency<Time>(this) {}
template <class T, class Time>
SignalTimeDependent<T, Time>::SignalTimeDependent(
const SignalArray_const<Time> &arr, std::string name)
: Signal<T, Time>(name), TimeDependency<Time>(this, arr) {}
template <class T, class Time>
SignalTimeDependent<T, Time>::SignalTimeDependent(
boost::function2<T &, T &, Time> t, const SignalArray_const<Time> &sig,
std::string name)
: Signal<T, Time>(name), TimeDependency<Time>(this, sig) {
this->setFunction(t);
}
template <class T, class Time>
const T &SignalTimeDependent<T, Time>::access(const Time &t1) {
const bool up = TimeDependency<Time>::needUpdate(t1);
// SignalBase<Time>::setReady(false);
/* std::cout << "Time before: "<< signalTime << " -- " */
/* << t1<< " -> Up: "<<up <<std::endl ; */
if (up) {
TimeDependency<Time>::lastAskForUpdate = false;
const T &Tres = Signal<T, Time>::access(t1);
SignalBase<Time>::setReady(false);
return Tres;
} else {
return Signal<T, Time>::accessCopy();
}
}
template <class T, class Time>
void SignalTimeDependent<T, Time>::addDependency(
const SignalBase<Time> &signal) {
TimeDependency<Time>::addDependency(signal);
}
template <class T, class Time>
void SignalTimeDependent<T, Time>::removeDependency(
const SignalBase<Time> &signal) {
TimeDependency<Time>::removeDependency(signal);
}
template <class T, class Time>
void SignalTimeDependent<T, Time>::clearDependencies() {
TimeDependency<Time>::clearDependency();
}
template <class T, class Time>
bool SignalTimeDependent<T, Time>::needUpdate(const Time &t) const {
return TimeDependency<Time>::needUpdate(t);
}
template <class T, class Time>
void SignalTimeDependent<T, Time>::setPeriodTime(const Time &p) {
TimeDependency<Time>::setPeriodTime(p);
}
template <class T, class Time>
Time SignalTimeDependent<T, Time>::getPeriodTime() const {
return TimeDependency<Time>::getPeriodTime();
}
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_SIGNAL_TIME_DEPENDENT_H
......@@ -10,14 +10,13 @@
#ifndef __SIGNAL_HH
#define __SIGNAL_HH
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/signal-base.h>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <string>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/signal-base.h>
#ifdef HAVE_LIBBOOST_THREAD
#include <boost/thread.hpp>
#endif
......@@ -33,34 +32,25 @@ namespace dynamicgraph {
There are several ways to specify the value output by a signal:
\li using the function setConstant(T) to set the value of the signal to T;
\li using the function setReference(mutex, T*) to set the value from a pointer,
whose access is restricted by a mutex;
\li using the function setFunction(boost::function2) that will be called when the
signal's value is accessed.
*/
template< class T,class Time >
class Signal
: public SignalBase<Time>
{
\li using the function setReference(mutex, T*) to set the value
from a pointer, whose access is restricted by a mutex;
\li using the function setFunction(boost::function2) that will be called
when the signal's value is accessed.
*/
template <class T, class Time>
class Signal : public SignalBase<Time> {
protected:
enum SignalType
{
CONSTANT
,REFERENCE
,REFERENCE_NON_CONST
,FUNCTION
};
enum SignalType { CONSTANT, REFERENCE, REFERENCE_NON_CONST, FUNCTION };
static const SignalType SIGNAL_TYPE_DEFAULT = CONSTANT;
SignalType signalType;
T Tcopy1,Tcopy2;
T* Tcopy;
T Tcopy1, Tcopy2;
T *Tcopy;
bool copyInit;
const T* Treference;
T* TreferenceNonConst;
boost::function2<T&,T&,Time> Tfunction;
const T *Treference;
T *TreferenceNonConst;
boost::function2<T &, T &, Time> Tfunction;
bool keepReference;
const static bool KEEP_REFERENCE_DEFAULT = false;
......@@ -70,11 +60,11 @@ class Signal
typedef boost::try_mutex Mutex;
typedef boost::lock_error MutexError;
#else
typedef int* Mutex;
typedef int* MutexError;
typedef int *Mutex;
typedef int *MutexError;
#endif
protected:
protected:
Mutex *providerMutex;
using SignalBase<Time>::signalTime;
......@@ -82,57 +72,57 @@ protected:
using SignalBase<Time>::setReady;
public:
/* --- Constructor/destrusctor --- */
Signal( std::string name );
virtual ~Signal () {}
Signal(std::string name);
virtual ~Signal() {}
/* --- Generic In/Out function --- */
virtual void get( std::ostream& value ) const;
virtual void set( std::istringstream& value ) ;
virtual void trace( std::ostream& os ) const;
virtual void get(std::ostream &value) const;
virtual void set(std::istringstream &value);
virtual void trace(std::ostream &os) const;
/* --- Generic Set function --- */
virtual void setConstant( const T& t );
virtual void setReference( const T* t,Mutex *mutexref=NULL );
virtual void setReferenceNonConstant( T* t,Mutex *mutexref=NULL );
virtual void setFunction( boost::function2<T&,T&,Time> t,
Mutex *mutexref=NULL);
virtual void setConstant(const T &t);
virtual void setReference(const T *t, Mutex *mutexref = NULL);
virtual void setReferenceNonConstant(T *t, Mutex *mutexref = NULL);
virtual void setFunction(boost::function2<T &, T &, Time> t,
Mutex *mutexref = NULL);
inline bool getKeepReference (){ return keepReference; }
inline void setKeepReference( const bool& b ){ keepReference=b; }
inline bool getKeepReference() { return keepReference; }
inline void setKeepReference(const bool &b) { keepReference = b; }
/* --- Signal computation --- */
virtual const T& access( const Time & t );
virtual inline void recompute( const Time & t ) { access(t); }
virtual const T& accessCopy () const;
virtual const T &access(const Time &t);
virtual inline void recompute(const Time &t) { access(t); }
virtual const T &accessCopy() const;
virtual std::ostream& display( std::ostream& os ) const;
virtual std::ostream &display(std::ostream &os) const;
/* --- Operators --- */
virtual inline const T& operator ()( const Time & t ){ return access(t); }
virtual Signal<T,Time>& operator= ( const T& t );
inline operator const T& () const { return accessCopy (); }
virtual void getClassName(std::string & aClassName) const
{ aClassName = typeid(this).name(); }
virtual inline const T &operator()(const Time &t) { return access(t); }
virtual Signal<T, Time> &operator=(const T &t);
inline operator const T &() const { return accessCopy(); }
virtual void getClassName(std::string &aClassName) const {
aClassName = typeid(this).name();
}
public:
virtual void checkCompatibility () { throw Tcopy; }
/// checkCompatibility is used to get the object contained in the
/// signal. This used to verify if a dynamic cast is possible or not.
virtual void checkCompatibility() { throw Tcopy; }
private:
const T& setTcopy( const T& t );
T& getTwork ();
const T& getTwork () const ;
const T& switchTcopy ();
const T &setTcopy(const T &t);
T &getTwork();
const T &getTwork() const;
const T &switchTcopy();
};
} // end of namespace dynamicgraph
} // end of namespace dynamicgraph
#include <dynamic-graph/signal.t.cpp>
#endif // #ifndef __SIGNAL_HH
#endif // #ifndef __SIGNAL_HH
/*
* Local variables:
......
......@@ -4,296 +4,237 @@
//
#ifndef DYNAMIC_GRAPH_SIGNAL_T_CPP
# define DYNAMIC_GRAPH_SIGNAL_T_CPP
# include <dynamic-graph/signal.h>
# include <dynamic-graph/signal-caster.h>
# undef VP_TEMPLATE_DEBUG_MODE
# define VP_TEMPLATE_DEBUG_MODE 0
# include <dynamic-graph/debug.h>
# define __SIGNAL_INIT(name,Tcpy,Tref,TrefNC,mutex) \
SignalBase<Time>(name) \
,signalType (SIGNAL_TYPE_DEFAULT) \
,Tcopy1 (Tcpy) \
,Tcopy2 (Tcpy) \
,Tcopy (&Tcopy1) \
,Treference (Tref) \
,TreferenceNonConst (TrefNC) \
,Tfunction () \
,keepReference (KEEP_REFERENCE_DEFAULT) \
,providerMutex (mutex)
namespace dynamicgraph
{
template< class T,class Time >
Signal<T,Time>::
Signal( std::string name )
:__SIGNAL_INIT(name,T (),NULL,NULL,NULL)
{
return;
}
/* -------------------------------------------------------------------------- */
template< class T,class Time >
void Signal<T,Time>::
set( std::istringstream& stringValue )
{
(*this) = signal_cast<T>( stringValue );
}
template< class T,class Time >
void Signal<T,Time>::
get( std::ostream& os ) const
{
signal_disp<T>( this->accessCopy (),os );
}
template< class T,class Time >
void Signal<T,Time>::
trace( std::ostream& os ) const
{
try { signal_trace<T>( this->accessCopy (),os ); }
catch DG_RETHROW
catch (...)
{ DG_THROW ExceptionSignal( ExceptionSignal::SET_IMPOSSIBLE,
"TRACE operation not possible with this signal. ",
"(bad cast while getting value from %s).",
SignalBase<Time>::getName ().c_str ());
}
}
/* -------------------------------------------------------------------------- */
template< class T,class Time >
const T& Signal<T,Time>::
setTcopy( const T& t )
{
if( Tcopy==&Tcopy1 )
{
Tcopy2 = t;
copyInit = true;
Tcopy = &Tcopy2;
return Tcopy2;
}
else
{
Tcopy1 = t;
copyInit = true;
Tcopy = &Tcopy1;
return Tcopy1;
}
}
template< class T,class Time >
T& Signal<T,Time>::
getTwork ()
{
if( Tcopy==&Tcopy1 ) return Tcopy2; else return Tcopy1;
}
template< class T,class Time >
const T& Signal<T,Time>::
getTwork () const
{
if( Tcopy==&Tcopy1 ) return Tcopy2; else return Tcopy1;
}
template< class T,class Time >
const T& Signal<T,Time>::
switchTcopy ()
{
if( Tcopy==&Tcopy1 )
{
Tcopy = &Tcopy2;
return Tcopy2;
}
else
{
Tcopy = &Tcopy1;
return Tcopy1;
}
}
template< class T,class Time >
void Signal<T,Time>::
setConstant( const T& t )
{
signalType = CONSTANT; setTcopy(t);
setReady ();
}
template< class T,class Time >
void Signal<T,Time>::
setReference( const T* t,Mutex *mutexref )
{
signalType = REFERENCE; Treference = t;
providerMutex = mutexref;
copyInit = false;
setReady ();
}
template< class T,class Time >
void Signal<T,Time>::
setReferenceNonConstant( T* t,Mutex *mutexref )
{
signalType = REFERENCE_NON_CONST;
Treference = t;
TreferenceNonConst = t;
providerMutex = mutexref;
copyInit = false;
setReady ();
}
template< class T,class Time >
void Signal<T,Time>::
setFunction( boost::function2<T&,T&,Time> t,Mutex *mutexref )
{
signalType = FUNCTION;
Tfunction = t;
providerMutex = mutexref;
copyInit = false;
setReady ();
}
template< class T,class Time >
const T& Signal<T,Time>::
accessCopy () const
{
return *Tcopy;
}
template< class T,class Time >
const T& Signal<T,Time>::
access(const Time& t)
{
//dgTDEBUG(20) << "# In (" << SignalBase<Time>::name <<")"<<std::endl;
switch( signalType )
{
case REFERENCE:
case REFERENCE_NON_CONST:
{
if( NULL==providerMutex )
{
copyInit=true;
signalTime = t;
return setTcopy( *Treference );
}
else
{
try
{
#define DYNAMIC_GRAPH_SIGNAL_T_CPP
#include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/signal.h>
#undef VP_TEMPLATE_DEBUG_MODE
#define VP_TEMPLATE_DEBUG_MODE 0
#include <dynamic-graph/debug.h>
#define __SIGNAL_INIT(name, Tcpy, Tref, TrefNC, mutex) \
SignalBase<Time>(name), signalType(SIGNAL_TYPE_DEFAULT), Tcopy1(Tcpy), \
Tcopy2(Tcpy), Tcopy(&Tcopy1), Treference(Tref), \
TreferenceNonConst(TrefNC), Tfunction(), \
keepReference(KEEP_REFERENCE_DEFAULT), providerMutex(mutex)
namespace dynamicgraph {
template <class T, class Time>
Signal<T, Time>::Signal(std::string name)
: __SIGNAL_INIT(name, T(), NULL, NULL, NULL) {
return;
}
/* ------------------------------------------------------------------------ */
template <class T, class Time>
void Signal<T, Time>::set(std::istringstream &stringValue) {
(*this) = signal_io<T>::cast(stringValue);
}
template <class T, class Time>
void Signal<T, Time>::get(std::ostream &os) const {
signal_io<T>::disp(this->accessCopy(), os);
}
template <class T, class Time>
void Signal<T, Time>::trace(std::ostream &os) const {
try {
signal_io<T>::trace(this->accessCopy(), os);
} catch DG_RETHROW catch (...) {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
"TRACE operation not possible with this signal. ",
"(bad cast while getting value from %s).",
SignalBase<Time>::getName().c_str());
}
}
/* ------------------------------------------------------------------------ */
template <class T, class Time>
const T &Signal<T, Time>::setTcopy(const T &t) {
if (Tcopy == &Tcopy1) {
Tcopy2 = t;
copyInit = true;
Tcopy = &Tcopy2;
return Tcopy2;
} else {
Tcopy1 = t;
copyInit = true;
Tcopy = &Tcopy1;
return Tcopy1;
}
}
template <class T, class Time>
T &Signal<T, Time>::getTwork() {
if (Tcopy == &Tcopy1)
return Tcopy2;
else
return Tcopy1;
}
template <class T, class Time>
const T &Signal<T, Time>::getTwork() const {
if (Tcopy == &Tcopy1)
return Tcopy2;
else
return Tcopy1;
}
template <class T, class Time>
const T &Signal<T, Time>::switchTcopy() {
if (Tcopy == &Tcopy1) {
Tcopy = &Tcopy2;
return Tcopy2;
} else {
Tcopy = &Tcopy1;
return Tcopy1;
}
}
template <class T, class Time>
void Signal<T, Time>::setConstant(const T &t) {
signalType = CONSTANT;
setTcopy(t);
setReady();
}
template <class T, class Time>
void Signal<T, Time>::setReference(const T *t, Mutex *mutexref) {
signalType = REFERENCE;
Treference = t;
providerMutex = mutexref;
copyInit = false;
setReady();
}
template <class T, class Time>
void Signal<T, Time>::setReferenceNonConstant(T *t, Mutex *mutexref) {
signalType = REFERENCE_NON_CONST;
Treference = t;
TreferenceNonConst = t;
providerMutex = mutexref;
copyInit = false;
setReady();
}
template <class T, class Time>
void Signal<T, Time>::setFunction(boost::function2<T &, T &, Time> t,
Mutex *mutexref) {
signalType = FUNCTION;
Tfunction = t;
providerMutex = mutexref;
copyInit = false;
setReady();
}
template <class T, class Time>
const T &Signal<T, Time>::accessCopy() const {
return *Tcopy;
}
template <class T, class Time>
const T &Signal<T, Time>::access(const Time &t) {
switch (signalType) {
case REFERENCE:
case REFERENCE_NON_CONST: {
if (NULL == providerMutex) {
copyInit = true;
signalTime = t;
return setTcopy(*Treference);
} else {
try {
#ifdef HAVE_LIBBOOST_THREAD
boost::try_mutex::scoped_try_lock lock(*providerMutex);
boost::try_mutex::scoped_try_lock lock(*providerMutex);
#endif
copyInit = true;
signalTime = t;
return setTcopy(*Treference);
}
catch(const MutexError&)
{ return accessCopy (); }
}
break;
}
copyInit = true;
signalTime = t;
return setTcopy(*Treference);
} catch (const MutexError &) {
return accessCopy();
}
}
case FUNCTION:
{
if( NULL==providerMutex )
{
signalTime = t;
Tfunction(getTwork (),t);
copyInit=true;
return switchTcopy ();
}
else
{
try
{
break;
}
case FUNCTION: {
if (NULL == providerMutex) {
signalTime = t;
Tfunction(getTwork(), t);
copyInit = true;
return switchTcopy();
} else {
try {
#ifdef HAVE_LIBBOOST_THREAD
boost::try_mutex::scoped_try_lock lock(*providerMutex);
boost::try_mutex::scoped_try_lock lock(*providerMutex);
#endif
signalTime = t;
Tfunction(getTwork (),t);
copyInit = true;
return switchTcopy ();
}
catch(const MutexError&)
{ return accessCopy (); }
}
break;
}
case CONSTANT:
default:
if( this->getReady () )
{
setReady(false);
this->setTime(t);
}
return accessCopy ();
};
}
template< class T,class Time >
Signal<T,Time>& Signal<T,Time>::operator= ( const T& t )
{
if( keepReference&&(REFERENCE_NON_CONST==signalType)&&(NULL!=TreferenceNonConst) )
{
if( NULL==providerMutex )
{
setTcopy( t );
(*TreferenceNonConst)=t;
}
else
{
try
{
signalTime = t;
Tfunction(getTwork(), t);
copyInit = true;
return switchTcopy();
} catch (const MutexError &) {
return accessCopy();
}
}
break;
}
case CONSTANT:
default:
if (this->getReady()) {
setReady(false);
this->setTime(t);
}
return accessCopy();
};
}
template <class T, class Time>
Signal<T, Time> &Signal<T, Time>::operator=(const T &t) {
if (keepReference && (REFERENCE_NON_CONST == signalType) &&
(NULL != TreferenceNonConst)) {
if (NULL == providerMutex) {
setTcopy(t);
(*TreferenceNonConst) = t;
} else {
try {
#ifdef HAVE_LIBBOOST_THREAD
boost::try_mutex::scoped_try_lock lock(*providerMutex);
boost::try_mutex::scoped_try_lock lock(*providerMutex);
#endif
setTcopy(t);
(*TreferenceNonConst)=t;
}
catch(const MutexError&)
{ /* TODO ERROR */ }
}
setTcopy(t);
(*TreferenceNonConst) = t;
} catch (const MutexError &) { /* TODO ERROR */
}
else
{ setConstant( t ); }
return *this;
}
template< class T,class Time >
std::ostream& Signal<T,Time>::
display (std::ostream& os) const
{
os<<"Sig:"<<this->name<<" (Type ";
switch( this->signalType )
{
case Signal<T,Time>::CONSTANT: os<< "Cst";break;
case Signal<T,Time>::REFERENCE: os<<"Ref"; break;
case Signal<T,Time>::REFERENCE_NON_CONST: os<<"RefNonCst"; break;
case Signal<T,Time>::FUNCTION: os<<"Fun"; break;
}
return os<<")";
}
} // end of namespace dynamicgraph.
# undef __SIGNAL_INIT
#endif //! DYNAMIC_GRAPH_SIGNAL_T_CPP
}
} else {
setConstant(t);
}
return *this;
}
template <class T, class Time>
std::ostream &Signal<T, Time>::display(std::ostream &os) const {
os << "Sig:" << this->name << " (Type ";
switch (this->signalType) {
case Signal<T, Time>::CONSTANT:
os << "Cst";
break;
case Signal<T, Time>::REFERENCE:
os << "Ref";
break;
case Signal<T, Time>::REFERENCE_NON_CONST:
os << "RefNonCst";
break;
case Signal<T, Time>::FUNCTION:
os << "Fun";
break;
}
return os << ")";
}
} // end of namespace dynamicgraph.
#undef __SIGNAL_INIT
#endif //! DYNAMIC_GRAPH_SIGNAL_T_CPP
......@@ -4,79 +4,71 @@
//
#ifndef DYNAMIC_GRAPH_TIME_DEPENDENCY_H
# define DYNAMIC_GRAPH_TIME_DEPENDENCY_H
# include <list>
#define DYNAMIC_GRAPH_TIME_DEPENDENCY_H
#include <dynamic-graph/signal-array.h>
#include <dynamic-graph/signal-base.h>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/signal-base.h>
# include <dynamic-graph/signal-array.h>
#include <dynamic-graph/fwd.hh>
#include <list>
namespace dynamicgraph
{
/** \brief A helper class for setting and specifying dependencies
between signals.
*/
template<class Time>
class TimeDependency
{
public:
enum DependencyType
{
TIME_DEPENDENT,
BOOL_DEPENDENT,
ALWAYS_READY
};
namespace dynamicgraph {
/** \brief A helper class for setting and specifying dependencies
between signals.
*/
template <class Time>
class TimeDependency {
public:
enum DependencyType { TIME_DEPENDENT, BOOL_DEPENDENT, ALWAYS_READY };
mutable Time lastAskForUpdate;
mutable Time lastAskForUpdate;
public:
public:
SignalBase<Time> &leader;
SignalBase< Time >& leader;
typedef std::list<const SignalBase<Time> *> Dependencies;
static const DependencyType DEPENDENCY_TYPE_DEFAULT = TIME_DEPENDENT;
typedef std::list< const SignalBase<Time> * > Dependencies;
static const DependencyType DEPENDENCY_TYPE_DEFAULT = TIME_DEPENDENT;
Dependencies dependencies;
bool updateFromAllChildren;
static const bool ALL_READY_DEFAULT = false;
Dependencies dependencies;
bool updateFromAllChildren;
static const bool ALL_READY_DEFAULT = false;
DependencyType dependencyType;
DependencyType dependencyType;
Time periodTime;
static const Time PERIOD_TIME_DEFAULT = 1;
Time periodTime;
static const Time PERIOD_TIME_DEFAULT = 1;
public:
TimeDependency(SignalBase<Time> *sig,
const DependencyType dep = DEPENDENCY_TYPE_DEFAULT);
TimeDependency(SignalBase<Time> *sig, const SignalArray_const<Time> &arr,
const DependencyType dep = DEPENDENCY_TYPE_DEFAULT);
virtual ~TimeDependency() {}
public:
void addDependencies(const SignalArray_const<Time> &arr);
void addDependency(const SignalBase<Time> &sig);
void removeDependency(const SignalBase<Time> &sig);
void clearDependency();
TimeDependency( SignalBase<Time>* sig,
const DependencyType dep = DEPENDENCY_TYPE_DEFAULT );
TimeDependency( SignalBase<Time>* sig,
const SignalArray_const<Time>& arr,
const DependencyType dep = DEPENDENCY_TYPE_DEFAULT );
virtual ~TimeDependency () {}
virtual std::ostream &writeGraph(std::ostream &os) const;
std::ostream &displayDependencies(std::ostream &os, const int depth = -1,
std::string space = "",
std::string next1 = "",
std::string next2 = "") const;
void addDependency( const SignalBase<Time>& sig );
void removeDependency( const SignalBase<Time>& sig );
void clearDependency ();
bool needUpdate(const Time &t1) const;
void setDependencyType(DependencyType dep) { dependencyType = dep; }
virtual std::ostream & writeGraph(std::ostream &os) const;
std::ostream& displayDependencies( std::ostream& os,const int depth=-1,
std::string space="",
std::string next1="",std::string next2="" ) const;
void setNeedUpdateFromAllChildren(const bool b = true) {
updateFromAllChildren = b;
}
bool getNeedUpdateFromAllChildren() const { return updateFromAllChildren; }
bool needUpdate( const Time& t1 ) const;
void setPeriodTime(const Time &p) { periodTime = p; }
Time getPeriodTime() const { return periodTime; }
};
void setDependencyType( DependencyType dep ) { dependencyType = dep; }
} // end of namespace dynamicgraph
void setNeedUpdateFromAllChildren( const bool b = true ){ updateFromAllChildren=b; }
bool getNeedUpdateFromAllChildren () const { return updateFromAllChildren; }
void setPeriodTime( const Time& p ) { periodTime = p; }
Time getPeriodTime () const { return periodTime; }
};
} // end of namespace dynamicgraph
# include <dynamic-graph/time-dependency.t.cpp>
#endif //! DYNAMIC_GRAPH_TIME_DEPENDENCY_H
#include <dynamic-graph/time-dependency.t.cpp>
#endif //! DYNAMIC_GRAPH_TIME_DEPENDENCY_H
......@@ -4,162 +4,162 @@
//
#ifndef DYNAMIC_GRAPH_TIME_DEPENDENCY_T_CPP
# define DYNAMIC_GRAPH_TIME_DEPENDENCY_T_CPP
# include <dynamic-graph/time-dependency.h>
# undef VP_TEMPLATE_DEBUG_MODE
# define VP_TEMPLATE_DEBUG_MODE 0
# include <dynamic-graph/debug.h>
# define __TIME_DEPENDENCY_INIT(sig,dep) \
leader(*sig) \
,dependencies () \
,updateFromAllChildren (ALL_READY_DEFAULT) \
,dependencyType (dep) \
,periodTime (PERIOD_TIME_DEFAULT)
namespace dynamicgraph
{
template<class Time>
TimeDependency<Time>::
TimeDependency( SignalBase<Time> *sig
,const DependencyType dep )
:__TIME_DEPENDENCY_INIT(sig,dep)
{}
template<class Time>
TimeDependency<Time>::
TimeDependency( SignalBase<Time> * sig
,const SignalArray_const<Time>& ar
,const DependencyType dep )
:__TIME_DEPENDENCY_INIT(sig,dep)
{
for( unsigned int i=0;i<ar.getSize ();++i )
{addDependency( ar[i] ); }
return ;
#define DYNAMIC_GRAPH_TIME_DEPENDENCY_T_CPP
#include <dynamic-graph/time-dependency.h>
#undef VP_TEMPLATE_DEBUG_MODE
#define VP_TEMPLATE_DEBUG_MODE 0
#include <dynamic-graph/debug.h>
#define __TIME_DEPENDENCY_INIT(sig, dep) \
leader(*sig), dependencies(), updateFromAllChildren(ALL_READY_DEFAULT), \
dependencyType(dep), periodTime(PERIOD_TIME_DEFAULT)
namespace dynamicgraph {
template <class Time>
TimeDependency<Time>::TimeDependency(SignalBase<Time> *sig,
const DependencyType dep)
: __TIME_DEPENDENCY_INIT(sig, dep) {}
template <class Time>
TimeDependency<Time>::TimeDependency(SignalBase<Time> *sig,
const SignalArray_const<Time> &ar,
const DependencyType dep)
: __TIME_DEPENDENCY_INIT(sig, dep) {
addDependencies(ar);
return;
}
/* ------------------------------------------------------------------------ */
template <class Time>
void TimeDependency<Time>::addDependencies(const SignalArray_const<Time> &ar) {
for (unsigned int i = 0; i < ar.getSize(); ++i) {
addDependency(ar[i]);
}
}
/* -------------------------------------------------------------------------- */
template<class Time>
void TimeDependency<Time>::
addDependency( const SignalBase<Time>& sig )
{
dependencies.push_front(&sig);
}
template <class Time>
void TimeDependency<Time>::addDependency(const SignalBase<Time> &sig) {
dependencies.push_front(&sig);
}
template<class Time>
void TimeDependency<Time>::
removeDependency( const SignalBase<Time>& sig )
{
dependencies.remove(&sig);
}
template<class Time>
void TimeDependency<Time>::
clearDependency ()
{
dependencies.clear ();
}
template <class Time>
void TimeDependency<Time>::removeDependency(const SignalBase<Time> &sig) {
dependencies.remove(&sig);
}
template<class Time>
bool TimeDependency<Time>::
needUpdate( const Time& t1 ) const
{
dgTDEBUG(15) << "# In {" << leader.getName () << " : ("<< leader.getReady ()<<") "
<< t1 << " >? " << leader.getTime () << std::endl;
if( leader.getReady () ) { dgTDEBUGOUT(15);return true; }
if( lastAskForUpdate ) { dgTDEBUGOUT(15);return true; }
switch( dependencyType )
{
case ALWAYS_READY:
{ dgTDEBUGOUT(15);return true; }
case BOOL_DEPENDENT: break;
case TIME_DEPENDENT:
{
if( t1<leader.getTime ()+periodTime )
{ dgTDEBUGOUT(15);return false; }
break;
}
};
bool res = updateFromAllChildren;
const typename Dependencies::const_iterator itend=dependencies.end ();
for( typename Dependencies::const_iterator it=dependencies.begin ();it!=itend;++it )
{
const SignalBase<Time> &sig = **it;
dgTDEBUG(15)<< "Ask update for "<< sig <<std::endl;
if( (sig.getTime ()>leader.getTime ()) || (sig.needUpdate(t1)) )
{ if(updateFromAllChildren) continue; else {res=true; break;} }
else { if(updateFromAllChildren) {res=false; break;} else continue; }
}
lastAskForUpdate = res;
template <class Time>
void TimeDependency<Time>::clearDependency() {
dependencies.clear();
}
template <class Time>
bool TimeDependency<Time>::needUpdate(const Time &t1) const {
dgTDEBUG(15) << "# In {" << leader.getName() << " : (" << leader.getReady()
<< ") " << t1 << " >? " << leader.getTime() << std::endl;
if (leader.getReady()) {
dgTDEBUGOUT(15);
return res;
return true;
}
if (lastAskForUpdate) {
dgTDEBUGOUT(15);
return true;
}
template<class Time>
std::ostream& TimeDependency<Time>::
writeGraph( std::ostream & os) const
{
std::string LeaderLocalName;
std::string LeaderNodeName;
leader.ExtractNodeAndLocalNames(LeaderLocalName,LeaderNodeName);
if (dependencies.size ()!=0)
{
const typename Dependencies::const_iterator itend=dependencies.end ();
for( typename Dependencies::const_iterator it=dependencies.begin ();it!=itend;++it )
{
std::string itLocalName,itNodeName;
(*it)->ExtractNodeAndLocalNames(itLocalName,itNodeName);
os << "\"" << itNodeName << "\" -> \"" << LeaderNodeName << "\"" << std::endl
<< " [ headlabel = \"" << LeaderLocalName << "\" , taillabel = \"" << itLocalName << "\" ]" << std::endl;
}
switch (dependencyType) {
case ALWAYS_READY: {
dgTDEBUGOUT(15);
return true;
}
case BOOL_DEPENDENT:
break;
case TIME_DEPENDENT: {
if (t1 < leader.getTime() + periodTime) {
dgTDEBUGOUT(15);
return false;
}
return os;
break;
}
};
bool res = updateFromAllChildren;
const typename Dependencies::const_iterator itend = dependencies.end();
for (typename Dependencies::const_iterator it = dependencies.begin();
it != itend; ++it) {
const SignalBase<Time> &sig = **it;
dgTDEBUG(15) << "Ask update for " << sig << std::endl;
if ((sig.getTime() > leader.getTime()) || (sig.needUpdate(t1))) {
if (updateFromAllChildren)
continue;
else {
res = true;
break;
}
} else {
if (updateFromAllChildren) {
res = false;
break;
} else
continue;
}
}
template<class Time>
std::ostream& TimeDependency<Time>::
displayDependencies( std::ostream& os,const int depth,
std::string space,
std::string next1,std::string next2 ) const
lastAskForUpdate = res;
dgTDEBUGOUT(15);
return res;
}
template <class Time>
std::ostream &TimeDependency<Time>::writeGraph(std::ostream &os) const {
return os;
}
template <class Time>
std::ostream &TimeDependency<Time>::displayDependencies(
std::ostream &os, const int depth, std::string space, std::string next1,
std::string next2) const {
leader.SignalBase<Time>::displayDependencies(os, depth, space, next1, next2)
<< " (";
switch (dependencyType) {
case ALWAYS_READY:
os << "A";
break;
case BOOL_DEPENDENT:
os << "ready=" << ((leader.getReady()) ? "TRUE" : "FALSE");
break;
case TIME_DEPENDENT:
os << "t=" << leader.getTime() << " (/" << periodTime << ") ";
break;
};
os << ")"; //<<std::endl;
{
leader.SignalBase<Time>::displayDependencies(os,depth,space,next1,next2)<<" (";
switch( dependencyType )
{
case ALWAYS_READY: os<<"A"; break;
case BOOL_DEPENDENT: os << "ready=" << ((leader.getReady ())?"TRUE":"FALSE"); break;
case TIME_DEPENDENT:
os <<"t="<<leader.getTime () <<" (/"<<periodTime<<") " ;
break;
};
os<<")"; //<<std::endl;
{
const typename Dependencies::const_iterator itend=dependencies.end ();
for( typename Dependencies::const_iterator it=dependencies.begin ();it!=itend;++it )
if( depth!=0 )
{
os<<std::endl;
std::string ajout = "|";
std::string ajout2 = "|";
typename Dependencies::const_iterator it2=it; it2++;
if( it2==dependencies.end () ) { ajout = "`"; ajout2= " "; }
(*it)->displayDependencies( os,depth-1,space+next2+" ",ajout,ajout2 );
}
else
{ os<<std::endl<<space<<" `-- ..."; break; }
}
return os;
const typename Dependencies::const_iterator itend = dependencies.end();
for (typename Dependencies::const_iterator it = dependencies.begin();
it != itend; ++it)
if (depth != 0) {
os << std::endl;
std::string ajout = "|";
std::string ajout2 = "|";
typename Dependencies::const_iterator it2 = it;
++it2;
if (it2 == dependencies.end()) {
ajout = "`";
ajout2 = " ";
}
(*it)->displayDependencies(os, depth - 1, space + next2 + " ", ajout,
ajout2);
} else {
os << std::endl << space << " `-- ...";
break;
}
}
return os;
}
} // end of namespace dynamicgraph
} // end of namespace dynamicgraph
# undef __TIME_DEPENDENCY_INIT
#endif //! DYNAMIC_GRAPH_TIME_DEPENDENCY_T_CPP
#undef __TIME_DEPENDENCY_INIT
#endif //! DYNAMIC_GRAPH_TIME_DEPENDENCY_T_CPP
......@@ -4,79 +4,70 @@
//
#ifndef DYNAMIC_GRAPH_TRACER_REAL_TIME_H
# define DYNAMIC_GRAPH_TRACER_REAL_TIME_H
# include <sstream>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/tracer.h>
# include <dynamic-graph/config-tracer-real-time.hh>
namespace dynamicgraph
{
/// \ingroup plugin
///
/// \brief Stream for the tracer real-time.
class DG_TRACERREALTIME_DLLAPI OutStringStream : public std::ostringstream
{
public:
char* buffer;
std::streamsize index;
std::streamsize bufferSize;
bool full;
std::string givenname;
public:
OutStringStream ();
~OutStringStream ();
void resize (const std::streamsize& size);
bool addData (const char * data, const std::streamoff& size);
void dump (std::ostream& os);
void empty ();
};
/// \ingroup plugin
///
/// \brief Main class of the tracer real-time plug-in.
class DG_TRACERREALTIME_DLLAPI TracerRealTime : public Tracer
{
DYNAMIC_GRAPH_ENTITY_DECL ();
public:
TracerRealTime (const std::string & n);
virtual ~TracerRealTime ()
{}
virtual void closeFiles ();
virtual void trace ();
void display (std::ostream& os) const;
DG_TRACERREALTIME_DLLAPI friend std::ostream& operator<<
(std::ostream& os, const TracerRealTime& t);
protected:
virtual void openFile (const SignalBase<int>& sig,
const std::string& filename);
virtual void recordSignal (std::ostream& os,
const SignalBase<int>& sig);
void emptyBuffers ();
void setBufferSize (const int& SIZE)
{
bufferSize=SIZE;
}
const int& getBufferSize ()
{
return bufferSize;
}
typedef std::list<std::ofstream*> HardFileList;
static const int BUFFER_SIZE_DEFAULT = 1048576; // 1Mo
int bufferSize;
HardFileList hardFiles;
};
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_TRACER_REAL_TIME_H
#define DYNAMIC_GRAPH_TRACER_REAL_TIME_H
#include <dynamic-graph/tracer.h>
#include <dynamic-graph/config-tracer-real-time.hh>
#include <dynamic-graph/fwd.hh>
#include <sstream>
namespace dynamicgraph {
/// \ingroup plugin
///
/// \brief Stream for the tracer real-time.
class DG_TRACERREALTIME_DLLAPI OutStringStream : public std::ostringstream {
public:
char *buffer;
std::streamsize index;
std::streamsize bufferSize;
bool full;
std::string givenname;
public:
OutStringStream();
~OutStringStream();
void resize(const std::streamsize &size);
bool addData(const char *data, const std::streamoff &size);
void dump(std::ostream &os);
void empty();
};
/// \ingroup plugin
///
/// \brief Main class of the tracer real-time plug-in.
class DG_TRACERREALTIME_DLLAPI TracerRealTime : public Tracer {
DYNAMIC_GRAPH_ENTITY_DECL();
public:
TracerRealTime(const std::string &n);
virtual ~TracerRealTime() {}
virtual void closeFiles();
virtual void trace();
void display(std::ostream &os) const;
DG_TRACERREALTIME_DLLAPI friend std::ostream &operator<<(
std::ostream &os, const TracerRealTime &t);
void emptyBuffers();
void setBufferSize(const int &SIZE) { bufferSize = SIZE; }
const int &getBufferSize() { return bufferSize; }
protected:
virtual void openFile(const SignalBase<int> &sig,
const std::string &filename);
virtual void recordSignal(std::ostream &os, const SignalBase<int> &sig);
typedef std::list<std::ofstream *> HardFileList;
static const int BUFFER_SIZE_DEFAULT = 1048576; // 1Mo
int bufferSize;
HardFileList hardFiles;
};
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_TRACER_REAL_TIME_H