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 894 additions and 803 deletions
...@@ -5,14 +5,14 @@ ...@@ -5,14 +5,14 @@
#ifndef DYNAMIC_GRAPH_POOL_H #ifndef DYNAMIC_GRAPH_POOL_H
#define DYNAMIC_GRAPH_POOL_H #define DYNAMIC_GRAPH_POOL_H
#include <map> #include <dynamic-graph/dynamic-graph-api.h>
#include <string>
#include <sstream>
#include <dynamic-graph/fwd.hh>
#include <dynamic-graph/exception-factory.h> #include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/signal-base.h> #include <dynamic-graph/signal-base.h>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/fwd.hh>
#include <map>
#include <sstream>
#include <string>
namespace dynamicgraph { namespace dynamicgraph {
/*! @ingroup dgraph /*! @ingroup dgraph
...@@ -36,10 +36,10 @@ class DYNAMIC_GRAPH_DLLAPI PoolStorage { ...@@ -36,10 +36,10 @@ class DYNAMIC_GRAPH_DLLAPI PoolStorage {
@{ @{
*/ */
/*! \brief Sorted set of entities with unique key (name). */ /*! \brief Sorted set of entities with unique key (name). */
typedef std::map<std::string, Entity*> Entities; typedef std::map<std::string, Entity *> Entities;
/// \brief Get unique instance of the class. /// \brief Get unique instance of the class.
static PoolStorage* getInstance(); static PoolStorage *getInstance();
/// \brief Destroy the unique instance of the class /// \brief Destroy the unique instance of the class
static void destroy(); static void destroy();
...@@ -56,47 +56,47 @@ class DYNAMIC_GRAPH_DLLAPI PoolStorage { ...@@ -56,47 +56,47 @@ class DYNAMIC_GRAPH_DLLAPI PoolStorage {
\par[in] entname: The name of the entity, \par[in] entname: The name of the entity,
\par[in] ent: Pointer towards the entity. \par[in] ent: Pointer towards the entity.
*/ */
void registerEntity(const std::string& entname, Entity* ent); void registerEntity(const std::string &entname, Entity *ent);
/*! \brief Unregister an entity. /*! \brief Unregister an entity.
\par[in] entname: The name of the entity, \par[in] entname: The name of the entity,
*/ */
void deregisterEntity(const std::string& entname); void deregisterEntity(const std::string &entname);
/*! \brief Unregister an entity. /*! \brief Unregister an entity.
\par[in] entity: iterator in the map, \par[in] entity: iterator in the map,
*/ */
void deregisterEntity(const Entities::iterator& entity); void deregisterEntity(const Entities::iterator &entity);
/*! \brief Get an entity. /*! \brief Get an entity.
\par[in] entname: The name of the entity, \par[in] entname: The name of the entity,
\return Pointer towards the entity. \return Pointer towards the entity.
*/ */
Entity& getEntity(const std::string& name); Entity &getEntity(const std::string &name);
/// Const access to entity map /// Const access to entity map
const Entities& getEntityMap() const; const Entities &getEntityMap() const;
/*! \brief Test if the entity exists. */ /*! \brief Test if the entity exists. */
bool existEntity(const std::string& name); bool existEntity(const std::string &name);
/*! \brief Test if the entity exists. If it does, return a pointer on it. */ /*! \brief Test if the entity exists. If it does, return a pointer on it. */
bool existEntity(const std::string& name, Entity*& ptr); bool existEntity(const std::string &name, Entity *&ptr);
/*! \brief Disallocate an entity. /*! \brief Disallocate an entity.
\par[in] entname: The name of the entity, \par[in] entname: The name of the entity,
*/ */
void clearPlugin(const std::string& name); void clearPlugin(const std::string &name);
/*! @} */ /*! @} */
/// ///
/// \brief Get a signal by name /// \brief Get a signal by name
/// ///
/// \param sigpath stream containing a string of the form "entity.signal" /// \param sigpath stream containing a string of the form "entity.signal"
SignalBase<int>& getSignal(std::istringstream& sigpath); SignalBase<int> &getSignal(std::istringstream &sigpath);
/*! \brief This method write a graph description on the file named /*! \brief This method write a graph description on the file named
FileName. */ FileName. */
void writeGraph(const std::string& aFileName); void writeGraph(const std::string &aFileName);
void writeCompletionList(std::ostream& os); void writeCompletionList(std::ostream &os);
protected: protected:
/*! \name Fields of the class to manage the three entities. /*! \name Fields of the class to manage the three entities.
...@@ -108,10 +108,10 @@ class DYNAMIC_GRAPH_DLLAPI PoolStorage { ...@@ -108,10 +108,10 @@ class DYNAMIC_GRAPH_DLLAPI PoolStorage {
private: private:
PoolStorage() {} PoolStorage() {}
static PoolStorage* instance_; static PoolStorage *instance_;
}; };
inline PoolStorage& g_pool() { return *PoolStorage::getInstance(); } inline PoolStorage &g_pool() { return *PoolStorage::getInstance(); }
} // end of namespace dynamicgraph. } // end of namespace dynamicgraph.
......
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
*/ */
#ifndef DYNAMIC_GRAPH_PROCESS_LIST_H_ #ifndef DYNAMIC_GRAPH_PROCESS_LIST_H_
#define DYNAMIC_GRAPH_PROCESS_LIST_H #define DYNAMIC_GRAPH_PROCESS_LIST_H_
#include <dynamic-graph/dynamic-graph-api.h>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp> #include <boost/serialization/vector.hpp>
#include <dynamic-graph/fwd.hh> #include <dynamic-graph/fwd.hh>
#include <dynamic-graph/dynamic-graph-api.h>
namespace dynamicgraph { namespace dynamicgraph {
namespace CPU { namespace CPU {
...@@ -22,14 +22,15 @@ class DYNAMIC_GRAPH_DLLAPI ProcessList { ...@@ -22,14 +22,15 @@ class DYNAMIC_GRAPH_DLLAPI ProcessList {
ProcessList(); ProcessList();
}; };
/// \class This class gather information on a specific CPU. /// This class gather information on a specific CPU.
/// ///
class DYNAMIC_GRAPH_DLLAPI CPUData { class DYNAMIC_GRAPH_DLLAPI CPUData {
public: public:
CPUData(); CPUData();
int cpu_id_; int cpu_id_;
inline unsigned long long int computePeriod(unsigned long long int &a, unsigned long long int &b) { inline unsigned long long int computePeriod(unsigned long long int &a,
unsigned long long int &b) {
return (a > b) ? a - b : 0; return (a > b) ? a - b : 0;
} }
...@@ -122,7 +123,7 @@ class DYNAMIC_GRAPH_DLLAPI CPUData { ...@@ -122,7 +123,7 @@ class DYNAMIC_GRAPH_DLLAPI CPUData {
} }
}; };
/// \class This class gathers information on a computer. /// This class gathers information on a computer.
/// This includes a list of CPU /// This includes a list of CPU
class DYNAMIC_GRAPH_DLLAPI System { class DYNAMIC_GRAPH_DLLAPI System {
private: private:
......
// -*- 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
...@@ -4,163 +4,13 @@ ...@@ -4,163 +4,13 @@
#ifndef DYNAMIC_GRAPH_LOGGER_REAL_TIME_H #ifndef DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
#define 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
#ifdef ENABLE_RT_LOG #ifdef ENABLE_RT_LOG
#define dgADD_OSTREAM_TO_RTLOG(ostr) \ #define dgADD_OSTREAM_TO_RTLOG(ostr) \
::dynamicgraph::RealTimeLogger::instance().addOutputStream( \ ::dynamicgraph::RealTimeLogger::instance().addOutputStream( \
::dynamicgraph::LoggerStreamPtr_t(new ::dynamicgraph::LoggerIOStream(ostr))) ::dynamicgraph::LoggerStreamPtr_t( \
new ::dynamicgraph::LoggerIOStream(ostr)))
#define dgRTLOG() ::dynamicgraph::RealTimeLogger::instance().front() #define dgRTLOG() ::dynamicgraph::RealTimeLogger::instance().front()
#else // ENABLE_RT_LOG #else // ENABLE_RT_LOG
#define dgADD_OSTREAM_TO_RTLOG(ostr) struct __end_with_semicolon #define dgADD_OSTREAM_TO_RTLOG(ostr) struct __end_with_semicolon
...@@ -171,4 +21,6 @@ class DYNAMIC_GRAPH_DLLAPI RealTimeLogger { ...@@ -171,4 +21,6 @@ class DYNAMIC_GRAPH_DLLAPI RealTimeLogger {
__null_stream() __null_stream()
#endif #endif
#include <dynamic-graph/real-time-logger-def.h>
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_H #endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
#ifndef DYNAMIC_GRAPH_SIGNAL_ARRAY_H #ifndef DYNAMIC_GRAPH_SIGNAL_ARRAY_H
#define 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 <dynamic-graph/dynamic-graph-api.h>
#include <vector> #include <dynamic-graph/signal-base.h>
#include <stdio.h> #include <stdio.h>
#include <vector>
namespace dynamicgraph { namespace dynamicgraph {
/// \ingroup dgraph /// \ingroup dgraph
...@@ -21,30 +22,36 @@ class SignalArray_const { ...@@ -21,30 +22,36 @@ class SignalArray_const {
static const int DEFAULT_SIZE = 20; static const int DEFAULT_SIZE = 20;
protected: protected:
std::vector<const SignalBase<Time>*> const_array; std::vector<const SignalBase<Time> *> const_array;
unsigned int size, rank; unsigned int size, rank;
public: public:
SignalArray_const<Time>(const unsigned int& sizeARG = DEFAULT_SIZE) : const_array(sizeARG), size(sizeARG), rank(0) {} 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) { SignalArray_const<Time>(const SignalBase<Time> &sig)
: const_array(DEFAULT_SIZE), size(DEFAULT_SIZE), rank(0) {
addElmt(&sig); addElmt(&sig);
} }
SignalArray_const<Time>(const SignalArray<Time>& siga) SignalArray_const<Time>(const SignalArray<Time> &siga)
: const_array(siga.getSize()), size(siga.getSize()), rank(siga.getSize()) { : const_array(siga.getSize()),
size(siga.getSize()),
rank(siga.getSize()) {
for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i]; for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i];
} }
SignalArray_const<Time>(const SignalArray_const<Time>& siga) SignalArray_const<Time>(const SignalArray_const<Time> &siga)
: const_array(siga.getSize()), size(siga.getSize()), rank(siga.getSize()) { : const_array(siga.getSize()),
size(siga.getSize()),
rank(siga.getSize()) {
for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i]; for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i];
} }
virtual ~SignalArray_const<Time>() {} virtual ~SignalArray_const<Time>() {}
protected: protected:
void addElmt(const SignalBase<Time>* el) { void addElmt(const SignalBase<Time> *el) {
if (rank >= size) { if (rank >= size) {
size += DEFAULT_SIZE; size += DEFAULT_SIZE;
const_array.resize(size); const_array.resize(size);
...@@ -53,18 +60,21 @@ class SignalArray_const { ...@@ -53,18 +60,21 @@ class SignalArray_const {
} }
public: public:
virtual SignalArray_const<Time>& operator<<(const SignalBase<Time>& sig) { virtual SignalArray_const<Time> &operator<<(const SignalBase<Time> &sig) {
addElmt(&sig); addElmt(&sig);
return *this; return *this;
} }
public: public:
virtual const SignalBase<Time>& operator[](const unsigned int& idx) const { return *const_array[idx]; } virtual const SignalBase<Time> &operator[](const unsigned int &idx) const {
return *const_array[idx];
}
virtual unsigned int getSize() const { return rank; } virtual unsigned int getSize() const { return rank; }
}; };
template <class Time> template <class Time>
SignalArray_const<Time> operator<<(const SignalBase<Time>& sig1, const SignalBase<Time>& sig2) { SignalArray_const<Time> operator<<(const SignalBase<Time> &sig1,
const SignalBase<Time> &sig2) {
SignalArray_const<Time> res(sig1); SignalArray_const<Time> res(sig1);
res << sig2; res << sig2;
return res; return res;
...@@ -81,19 +91,22 @@ class SignalArray : public SignalArray_const<Time> { ...@@ -81,19 +91,22 @@ class SignalArray : public SignalArray_const<Time> {
using SignalArray_const<Time>::rank; using SignalArray_const<Time>::rank;
protected: protected:
mutable std::vector<SignalBase<Time>*> array; mutable std::vector<SignalBase<Time> *> array;
public: public:
SignalArray<Time>(const unsigned int& sizeARG = DEFAULT_SIZE) : SignalArray_const<Time>(0), array(sizeARG) { SignalArray<Time>(const unsigned int &sizeARG = DEFAULT_SIZE)
: SignalArray_const<Time>(0), array(sizeARG) {
size = sizeARG; size = sizeARG;
} }
SignalArray<Time>(SignalBase<Time>& sig) : SignalArray_const<Time>(0), array(DEFAULT_SIZE) { SignalArray<Time>(SignalBase<Time> &sig)
: SignalArray_const<Time>(0), array(DEFAULT_SIZE) {
size = DEFAULT_SIZE; size = DEFAULT_SIZE;
addElmt(&sig); addElmt(&sig);
} }
SignalArray<Time>(const SignalArray<Time>& siga) : SignalArray_const<Time>(siga.getSize()), array(siga.getSize()) { SignalArray<Time>(const SignalArray<Time> &siga)
: SignalArray_const<Time>(siga.getSize()), array(siga.getSize()) {
rank = siga.getSize(); rank = siga.getSize();
for (unsigned int i = 0; i < rank; ++i) array[i] = &siga[i]; for (unsigned int i = 0; i < rank; ++i) array[i] = &siga[i];
} }
...@@ -101,7 +114,7 @@ class SignalArray : public SignalArray_const<Time> { ...@@ -101,7 +114,7 @@ class SignalArray : public SignalArray_const<Time> {
virtual ~SignalArray<Time>() {} virtual ~SignalArray<Time>() {}
protected: protected:
void addElmt(SignalBase<Time>* el) { void addElmt(SignalBase<Time> *el) {
if (rank >= size) { if (rank >= size) {
size += DEFAULT_SIZE; size += DEFAULT_SIZE;
array.resize(size); array.resize(size);
...@@ -110,22 +123,25 @@ class SignalArray : public SignalArray_const<Time> { ...@@ -110,22 +123,25 @@ class SignalArray : public SignalArray_const<Time> {
} }
public: public:
virtual SignalArray<Time>& operator<<(SignalBase<Time>& sig) { virtual SignalArray<Time> &operator<<(SignalBase<Time> &sig) {
addElmt(&sig); addElmt(&sig);
return *this; return *this;
} }
virtual SignalArray_const<Time> operator<<(const SignalBase<Time>& sig) const { virtual SignalArray_const<Time> operator<<(
const SignalBase<Time> &sig) const {
SignalArray_const<Time> res(*this); SignalArray_const<Time> res(*this);
res << sig; res << sig;
return res; return res;
} }
virtual SignalBase<Time>& operator[](const unsigned int& idx) const { return *array[idx]; } virtual SignalBase<Time> &operator[](const unsigned int &idx) const {
return *array[idx];
}
}; };
template <class Time> template <class Time>
SignalArray<Time> operator<<(SignalBase<Time>& sig1, SignalBase<Time>& sig2) { SignalArray<Time> operator<<(SignalBase<Time> &sig1, SignalBase<Time> &sig2) {
SignalArray<Time> res(sig1); SignalArray<Time> res(sig1);
res << sig2; res << sig2;
return res; return res;
......
// -*- mode: c++ -*- // -*- mode: c++ -*-
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse, // Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST. // JRL, CNRS/AIST.
// LAAS, CNRS
// //
#ifndef DYNAMIC_GRAPH_SIGNAL_BASE_H #ifndef DYNAMIC_GRAPH_SIGNAL_BASE_H
#define DYNAMIC_GRAPH_SIGNAL_BASE_H #define DYNAMIC_GRAPH_SIGNAL_BASE_H
#include <string> #include <dynamic-graph/exception-signal.h>
#include <sstream>
#include <typeinfo>
#include <boost/noncopyable.hpp>
#include <boost/noncopyable.hpp>
#include <dynamic-graph/fwd.hh> #include <dynamic-graph/fwd.hh>
#include <dynamic-graph/exception-signal.h> #include <sstream>
#include <string>
#include <typeinfo>
namespace dynamicgraph { namespace dynamicgraph {
...@@ -25,23 +26,26 @@ namespace dynamicgraph { ...@@ -25,23 +26,26 @@ namespace dynamicgraph {
template <class Time> template <class Time>
class SignalBase : public boost::noncopyable { class SignalBase : public boost::noncopyable {
public: public:
explicit SignalBase(std::string name = "") : name(name), signalTime(0), ready(false) {} explicit SignalBase(std::string name = "")
: name(name), signalTime(0), ready(false) {}
virtual ~SignalBase() {} virtual ~SignalBase() {}
/// \name Time /// \name Time
/// \{ /// \{
virtual const Time& getTime() const { return signalTime; } virtual const Time &getTime() const { return signalTime; }
virtual void setTime(const Time& t) { signalTime = t; } virtual void setTime(const Time &t) { signalTime = t; }
const bool& getReady() const { return ready; } const bool &getReady() const { return ready; }
const std::string& getName() const { return name; } const std::string &getName() const { return name; }
void getClassName(std::string& aClassName) const { aClassName = typeid(this).name(); } void getClassName(std::string &aClassName) const {
aClassName = typeid(this).name();
}
virtual void setPeriodTime(const Time&) {} virtual void setPeriodTime(const Time &) {}
virtual Time getPeriodTime() const { return 1; } virtual Time getPeriodTime() const { return 1; }
...@@ -50,20 +54,22 @@ class SignalBase : public boost::noncopyable { ...@@ -50,20 +54,22 @@ class SignalBase : public boost::noncopyable {
/// \name Dependencies /// \name Dependencies
/// \{ /// \{
virtual void addDependency(const SignalBase<Time>&) {} virtual void addDependency(const SignalBase<Time> &) {}
virtual void removeDependency(const SignalBase<Time>&) {} virtual void removeDependency(const SignalBase<Time> &) {}
virtual void clearDependencies() {} virtual void clearDependencies() {}
virtual bool needUpdate(const Time&) const { return ready; } virtual bool needUpdate(const Time &) const { return ready; }
inline void setReady(const bool sready = true) { ready = sready; } inline void setReady(const bool sready = true) { ready = sready; }
virtual std::ostream& writeGraph(std::ostream& os) const { return os; } virtual std::ostream &writeGraph(std::ostream &os) const { return os; }
virtual std::ostream& displayDependencies(std::ostream& os, const int = -1, std::string space = "", virtual std::ostream &displayDependencies(std::ostream &os, const int = -1,
std::string next1 = "", std::string = "") const { std::string space = "",
std::string next1 = "",
std::string = "") const {
os << space << next1 << "-- "; os << space << next1 << "-- ";
display(os); display(os);
return os; return os;
...@@ -78,23 +84,30 @@ class SignalBase : public boost::noncopyable { ...@@ -78,23 +84,30 @@ class SignalBase : public boost::noncopyable {
* a descending operation (the actual <this> object will call the arg-signal * a descending operation (the actual <this> object will call the arg-signal
* and not the opposite). * and not the opposite).
*/ */
virtual void plug(SignalBase<Time>* sigarg) { virtual void plug(SignalBase<Time> *sigarg) {
DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Plug-in operation not possible with this signal. ", DG_THROW ExceptionSignal(
"(while trying to plug %s on %s).", sigarg->getName().c_str(), this->getName().c_str()); 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 unplug() { virtual void unplug() {
DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Plug-in operation not possible with this signal. ", DG_THROW ExceptionSignal(
"(while trying to unplug %s).", this->getName().c_str()); ExceptionSignal::PLUG_IMPOSSIBLE,
"Plug-in operation not possible with this signal. ",
"(while trying to unplug %s).", this->getName().c_str());
} }
virtual bool isPlugged() const { return false; } virtual bool isPlugged() const { return false; }
virtual SignalBase<Time>* getPluged() const { return NULL; } virtual SignalBase<Time> *getPluged() const { return NULL; }
virtual void setConstantDefault() { virtual void setConstantDefault() {
DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Plug-in operation not possible with this signal. ", DG_THROW ExceptionSignal(
"(while trying to save %s).", this->getName().c_str()); ExceptionSignal::PLUG_IMPOSSIBLE,
"Plug-in operation not possible with this signal. ",
"(while trying to save %s).", this->getName().c_str());
} }
/// \} /// \}
...@@ -105,24 +118,32 @@ class SignalBase : public boost::noncopyable { ...@@ -105,24 +118,32 @@ class SignalBase : public boost::noncopyable {
/* Generic set function. Should be reimplemented by the specific /* Generic set function. Should be reimplemented by the specific
* Signal. Sets a signal value * Signal. Sets a signal value
*/ */
virtual void set(std::istringstream&) { virtual void set(std::istringstream &) {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "Set operation not possible with this signal. ", DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
"(while trying to set %s).", this->getName().c_str()); "Set operation not possible with this signal. ",
"(while trying to set %s).",
this->getName().c_str());
} }
virtual void get(std::ostream&) const { virtual void get(std::ostream &) const {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "Get operation not possible with this signal. ", DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
"(while trying to get %s).", this->getName().c_str()); "Get operation not possible with this signal. ",
"(while trying to get %s).",
this->getName().c_str());
} }
virtual inline void recompute(const Time&) { virtual inline void recompute(const Time &) {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "Recompute operation not possible with this signal. ", DG_THROW ExceptionSignal(
"(while trying to recompute %s).", this->getName().c_str()); 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 { virtual void trace(std::ostream &) const {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "Trace operation not possible with this signal. ", DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
"(while trying to trace %s).", this->getName().c_str()); "Trace operation not possible with this signal. ",
"(while trying to trace %s).",
this->getName().c_str());
} }
/// \} /// \}
...@@ -130,7 +151,7 @@ class SignalBase : public boost::noncopyable { ...@@ -130,7 +151,7 @@ class SignalBase : public boost::noncopyable {
/// \name Display /// \name Display
/// \{ /// \{
virtual std::ostream& display(std::ostream& os) const { virtual std::ostream &display(std::ostream &os) const {
os << "Sig:" << name; os << "Sig:" << name;
return os; return os;
} }
...@@ -150,14 +171,17 @@ class SignalBase : public boost::noncopyable { ...@@ -150,14 +171,17 @@ class SignalBase : public boost::noncopyable {
/// \name Information providers /// \name Information providers
/// \{ /// \{
virtual void ExtractNodeAndLocalNames(std::string& LocalName, std::string& NodeName) const { virtual void ExtractNodeAndLocalNames(std::string &LocalName,
std::string &NodeName) const {
std::string fullname = this->getName(); std::string fullname = this->getName();
size_t IdxPosLocalName = fullname.rfind(":"); size_t IdxPosLocalName = fullname.rfind(":");
LocalName = fullname.substr(IdxPosLocalName + 1, fullname.length() - IdxPosLocalName + 1); LocalName = fullname.substr(IdxPosLocalName + 1,
fullname.length() - IdxPosLocalName + 1);
size_t IdxPosNodeNameStart = fullname.find("("); size_t IdxPosNodeNameStart = fullname.find("(");
size_t IdxPosNodeNameEnd = fullname.find(")"); size_t IdxPosNodeNameEnd = fullname.find(")");
NodeName = fullname.substr(IdxPosNodeNameStart + 1, IdxPosNodeNameEnd - IdxPosNodeNameStart - 1); NodeName = fullname.substr(IdxPosNodeNameStart + 1,
IdxPosNodeNameEnd - IdxPosNodeNameStart - 1);
} }
/// \} /// \}
...@@ -165,8 +189,10 @@ class SignalBase : public boost::noncopyable { ...@@ -165,8 +189,10 @@ class SignalBase : public boost::noncopyable {
/// \name Test /// \name Test
/// \{ /// \{
virtual void checkCompatibility() { virtual void checkCompatibility() {
DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Abstract signal not compatible with anything.", DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE,
"(while trying to plug <%s>).", this->getName().c_str()); "Abstract signal not compatible with anything.",
"(while trying to plug <%s>).",
this->getName().c_str());
} }
/// \} /// \}
...@@ -178,7 +204,7 @@ class SignalBase : public boost::noncopyable { ...@@ -178,7 +204,7 @@ class SignalBase : public boost::noncopyable {
/// Forward to a virtual fonction. /// Forward to a virtual fonction.
template <class Time> template <class Time>
std::ostream& operator<<(std::ostream& os, const SignalBase<Time>& sig) { std::ostream &operator<<(std::ostream &os, const SignalBase<Time> &sig) {
return sig.display(os); return sig.display(os);
} }
} // end of namespace dynamicgraph. } // end of namespace dynamicgraph.
......
// -*- c++-mode -*- // -*- 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 #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
#define DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH #define DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
#include <map>
#include <typeinfo>
#include <vector>
#include <boost/any.hpp> #pragma warning "This file is now useless"
#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_)
#endif // #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH #endif // #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH
...@@ -4,111 +4,142 @@ ...@@ -4,111 +4,142 @@
#ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HH #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HH
#define DYNAMIC_GRAPH_SIGNAL_CASTER_HH #define DYNAMIC_GRAPH_SIGNAL_CASTER_HH
#include <map> #include <dynamic-graph/dynamic-graph-api.h>
#include <typeinfo> #include <dynamic-graph/eigen-io.h>
#include <vector> #include <dynamic-graph/linear-algebra.h>
#include <boost/any.hpp>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <boost/function/function1.hpp>
#include <boost/function/function2.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/tuple/tuple.hpp> #include <map>
#include <vector>
#include <dynamic-graph/dynamic-graph-api.h>
#include "dynamic-graph/exception-signal.h" #include "dynamic-graph/exception-signal.h"
namespace dynamicgraph { 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 /// Inherit from this class if you want to keep default implementation for some
/// register a cast when instanced somewhere in a cpp file. Pass the /// functions.
/// typeid () of the type you want to register a cast to as the first template <typename T>
/// argument. The code is provided here so the class does not need struct signal_io_base {
/// to be exported. /// serialize a signal value.
class DYNAMIC_GRAPH_DLLAPI SignalCastRegisterer { inline static void disp(const T &value, std::ostream &os) { os << value; }
public: /// deserialize a signal value.
inline SignalCastRegisterer(const std::type_info& type, SignalCaster::displayer_type displayer, inline static T cast(std::istringstream &is) {
SignalCaster::caster_type caster, SignalCaster::tracer_type tracer) { T inst;
SignalCaster::getInstance()->registerCast(type, displayer, caster, tracer); 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; }
}; };
/// Global signal cast template (helper) functions /// Inherit from this class if tracing is not implemented for a given type.
///
/// Using these avoid using the typeid () operator and keeps the
/// implementation details hidden.
template <typename T> template <typename T>
void signal_disp(const T& value, std::ostream& os) { struct signal_io_unimplemented {
SignalCaster::getInstance()->disp(value, os); 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> template <typename T>
T signal_cast(std::istringstream& iss) { struct signal_io : signal_io_base<T> {};
return boost::any_cast<T>(SignalCaster::getInstance()->cast(typeid(T), iss));
} /// 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);
}
};
/// 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);
}
inline static quat_type cast(std::istringstream &is) {
return quat_type(signal_io<matrix_type>::cast(is));
}
inline static void trace(const quat_type &value, std::ostream &os) {
signal_io<matrix_type>::trace(value.coeffs(), os);
}
};
/// 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());
}
}
};
template <typename T>
void signal_trace(const T& value, std::ostream& os) {
SignalCaster::getInstance()->trace(value, os);
}
} // end of namespace dynamicgraph. } // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_CASTER_HH #endif //! DYNAMIC_GRAPH_SIGNAL_CASTER_HH
...@@ -12,31 +12,37 @@ ...@@ -12,31 +12,37 @@
/* dg signals */ /* dg signals */
#include <dynamic-graph/entity.h> #include <dynamic-graph/entity.h>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/signal-ptr.h> #include <dynamic-graph/signal-ptr.h>
#include <dynamic-graph/signal-time-dependent.h> #include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/linear-algebra.h>
/* --- MACROS ---------------------------------------------------------- */ /* --- MACROS ---------------------------------------------------------- */
#define SIGNAL_OUT_FUNCTION_NAME(name) name##SOUT_function #define SIGNAL_OUT_FUNCTION_NAME(name) name##SOUT_function
#define DECLARE_SIGNAL(name, IO, type) ::dynamicgraph::Signal<type, int> m_##name##S##IO #define DECLARE_SIGNAL(name, IO, type) \
#define CONSTRUCT_SIGNAL(name, IO, type) \ ::dynamicgraph::Signal<type, int> m_##name##S##IO
m_##name##S##IO(getClassName() + "(" + getName() + ")::" + #IO + "put(" + #type + ")::" + #name) #define CONSTRUCT_SIGNAL(name, IO, type) \
m_##name##S##IO(getClassName() + "(" + getName() + ")::" + #IO + "put(" + \
#type + ")::" + #name)
#define BIND_SIGNAL_TO_FUNCTION(name, IO, type) \ #define BIND_SIGNAL_TO_FUNCTION(name, IO, type) \
m_##name##S##IO.setFunction(boost::bind(&EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name), this, _1, _2)); 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 DECLARE_SIGNAL_IN(name, type) \
#define CONSTRUCT_SIGNAL_IN(name, type) \ ::dynamicgraph::SignalPtr<type, int> m_##name##SIN
m_##name##SIN(NULL, getClassName() + "(" + getName() + ")::input(" + #type + ")::" + #name) #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 DECLARE_SIGNAL_OUT_FUNCTION(name, type) \
type &SIGNAL_OUT_FUNCTION_NAME(name)(type &, int)
#define DEFINE_SIGNAL_OUT_FUNCTION(name, type) \ #define DEFINE_SIGNAL_OUT_FUNCTION(name, type) \
type& EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name)(type & s, int iter) type &EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name)(type & s, int iter)
#define SIGNAL_OUT_FUNCTION(name) name##SOUT_function #define SIGNAL_OUT_FUNCTION(name) name##SOUT_function
...@@ -45,19 +51,21 @@ ...@@ -45,19 +51,21 @@
::dynamicgraph::SignalTimeDependent<type, int> m_##name##SOUT; \ ::dynamicgraph::SignalTimeDependent<type, int> m_##name##SOUT; \
\ \
protected: \ protected: \
type& SIGNAL_OUT_FUNCTION(name)(type&, int) type &SIGNAL_OUT_FUNCTION(name)(type &, int)
#define CONSTRUCT_SIGNAL_OUT(name, type, dep) \ #define CONSTRUCT_SIGNAL_OUT(name, type, dep) \
m_##name##SOUT(boost::bind(&EntityClassName::name##SOUT_function, this, _1, _2), dep, \ m_##name##SOUT( \
getClassName() + "(" + getName() + ")::output(" + #type + ")::" + #name) boost::bind(&EntityClassName::name##SOUT_function, this, _1, _2), dep, \
getClassName() + "(" + getName() + ")::output(" + #type + ")::" + #name)
/**************** INNER SIGNALS *******************/ /**************** INNER SIGNALS *******************/
#define SIGNAL_INNER_FUNCTION_NAME(name) name##SINNER_function #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 DECLARE_SIGNAL_INNER_FUNCTION(name, type) \
type &SIGNAL_INNER_FUNCTION_NAME(name)(type &, int)
#define DEFINE_SIGNAL_INNER_FUNCTION(name, type) \ #define DEFINE_SIGNAL_INNER_FUNCTION(name, type) \
type& EntityClassName::SIGNAL_INNER_FUNCTION_NAME(name)(type & s, int iter) type &EntityClassName::SIGNAL_INNER_FUNCTION_NAME(name)(type & s, int iter)
#define DECLARE_SIGNAL_INNER(name, type) \ #define DECLARE_SIGNAL_INNER(name, type) \
public: \ public: \
...@@ -66,8 +74,9 @@ ...@@ -66,8 +74,9 @@
protected: \ protected: \
DECLARE_SIGNAL_INNER_FUNCTION(name, type) DECLARE_SIGNAL_INNER_FUNCTION(name, type)
#define CONSTRUCT_SIGNAL_INNER(name, type, dep) \ #define CONSTRUCT_SIGNAL_INNER(name, type, dep) \
m_##name##SINNER(boost::bind(&EntityClassName::name##SINNER_function, this, _1, _2), dep, \ m_##name##SINNER( \
getClassName() + "(" + getName() + ")::inner(" + #type + ")::" + #name) 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__
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#include <dynamic-graph/exception-signal.h> #include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/signal.h> #include <dynamic-graph/signal.h>
#include <dynamic-graph/deprecated.hh>
namespace dynamicgraph { namespace dynamicgraph {
/// \ingroup dgraph /// \ingroup dgraph
/// ///
...@@ -20,22 +18,27 @@ namespace dynamicgraph { ...@@ -20,22 +18,27 @@ namespace dynamicgraph {
/// In that sense, when plugged into, it acts as a "pointer" to the /// In that sense, when plugged into, it acts as a "pointer" to the
/// input signal, hence the name. Operator -> is also overloaded and /// input signal, hence the name. Operator -> is also overloaded and
/// can be used to access the pointed signal. /// 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> template <class T, class Time>
class SignalPtr : public virtual Signal<T, Time> { class SignalPtr : public virtual Signal<T, Time> {
public: public:
using SignalBase<Time>::getName; using SignalBase<Time>::getName;
protected: protected:
Signal<T, Time>* signalPtr; Signal<T, Time> *signalPtr;
bool modeNoThrow; bool modeNoThrow;
bool transmitAbstract; bool transmitAbstract;
SignalBase<Time>* abstractTransmitter; SignalBase<Time> *abstractTransmitter;
T* transmitAbstractData; T *transmitAbstractData;
inline bool autoref() const { return signalPtr == this; } inline bool autoref() const { return signalPtr == this; }
public: /* --- CONSTRUCTORS --- */ public: /* --- CONSTRUCTORS --- */
SignalPtr(Signal<T, Time>* ptr, std::string name = "") SignalPtr(Signal<T, Time> *ptr, std::string name = "")
: Signal<T, Time>(name), : Signal<T, Time>(name),
signalPtr(ptr), signalPtr(ptr),
modeNoThrow(false), modeNoThrow(false),
...@@ -44,43 +47,44 @@ class SignalPtr : public virtual Signal<T, Time> { ...@@ -44,43 +47,44 @@ class SignalPtr : public virtual Signal<T, Time> {
virtual ~SignalPtr() { signalPtr = NULL; } virtual ~SignalPtr() { signalPtr = NULL; }
public: /* --- PLUG-IN OPERATION --- */ public:
Signal<T, Time>* getPtr(); // throw /* --- PLUG-IN OPERATION --- */
const Signal<T, Time>* getPtr() const; // throw Signal<T, Time> *getPtr(); // throw
SignalBase<Time>* getAbstractPtr(); // throw const Signal<T, Time> *getPtr() const; // throw
const SignalBase<Time>* getAbstractPtr() const; // throw SignalBase<Time> *getAbstractPtr(); // throw
virtual void plug(SignalBase<Time>* ref); const SignalBase<Time> *getAbstractPtr() const; // throw
virtual void plug(SignalBase<Time> *ref);
virtual void unplug() { plug(NULL); } virtual void unplug() { plug(NULL); }
virtual bool isPlugged() const { return (NULL != signalPtr); } virtual bool isPlugged() const { return (NULL != signalPtr); }
virtual SignalBase<Time>* getPluged() const { return signalPtr; } virtual SignalBase<Time> *getPluged() const { return signalPtr; }
virtual bool isAbstractPluged() const; virtual bool isAbstractPluged() const;
virtual const Time& getTime() const; virtual const Time &getTime() const;
/* Equivalent operator-like definitions. */ /* Equivalent operator-like definitions. */
inline Signal<T, Time>* operator->() { return getPtr(); } inline Signal<T, Time> *operator->() { return getPtr(); }
inline const Signal<T, Time>* operator->() const { return getPtr(); } inline const Signal<T, Time> *operator->() const { return getPtr(); }
inline Signal<T, Time>& operator*() { return *getPtr(); } inline Signal<T, Time> &operator*() { return *getPtr(); }
inline const Signal<T, Time>& operator*() const { return *getPtr(); } inline const Signal<T, Time> &operator*() const { return *getPtr(); }
inline operator bool() const { return isPlugged(); } inline operator bool() const { return isPlugged(); }
public: /* --- INHERITANCE --- */ public: /* --- INHERITANCE --- */
virtual bool needUpdate(const Time& t) const; virtual bool needUpdate(const Time &t) const;
virtual std::ostream& writeGraph(std::ostream& os) const; virtual std::ostream &writeGraph(std::ostream &os) const;
virtual std::ostream& display(std::ostream& os) const; virtual std::ostream &display(std::ostream &os) const;
/* For compatibility, .access () is equivalent to ->access (). For explicit /* For compatibility, .access () is equivalent to ->access (). For explicit
* pointer dereference : * pointer dereference :
* Prefere -> () to () * Prefere -> () to ()
*/ */
virtual const T& operator()(const Time& t); virtual const T &operator()(const Time &t);
/* Similarly, Prefere ->access to .access /* Similarly, Prefere ->access to .access
*/ */
virtual const T& access(const Time& t); virtual const T &access(const Time &t);
virtual const T& accessCopy() const; virtual const T &accessCopy() const;
inline void setConstantDefault(const T& t) { inline void setConstantDefault(const T &t) {
Signal<T, Time>::setConstant(t); Signal<T, Time>::setConstant(t);
modeNoThrow = true; modeNoThrow = true;
} }
...@@ -94,31 +98,36 @@ class SignalPtr : public virtual Signal<T, Time> { ...@@ -94,31 +98,36 @@ class SignalPtr : public virtual Signal<T, Time> {
* setting functions. The behavior is to plugged the signalPtr on * setting functions. The behavior is to plugged the signalPtr on
* the classical mother Signal layer of the object. * the classical mother Signal layer of the object.
*/ */
virtual void setConstant(const T& t) { virtual void setConstant(const T &t) {
plug(this); plug(this);
Signal<T, Time>::setConstant(t); Signal<T, Time>::setConstant(t);
} }
virtual void setReference(const T* t, typename Signal<T, Time>::Mutex* m = NULL) { virtual void setReference(const T *t,
typename Signal<T, Time>::Mutex *m = NULL) {
plug(this); plug(this);
Signal<T, Time>::setReference(t, m); Signal<T, Time>::setReference(t, m);
} }
virtual void setFunction(boost::function2<T&, T&, Time> t, typename Signal<T, Time>::Mutex* m = NULL) { virtual void setFunction(boost::function2<T &, T &, Time> t,
typename Signal<T, Time>::Mutex *m = NULL) {
plug(this); plug(this);
Signal<T, Time>::setFunction(t, m); Signal<T, Time>::setFunction(t, m);
} }
/* template< class Provider > */ /* template< class Provider > */
/* void setFunction( T& (Provider::*fun)(Time,T&),Provider& obj, */ /* void setFunction( T& (Provider::*fun)(Time,T&),Provider& obj, */
/* boost::try_mutex *mutexref=NULL ) */ /* boost::try_mutex *mutexref=NULL ) */
/* { plug(this); Signal<T,Time>::setFunction(fun,obj,mutexref); } */ /* { plug(this); Signal<T,Time>::setFunction(fun,obj,mutexref); } */
virtual inline Signal<T, Time>& operator=(const T& t) { virtual inline Signal<T, Time> &operator=(const T &t) {
setConstant(t); setConstant(t);
return *this; return *this;
} }
virtual std::ostream& displayDependencies(std::ostream& os, const int depth = -1, std::string space = "", virtual std::ostream &displayDependencies(std::ostream &os,
std::string next1 = "", std::string next2 = "") const; const int depth = -1,
std::string space = "",
std::string next1 = "",
std::string next2 = "") const;
protected: // Interdiction of the rest of the heritage protected: // Interdiction of the rest of the heritage
using Signal<T, Time>::addDependency; using Signal<T, Time>::addDependency;
......
...@@ -18,32 +18,36 @@ bool SignalPtr<T, Time>::isAbstractPluged() const { ...@@ -18,32 +18,36 @@ bool SignalPtr<T, Time>::isAbstractPluged() const {
} }
template <class T, class Time> template <class T, class Time>
Signal<T, Time>* SignalPtr<T, Time>::getPtr() { Signal<T, Time> *SignalPtr<T, Time>::getPtr() {
dgTDEBUGIN(25); dgTDEBUGIN(25);
if (!isPlugged()) if (!isPlugged()) DG_THROW
DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED, "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", ExceptionSignal(ExceptionSignal::NOT_INITIALIZED,
getName().c_str()); "In SignalPtr: SIN ptr not set.", " (in signal <%s>)",
getName().c_str());
dgTDEBUGOUT(25); dgTDEBUGOUT(25);
return signalPtr; return signalPtr;
} }
template <class T, class Time> template <class T, class Time>
const Signal<T, Time>* SignalPtr<T, Time>::getPtr() const { const Signal<T, Time> *SignalPtr<T, Time>::getPtr() const {
dgTDEBUGIN(25) << SignalBase<Time>::name << "(" << isPlugged() << ")" << this << "->" << signalPtr << std::endl; dgTDEBUGIN(25) << SignalBase<Time>::name << "(" << isPlugged() << ")" << this
<< "->" << signalPtr << std::endl;
dgTDEBUGIN(25); dgTDEBUGIN(25);
if (!isPlugged()) { if (!isPlugged()) {
DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED, "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED,
getName().c_str()); "In SignalPtr: SIN ptr not set.",
" (in signal <%s>)", getName().c_str());
} }
dgTDEBUGOUT(25); dgTDEBUGOUT(25);
return signalPtr; return signalPtr;
} }
template <class T, class Time> template <class T, class Time>
SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() { SignalBase<Time> *SignalPtr<T, Time>::getAbstractPtr() {
if (!isAbstractPluged()) { if (!isAbstractPluged()) {
DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED, "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED,
getName().c_str()); "In SignalPtr: SIN ptr not set.",
" (in signal <%s>)", getName().c_str());
} }
if (NULL != signalPtr) if (NULL != signalPtr)
return signalPtr; return signalPtr;
...@@ -52,10 +56,11 @@ SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() { ...@@ -52,10 +56,11 @@ SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() {
} }
template <class T, class Time> template <class T, class Time>
const SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() const { const SignalBase<Time> *SignalPtr<T, Time>::getAbstractPtr() const {
if (!isAbstractPluged()) { if (!isAbstractPluged()) {
DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED, "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED,
getName().c_str()); "In SignalPtr: SIN ptr not set.",
" (in signal <%s>)", getName().c_str());
} }
if (NULL != signalPtr) if (NULL != signalPtr)
return signalPtr; return signalPtr;
...@@ -64,7 +69,7 @@ const SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() const { ...@@ -64,7 +69,7 @@ const SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() const {
} }
template <class T, class Time> template <class T, class Time>
void SignalPtr<T, Time>::plug(SignalBase<Time>* unknown_ref) { void SignalPtr<T, Time>::plug(SignalBase<Time> *unknown_ref) {
dgTDEBUGIN(5); dgTDEBUGIN(5);
if (!unknown_ref) { if (!unknown_ref) {
signalPtr = NULL; signalPtr = NULL;
...@@ -73,13 +78,14 @@ void SignalPtr<T, Time>::plug(SignalBase<Time>* unknown_ref) { ...@@ -73,13 +78,14 @@ void SignalPtr<T, Time>::plug(SignalBase<Time>* unknown_ref) {
return; return;
} }
dgTDEBUG(5) << "# In T = " << getName() << " =" << typeid(Signal<T, Time>::Tcopy1).name() << "{ " << std::endl; dgTDEBUG(5) << "# In T = " << getName() << " ="
<< typeid(Signal<T, Time>::Tcopy1).name() << "{ " << std::endl;
Signal<T, Time>* ref = dynamic_cast<Signal<T, Time>*>(unknown_ref); Signal<T, Time> *ref = dynamic_cast<Signal<T, Time> *>(unknown_ref);
if (NULL == ref) { if (NULL == ref) {
try { try {
unknown_ref->checkCompatibility(); unknown_ref->checkCompatibility();
} catch (T* t) { } catch (T *t) {
dgTDEBUG(25) << "Cast THROW ok." << std::endl; dgTDEBUG(25) << "Cast THROW ok." << std::endl;
Signal<T, Time>::setReference(t); Signal<T, Time>::setReference(t);
transmitAbstract = true; transmitAbstract = true;
...@@ -88,10 +94,12 @@ void SignalPtr<T, Time>::plug(SignalBase<Time>* unknown_ref) { ...@@ -88,10 +94,12 @@ void SignalPtr<T, Time>::plug(SignalBase<Time>* unknown_ref) {
} catch (...) { } catch (...) {
dgTDEBUG(25) << "Fatal error." << std::endl; dgTDEBUG(25) << "Fatal error." << std::endl;
transmitAbstract = false; transmitAbstract = false;
DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Compl. Uncompatible types for plugin.", DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE,
"Compl. Uncompatible types for plugin.",
"(while trying to plug <%s> on <%s>)" "(while trying to plug <%s> on <%s>)"
" with types <%s> on <%s>.", " with types <%s> on <%s>.",
unknown_ref->getName().c_str(), this->getName().c_str(), typeid(T).name(), unknown_ref->getName().c_str(),
this->getName().c_str(), typeid(T).name(),
typeid(unknown_ref).name()); typeid(unknown_ref).name());
} }
} else { } else {
...@@ -113,7 +121,7 @@ void SignalPtr<T, Time>::checkCompatibility() { ...@@ -113,7 +121,7 @@ void SignalPtr<T, Time>::checkCompatibility() {
} }
template <class T, class Time> template <class T, class Time>
bool SignalPtr<T, Time>::needUpdate(const Time& t) const { bool SignalPtr<T, Time>::needUpdate(const Time &t) const {
if ((isAbstractPluged()) && (!autoref())) { if ((isAbstractPluged()) && (!autoref())) {
return getAbstractPtr()->needUpdate(t); return getAbstractPtr()->needUpdate(t);
} else } else
...@@ -121,7 +129,7 @@ bool SignalPtr<T, Time>::needUpdate(const Time& t) const { ...@@ -121,7 +129,7 @@ bool SignalPtr<T, Time>::needUpdate(const Time& t) const {
} }
template <class T, class Time> template <class T, class Time>
const Time& SignalPtr<T, Time>::getTime() const { const Time &SignalPtr<T, Time>::getTime() const {
if ((isAbstractPluged()) && (!autoref())) { if ((isAbstractPluged()) && (!autoref())) {
return getAbstractPtr()->getTime(); return getAbstractPtr()->getTime();
} }
...@@ -129,12 +137,12 @@ const Time& SignalPtr<T, Time>::getTime() const { ...@@ -129,12 +137,12 @@ const Time& SignalPtr<T, Time>::getTime() const {
} }
template <class T, class Time> template <class T, class Time>
const T& SignalPtr<T, Time>::operator()(const Time& t) { const T &SignalPtr<T, Time>::operator()(const Time &t) {
return access(t); return access(t);
} }
template <class T, class Time> template <class T, class Time>
const T& SignalPtr<T, Time>::access(const Time& t) { const T &SignalPtr<T, Time>::access(const Time &t) {
dgTDEBUGIN(15); dgTDEBUGIN(15);
if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit) { if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit) {
dgTDEBUGOUT(15); dgTDEBUGOUT(15);
...@@ -151,8 +159,9 @@ const T& SignalPtr<T, Time>::access(const Time& t) { ...@@ -151,8 +159,9 @@ const T& SignalPtr<T, Time>::access(const Time& t) {
return getPtr()->access(t); return getPtr()->access(t);
} }
} }
template <class T, class Time> template <class T, class Time>
const T& SignalPtr<T, Time>::accessCopy() const { const T &SignalPtr<T, Time>::accessCopy() const {
if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit) if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit)
return Signal<T, Time>::accessCopy(); return Signal<T, Time>::accessCopy();
else if (autoref()) else if (autoref())
...@@ -163,28 +172,28 @@ const T& SignalPtr<T, Time>::accessCopy() const { ...@@ -163,28 +172,28 @@ const T& SignalPtr<T, Time>::accessCopy() const {
return getPtr()->accessCopy(); return getPtr()->accessCopy();
} }
template <class T, class Time> template <class T, class Time>
std::ostream& SignalPtr<T, Time>::writeGraph(std::ostream& os) const { std::ostream &SignalPtr<T, Time>::writeGraph(std::ostream &os) const {
std::string LeaderLocalName; std::string LeaderLocalName;
std::string LeaderNodeName; std::string LeaderNodeName;
Signal<T, Time>::ExtractNodeAndLocalNames(LeaderLocalName, LeaderNodeName); Signal<T, Time>::ExtractNodeAndLocalNames(LeaderLocalName, LeaderNodeName);
if (isAbstractPluged() && !autoref()) { if (isAbstractPluged() && !autoref()) {
std::string itLocalName, itNodeName; std::string itLocalName, itNodeName;
getAbstractPtr()->ExtractNodeAndLocalNames(itLocalName, itNodeName); getAbstractPtr()->ExtractNodeAndLocalNames(itLocalName, itNodeName);
os << "\t\"" << itNodeName << "\" -> \"" << LeaderNodeName << "\"" << std::endl os << "\t\"" << itNodeName << "\" -> \"" << LeaderNodeName << "\""
<< "\t [ headlabel = \"" << LeaderLocalName << "\" , taillabel = \"" << itLocalName << std::endl
<< "\", fontsize=7, fontcolor=red ]" << std::endl; << "\t [ headlabel = \"" << LeaderLocalName << "\" , taillabel = \""
<< itLocalName << "\", fontsize=7, fontcolor=red ]" << std::endl;
} }
return os; return os;
} }
template <class T, class Time> template <class T, class Time>
std::ostream& SignalPtr<T, Time>::display(std::ostream& os) const { std::ostream &SignalPtr<T, Time>::display(std::ostream &os) const {
dgTDEBUGIN(25) << SignalBase<Time>::name << this << "||" << isPlugged() << "||" << signalPtr; dgTDEBUGIN(25) << SignalBase<Time>::name << this << "||" << isPlugged()
<< "||" << signalPtr;
{ Signal<T, Time>::display(os); } { Signal<T, Time>::display(os); }
if ((isAbstractPluged()) && (!autoref())) { if ((isAbstractPluged()) && (!autoref())) {
// dgTDEBUG(25) << "Display pointed."<<std::endl;
// getPtr ()->display(os<<"PTR->");
os << " -->-- PLUGGED"; os << " -->-- PLUGGED";
} else { } else {
if (!isAbstractPluged()) if (!isAbstractPluged())
...@@ -198,11 +207,16 @@ std::ostream& SignalPtr<T, Time>::display(std::ostream& os) const { ...@@ -198,11 +207,16 @@ std::ostream& SignalPtr<T, Time>::display(std::ostream& os) const {
} }
template <class T, class Time> template <class T, class Time>
std::ostream& SignalPtr<T, Time>::displayDependencies(std::ostream& os, const int depth, std::string space, std::ostream &SignalPtr<T, Time>::displayDependencies(std::ostream &os,
std::string next1, std::string next2) const { const int depth,
std::string space,
std::string next1,
std::string next2) const {
dgTDEBUGIN(25); dgTDEBUGIN(25);
if ((isAbstractPluged()) && (!autoref())) { if ((isAbstractPluged()) && (!autoref())) {
getAbstractPtr()->displayDependencies(os, depth, space, next1 + "-- " + SignalBase<Time>::name + " -->", next2); getAbstractPtr()->displayDependencies(
os, depth, space, next1 + "-- " + SignalBase<Time>::name + " -->",
next2);
} else { } else {
SignalBase<Time>::displayDependencies(os, depth, space, next1, next2); SignalBase<Time>::displayDependencies(os, depth, space, next1, next2);
} }
......
...@@ -9,41 +9,90 @@ ...@@ -9,41 +9,90 @@
#include <dynamic-graph/time-dependency.h> #include <dynamic-graph/time-dependency.h>
namespace dynamicgraph { namespace dynamicgraph {
/*! \brief A type of signal that enforces a time dependency between other signals, /*! \brief A type of signal that enforces a time dependency between other
making sure its inputs are up to date on access, using a incrementing time tick as reference. signals,
It works this way: for a given SignalTimeDependent S, the user manually adds dependent signals through the making sure its inputs are up to date on access, using a incrementing time
use of the addDependency function. On access (calling the signal S operator () or access(Time) function), tick as reference.
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 It works this way. For a given SignalTimeDependent S,
signals can be accessed \b quickly and \b repeatedly through the accessCopy () function. - 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:
// 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> template <class T, class Time>
class SignalTimeDependent : public virtual Signal<T, Time>, public TimeDependency<Time> { class SignalTimeDependent : public virtual Signal<T, Time>,
public TimeDependency<Time> {
// TimeDependency<Time> timeDependency; // TimeDependency<Time> timeDependency;
public: public:
SignalTimeDependent(std::string name = ""); SignalTimeDependent(std::string name = "");
SignalTimeDependent(const SignalArray_const<Time>& arr, std::string name = ""); SignalTimeDependent(const SignalArray_const<Time> &arr,
SignalTimeDependent(boost::function2<T&, T&, Time> t, const SignalArray_const<Time>& sig, std::string name = ""); std::string name = "");
SignalTimeDependent(boost::function2<T &, T &, Time> t,
const SignalArray_const<Time> &sig,
std::string name = "");
virtual ~SignalTimeDependent() {} virtual ~SignalTimeDependent() {}
inline const T& operator()(const Time& t1) { return access(t1); } inline const T &operator()(const Time &t1) { return access(t1); }
const T& access(const Time& t1); const T &access(const Time &t1);
virtual void addDependency(const SignalBase<Time>& signal); virtual void addDependency(const SignalBase<Time> &signal);
virtual void removeDependency(const SignalBase<Time>& signal); virtual void removeDependency(const SignalBase<Time> &signal);
virtual void clearDependencies(); virtual void clearDependencies();
std::ostream& writeGraph(std::ostream& os) const { return os; } std::ostream &writeGraph(std::ostream &os) const { return os; }
std::ostream& displayDependencies(std::ostream& os, const int depth = -1, std::string space = "", std::ostream &displayDependencies(std::ostream &os, const int depth = -1,
std::string next1 = "", std::string next2 = "") const { std::string space = "",
return TimeDependency<Time>::displayDependencies(os, depth, space, next1, next2); std::string next1 = "",
std::string next2 = "") const {
return TimeDependency<Time>::displayDependencies(os, depth, space, next1,
next2);
} }
virtual bool needUpdate(const Time& t) const; virtual bool needUpdate(const Time &t) const;
virtual void setPeriodTime(const Time& p); virtual void setPeriodTime(const Time &p);
virtual Time getPeriodTime() const; virtual Time getPeriodTime() const;
}; };
...@@ -54,26 +103,28 @@ SignalTimeDependent<T, Time>::SignalTimeDependent(std::string name) ...@@ -54,26 +103,28 @@ SignalTimeDependent<T, Time>::SignalTimeDependent(std::string name)
: Signal<T, Time>(name), TimeDependency<Time>(this) {} : Signal<T, Time>(name), TimeDependency<Time>(this) {}
template <class T, class Time> template <class T, class Time>
SignalTimeDependent<T, Time>::SignalTimeDependent(const SignalArray_const<Time>& arr, std::string name) SignalTimeDependent<T, Time>::SignalTimeDependent(
const SignalArray_const<Time> &arr, std::string name)
: Signal<T, Time>(name), TimeDependency<Time>(this, arr) {} : Signal<T, Time>(name), TimeDependency<Time>(this, arr) {}
template <class T, class Time> template <class T, class Time>
SignalTimeDependent<T, Time>::SignalTimeDependent(boost::function2<T&, T&, Time> t, const SignalArray_const<Time>& sig, SignalTimeDependent<T, Time>::SignalTimeDependent(
std::string name) boost::function2<T &, T &, Time> t, const SignalArray_const<Time> &sig,
std::string name)
: Signal<T, Time>(name), TimeDependency<Time>(this, sig) { : Signal<T, Time>(name), TimeDependency<Time>(this, sig) {
this->setFunction(t); this->setFunction(t);
} }
template <class T, class Time> template <class T, class Time>
const T& SignalTimeDependent<T, Time>::access(const Time& t1) { const T &SignalTimeDependent<T, Time>::access(const Time &t1) {
const bool up = TimeDependency<Time>::needUpdate(t1); const bool up = TimeDependency<Time>::needUpdate(t1);
// SignalBase<Time>::setReady(false); // SignalBase<Time>::setReady(false);
/* std::cout << "Time before: "<< signalTime << " -- " */ /* std::cout << "Time before: "<< signalTime << " -- " */
/* << t1<< " -> Up: "<<up <<std::endl ; */ /* << t1<< " -> Up: "<<up <<std::endl ; */
if (up) { if (up) {
TimeDependency<Time>::lastAskForUpdate = false; TimeDependency<Time>::lastAskForUpdate = false;
const T& Tres = Signal<T, Time>::access(t1); const T &Tres = Signal<T, Time>::access(t1);
SignalBase<Time>::setReady(false); SignalBase<Time>::setReady(false);
return Tres; return Tres;
} else { } else {
...@@ -82,12 +133,14 @@ const T& SignalTimeDependent<T, Time>::access(const Time& t1) { ...@@ -82,12 +133,14 @@ const T& SignalTimeDependent<T, Time>::access(const Time& t1) {
} }
template <class T, class Time> template <class T, class Time>
void SignalTimeDependent<T, Time>::addDependency(const SignalBase<Time>& signal) { void SignalTimeDependent<T, Time>::addDependency(
const SignalBase<Time> &signal) {
TimeDependency<Time>::addDependency(signal); TimeDependency<Time>::addDependency(signal);
} }
template <class T, class Time> template <class T, class Time>
void SignalTimeDependent<T, Time>::removeDependency(const SignalBase<Time>& signal) { void SignalTimeDependent<T, Time>::removeDependency(
const SignalBase<Time> &signal) {
TimeDependency<Time>::removeDependency(signal); TimeDependency<Time>::removeDependency(signal);
} }
...@@ -97,12 +150,12 @@ void SignalTimeDependent<T, Time>::clearDependencies() { ...@@ -97,12 +150,12 @@ void SignalTimeDependent<T, Time>::clearDependencies() {
} }
template <class T, class Time> template <class T, class Time>
bool SignalTimeDependent<T, Time>::needUpdate(const Time& t) const { bool SignalTimeDependent<T, Time>::needUpdate(const Time &t) const {
return TimeDependency<Time>::needUpdate(t); return TimeDependency<Time>::needUpdate(t);
} }
template <class T, class Time> template <class T, class Time>
void SignalTimeDependent<T, Time>::setPeriodTime(const Time& p) { void SignalTimeDependent<T, Time>::setPeriodTime(const Time &p) {
TimeDependency<Time>::setPeriodTime(p); TimeDependency<Time>::setPeriodTime(p);
} }
template <class T, class Time> template <class T, class Time>
......
...@@ -10,14 +10,13 @@ ...@@ -10,14 +10,13 @@
#ifndef __SIGNAL_HH #ifndef __SIGNAL_HH
#define __SIGNAL_HH #define __SIGNAL_HH
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/signal-base.h>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>
#include <string> #include <string>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/signal-base.h>
#ifdef HAVE_LIBBOOST_THREAD #ifdef HAVE_LIBBOOST_THREAD
#include <boost/thread.hpp> #include <boost/thread.hpp>
#endif #endif
...@@ -33,11 +32,11 @@ namespace dynamicgraph { ...@@ -33,11 +32,11 @@ namespace dynamicgraph {
There are several ways to specify the value output by a signal: 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 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, \li using the function setReference(mutex, T*) to set the value
whose access is restricted by a mutex; from a pointer, whose access is restricted by a mutex;
\li using the function setFunction(boost::function2) that will be called when the \li using the function setFunction(boost::function2) that will be called
signal's value is accessed. when the signal's value is accessed.
*/ */
template <class T, class Time> template <class T, class Time>
class Signal : public SignalBase<Time> { class Signal : public SignalBase<Time> {
protected: protected:
...@@ -46,12 +45,12 @@ class Signal : public SignalBase<Time> { ...@@ -46,12 +45,12 @@ class Signal : public SignalBase<Time> {
SignalType signalType; SignalType signalType;
T Tcopy1, Tcopy2; T Tcopy1, Tcopy2;
T* Tcopy; T *Tcopy;
bool copyInit; bool copyInit;
const T* Treference; const T *Treference;
T* TreferenceNonConst; T *TreferenceNonConst;
boost::function2<T&, T&, Time> Tfunction; boost::function2<T &, T &, Time> Tfunction;
bool keepReference; bool keepReference;
const static bool KEEP_REFERENCE_DEFAULT = false; const static bool KEEP_REFERENCE_DEFAULT = false;
...@@ -61,12 +60,12 @@ class Signal : public SignalBase<Time> { ...@@ -61,12 +60,12 @@ class Signal : public SignalBase<Time> {
typedef boost::try_mutex Mutex; typedef boost::try_mutex Mutex;
typedef boost::lock_error MutexError; typedef boost::lock_error MutexError;
#else #else
typedef int* Mutex; typedef int *Mutex;
typedef int* MutexError; typedef int *MutexError;
#endif #endif
protected: protected:
Mutex* providerMutex; Mutex *providerMutex;
using SignalBase<Time>::signalTime; using SignalBase<Time>::signalTime;
public: public:
...@@ -78,40 +77,45 @@ class Signal : public SignalBase<Time> { ...@@ -78,40 +77,45 @@ class Signal : public SignalBase<Time> {
virtual ~Signal() {} virtual ~Signal() {}
/* --- Generic In/Out function --- */ /* --- Generic In/Out function --- */
virtual void get(std::ostream& value) const; virtual void get(std::ostream &value) const;
virtual void set(std::istringstream& value); virtual void set(std::istringstream &value);
virtual void trace(std::ostream& os) const; virtual void trace(std::ostream &os) const;
/* --- Generic Set function --- */ /* --- Generic Set function --- */
virtual void setConstant(const T& t); virtual void setConstant(const T &t);
virtual void setReference(const T* t, Mutex* mutexref = NULL); virtual void setReference(const T *t, Mutex *mutexref = NULL);
virtual void setReferenceNonConstant(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 setFunction(boost::function2<T &, T &, Time> t,
Mutex *mutexref = NULL);
inline bool getKeepReference() { return keepReference; } inline bool getKeepReference() { return keepReference; }
inline void setKeepReference(const bool& b) { keepReference = b; } inline void setKeepReference(const bool &b) { keepReference = b; }
/* --- Signal computation --- */ /* --- Signal computation --- */
virtual const T& access(const Time& t); virtual const T &access(const Time &t);
virtual inline void recompute(const Time& t) { access(t); } virtual inline void recompute(const Time &t) { access(t); }
virtual const T& accessCopy() const; virtual const T &accessCopy() const;
virtual std::ostream& display(std::ostream& os) const; virtual std::ostream &display(std::ostream &os) const;
/* --- Operators --- */ /* --- Operators --- */
virtual inline const T& operator()(const Time& t) { return access(t); } virtual inline const T &operator()(const Time &t) { return access(t); }
virtual Signal<T, Time>& operator=(const T& t); virtual Signal<T, Time> &operator=(const T &t);
inline operator const T&() const { return accessCopy(); } inline operator const T &() const { return accessCopy(); }
virtual void getClassName(std::string& aClassName) const { aClassName = typeid(this).name(); } virtual void getClassName(std::string &aClassName) const {
aClassName = typeid(this).name();
}
public: public:
/// 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; } virtual void checkCompatibility() { throw Tcopy; }
private: private:
const T& setTcopy(const T& t); const T &setTcopy(const T &t);
T& getTwork(); T &getTwork();
const T& getTwork() const; const T &getTwork() const;
const T& switchTcopy(); const T &switchTcopy();
}; };
} // end of namespace dynamicgraph } // end of namespace dynamicgraph
......
...@@ -5,51 +5,55 @@ ...@@ -5,51 +5,55 @@
#ifndef DYNAMIC_GRAPH_SIGNAL_T_CPP #ifndef DYNAMIC_GRAPH_SIGNAL_T_CPP
#define DYNAMIC_GRAPH_SIGNAL_T_CPP #define DYNAMIC_GRAPH_SIGNAL_T_CPP
#include <dynamic-graph/signal.h>
#include <dynamic-graph/signal-caster.h> #include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/signal.h>
#undef VP_TEMPLATE_DEBUG_MODE #undef VP_TEMPLATE_DEBUG_MODE
#define VP_TEMPLATE_DEBUG_MODE 0 #define VP_TEMPLATE_DEBUG_MODE 0
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#define __SIGNAL_INIT(name, Tcpy, Tref, TrefNC, mutex) \ #define __SIGNAL_INIT(name, Tcpy, Tref, TrefNC, mutex) \
SignalBase<Time>(name), signalType(SIGNAL_TYPE_DEFAULT), Tcopy1(Tcpy), Tcopy2(Tcpy), Tcopy(&Tcopy1), \ SignalBase<Time>(name), signalType(SIGNAL_TYPE_DEFAULT), Tcopy1(Tcpy), \
Treference(Tref), TreferenceNonConst(TrefNC), Tfunction(), keepReference(KEEP_REFERENCE_DEFAULT), \ Tcopy2(Tcpy), Tcopy(&Tcopy1), Treference(Tref), \
providerMutex(mutex) TreferenceNonConst(TrefNC), Tfunction(), \
keepReference(KEEP_REFERENCE_DEFAULT), providerMutex(mutex)
namespace dynamicgraph { namespace dynamicgraph {
template <class T, class Time> template <class T, class Time>
Signal<T, Time>::Signal(std::string name) : __SIGNAL_INIT(name, T(), NULL, NULL, NULL) { Signal<T, Time>::Signal(std::string name)
: __SIGNAL_INIT(name, T(), NULL, NULL, NULL) {
return; return;
} }
/* -------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------ */
template <class T, class Time> template <class T, class Time>
void Signal<T, Time>::set(std::istringstream& stringValue) { void Signal<T, Time>::set(std::istringstream &stringValue) {
(*this) = signal_cast<T>(stringValue); (*this) = signal_io<T>::cast(stringValue);
} }
template <class T, class Time> template <class T, class Time>
void Signal<T, Time>::get(std::ostream& os) const { void Signal<T, Time>::get(std::ostream &os) const {
signal_disp<T>(this->accessCopy(), os); signal_io<T>::disp(this->accessCopy(), os);
} }
template <class T, class Time> template <class T, class Time>
void Signal<T, Time>::trace(std::ostream& os) const { void Signal<T, Time>::trace(std::ostream &os) const {
try { try {
signal_trace<T>(this->accessCopy(), os); signal_io<T>::trace(this->accessCopy(), os);
} catch DG_RETHROW catch (...) { } catch DG_RETHROW catch (...) {
DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "TRACE operation not possible with this signal. ", DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE,
"(bad cast while getting value from %s).", SignalBase<Time>::getName().c_str()); "TRACE operation not possible with this signal. ",
"(bad cast while getting value from %s).",
SignalBase<Time>::getName().c_str());
} }
} }
/* -------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------ */
template <class T, class Time> template <class T, class Time>
const T& Signal<T, Time>::setTcopy(const T& t) { const T &Signal<T, Time>::setTcopy(const T &t) {
if (Tcopy == &Tcopy1) { if (Tcopy == &Tcopy1) {
Tcopy2 = t; Tcopy2 = t;
copyInit = true; copyInit = true;
...@@ -64,7 +68,7 @@ const T& Signal<T, Time>::setTcopy(const T& t) { ...@@ -64,7 +68,7 @@ const T& Signal<T, Time>::setTcopy(const T& t) {
} }
template <class T, class Time> template <class T, class Time>
T& Signal<T, Time>::getTwork() { T &Signal<T, Time>::getTwork() {
if (Tcopy == &Tcopy1) if (Tcopy == &Tcopy1)
return Tcopy2; return Tcopy2;
else else
...@@ -72,7 +76,7 @@ T& Signal<T, Time>::getTwork() { ...@@ -72,7 +76,7 @@ T& Signal<T, Time>::getTwork() {
} }
template <class T, class Time> template <class T, class Time>
const T& Signal<T, Time>::getTwork() const { const T &Signal<T, Time>::getTwork() const {
if (Tcopy == &Tcopy1) if (Tcopy == &Tcopy1)
return Tcopy2; return Tcopy2;
else else
...@@ -80,7 +84,7 @@ const T& Signal<T, Time>::getTwork() const { ...@@ -80,7 +84,7 @@ const T& Signal<T, Time>::getTwork() const {
} }
template <class T, class Time> template <class T, class Time>
const T& Signal<T, Time>::switchTcopy() { const T &Signal<T, Time>::switchTcopy() {
if (Tcopy == &Tcopy1) { if (Tcopy == &Tcopy1) {
Tcopy = &Tcopy2; Tcopy = &Tcopy2;
return Tcopy2; return Tcopy2;
...@@ -91,14 +95,14 @@ const T& Signal<T, Time>::switchTcopy() { ...@@ -91,14 +95,14 @@ const T& Signal<T, Time>::switchTcopy() {
} }
template <class T, class Time> template <class T, class Time>
void Signal<T, Time>::setConstant(const T& t) { void Signal<T, Time>::setConstant(const T &t) {
signalType = CONSTANT; signalType = CONSTANT;
setTcopy(t); setTcopy(t);
setReady(); setReady();
} }
template <class T, class Time> template <class T, class Time>
void Signal<T, Time>::setReference(const T* t, Mutex* mutexref) { void Signal<T, Time>::setReference(const T *t, Mutex *mutexref) {
signalType = REFERENCE; signalType = REFERENCE;
Treference = t; Treference = t;
providerMutex = mutexref; providerMutex = mutexref;
...@@ -107,7 +111,7 @@ void Signal<T, Time>::setReference(const T* t, Mutex* mutexref) { ...@@ -107,7 +111,7 @@ void Signal<T, Time>::setReference(const T* t, Mutex* mutexref) {
} }
template <class T, class Time> template <class T, class Time>
void Signal<T, Time>::setReferenceNonConstant(T* t, Mutex* mutexref) { void Signal<T, Time>::setReferenceNonConstant(T *t, Mutex *mutexref) {
signalType = REFERENCE_NON_CONST; signalType = REFERENCE_NON_CONST;
Treference = t; Treference = t;
TreferenceNonConst = t; TreferenceNonConst = t;
...@@ -117,7 +121,8 @@ void Signal<T, Time>::setReferenceNonConstant(T* t, Mutex* mutexref) { ...@@ -117,7 +121,8 @@ void Signal<T, Time>::setReferenceNonConstant(T* t, Mutex* mutexref) {
} }
template <class T, class Time> template <class T, class Time>
void Signal<T, Time>::setFunction(boost::function2<T&, T&, Time> t, Mutex* mutexref) { void Signal<T, Time>::setFunction(boost::function2<T &, T &, Time> t,
Mutex *mutexref) {
signalType = FUNCTION; signalType = FUNCTION;
Tfunction = t; Tfunction = t;
providerMutex = mutexref; providerMutex = mutexref;
...@@ -126,13 +131,12 @@ void Signal<T, Time>::setFunction(boost::function2<T&, T&, Time> t, Mutex* mutex ...@@ -126,13 +131,12 @@ void Signal<T, Time>::setFunction(boost::function2<T&, T&, Time> t, Mutex* mutex
} }
template <class T, class Time> template <class T, class Time>
const T& Signal<T, Time>::accessCopy() const { const T &Signal<T, Time>::accessCopy() const {
return *Tcopy; return *Tcopy;
} }
template <class T, class Time> template <class T, class Time>
const T& Signal<T, Time>::access(const Time& t) { const T &Signal<T, Time>::access(const Time &t) {
// dgTDEBUG(20) << "# In (" << SignalBase<Time>::name <<")"<<std::endl;
switch (signalType) { switch (signalType) {
case REFERENCE: case REFERENCE:
case REFERENCE_NON_CONST: { case REFERENCE_NON_CONST: {
...@@ -148,7 +152,7 @@ const T& Signal<T, Time>::access(const Time& t) { ...@@ -148,7 +152,7 @@ const T& Signal<T, Time>::access(const Time& t) {
copyInit = true; copyInit = true;
signalTime = t; signalTime = t;
return setTcopy(*Treference); return setTcopy(*Treference);
} catch (const MutexError&) { } catch (const MutexError &) {
return accessCopy(); return accessCopy();
} }
} }
...@@ -171,7 +175,7 @@ const T& Signal<T, Time>::access(const Time& t) { ...@@ -171,7 +175,7 @@ const T& Signal<T, Time>::access(const Time& t) {
Tfunction(getTwork(), t); Tfunction(getTwork(), t);
copyInit = true; copyInit = true;
return switchTcopy(); return switchTcopy();
} catch (const MutexError&) { } catch (const MutexError &) {
return accessCopy(); return accessCopy();
} }
} }
...@@ -188,8 +192,9 @@ const T& Signal<T, Time>::access(const Time& t) { ...@@ -188,8 +192,9 @@ const T& Signal<T, Time>::access(const Time& t) {
} }
template <class T, class Time> template <class T, class Time>
Signal<T, Time>& Signal<T, Time>::operator=(const T& t) { Signal<T, Time> &Signal<T, Time>::operator=(const T &t) {
if (keepReference && (REFERENCE_NON_CONST == signalType) && (NULL != TreferenceNonConst)) { if (keepReference && (REFERENCE_NON_CONST == signalType) &&
(NULL != TreferenceNonConst)) {
if (NULL == providerMutex) { if (NULL == providerMutex) {
setTcopy(t); setTcopy(t);
(*TreferenceNonConst) = t; (*TreferenceNonConst) = t;
...@@ -200,7 +205,7 @@ Signal<T, Time>& Signal<T, Time>::operator=(const T& t) { ...@@ -200,7 +205,7 @@ Signal<T, Time>& Signal<T, Time>::operator=(const T& t) {
#endif #endif
setTcopy(t); setTcopy(t);
(*TreferenceNonConst) = t; (*TreferenceNonConst) = t;
} catch (const MutexError&) { /* TODO ERROR */ } catch (const MutexError &) { /* TODO ERROR */
} }
} }
} else { } else {
...@@ -210,7 +215,7 @@ Signal<T, Time>& Signal<T, Time>::operator=(const T& t) { ...@@ -210,7 +215,7 @@ Signal<T, Time>& Signal<T, Time>::operator=(const T& t) {
} }
template <class T, class Time> template <class T, class Time>
std::ostream& Signal<T, Time>::display(std::ostream& os) const { std::ostream &Signal<T, Time>::display(std::ostream &os) const {
os << "Sig:" << this->name << " (Type "; os << "Sig:" << this->name << " (Type ";
switch (this->signalType) { switch (this->signalType) {
case Signal<T, Time>::CONSTANT: case Signal<T, Time>::CONSTANT:
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
#ifndef DYNAMIC_GRAPH_TIME_DEPENDENCY_H #ifndef DYNAMIC_GRAPH_TIME_DEPENDENCY_H
#define DYNAMIC_GRAPH_TIME_DEPENDENCY_H #define DYNAMIC_GRAPH_TIME_DEPENDENCY_H
#include <list> #include <dynamic-graph/signal-array.h>
#include <dynamic-graph/signal-base.h>
#include <dynamic-graph/fwd.hh> #include <dynamic-graph/fwd.hh>
#include <dynamic-graph/signal-base.h> #include <list>
#include <dynamic-graph/signal-array.h>
namespace dynamicgraph { namespace dynamicgraph {
/** \brief A helper class for setting and specifying dependencies /** \brief A helper class for setting and specifying dependencies
...@@ -23,9 +23,9 @@ class TimeDependency { ...@@ -23,9 +23,9 @@ class TimeDependency {
mutable Time lastAskForUpdate; mutable Time lastAskForUpdate;
public: public:
SignalBase<Time>& leader; SignalBase<Time> &leader;
typedef std::list<const SignalBase<Time>*> Dependencies; typedef std::list<const SignalBase<Time> *> Dependencies;
static const DependencyType DEPENDENCY_TYPE_DEFAULT = TIME_DEPENDENT; static const DependencyType DEPENDENCY_TYPE_DEFAULT = TIME_DEPENDENT;
Dependencies dependencies; Dependencies dependencies;
...@@ -38,27 +38,33 @@ class TimeDependency { ...@@ -38,27 +38,33 @@ class TimeDependency {
static const Time PERIOD_TIME_DEFAULT = 1; static const Time PERIOD_TIME_DEFAULT = 1;
public: public:
TimeDependency(SignalBase<Time>* sig, const DependencyType dep = DEPENDENCY_TYPE_DEFAULT); TimeDependency(SignalBase<Time> *sig,
TimeDependency(SignalBase<Time>* sig, const SignalArray_const<Time>& arr, const DependencyType dep = DEPENDENCY_TYPE_DEFAULT);
TimeDependency(SignalBase<Time> *sig, const SignalArray_const<Time> &arr,
const DependencyType dep = DEPENDENCY_TYPE_DEFAULT); const DependencyType dep = DEPENDENCY_TYPE_DEFAULT);
virtual ~TimeDependency() {} virtual ~TimeDependency() {}
void addDependency(const SignalBase<Time>& sig); void addDependencies(const SignalArray_const<Time> &arr);
void removeDependency(const SignalBase<Time>& sig); void addDependency(const SignalBase<Time> &sig);
void removeDependency(const SignalBase<Time> &sig);
void clearDependency(); void clearDependency();
virtual std::ostream& writeGraph(std::ostream& os) const; virtual std::ostream &writeGraph(std::ostream &os) const;
std::ostream& displayDependencies(std::ostream& os, const int depth = -1, std::string space = "", std::ostream &displayDependencies(std::ostream &os, const int depth = -1,
std::string next1 = "", std::string next2 = "") const; std::string space = "",
std::string next1 = "",
std::string next2 = "") const;
bool needUpdate(const Time& t1) const; bool needUpdate(const Time &t1) const;
void setDependencyType(DependencyType dep) { dependencyType = dep; } void setDependencyType(DependencyType dep) { dependencyType = dep; }
void setNeedUpdateFromAllChildren(const bool b = true) { updateFromAllChildren = b; } void setNeedUpdateFromAllChildren(const bool b = true) {
updateFromAllChildren = b;
}
bool getNeedUpdateFromAllChildren() const { return updateFromAllChildren; } bool getNeedUpdateFromAllChildren() const { return updateFromAllChildren; }
void setPeriodTime(const Time& p) { periodTime = p; } void setPeriodTime(const Time &p) { periodTime = p; }
Time getPeriodTime() const { return periodTime; } Time getPeriodTime() const { return periodTime; }
}; };
......
...@@ -11,45 +11,53 @@ ...@@ -11,45 +11,53 @@
#define VP_TEMPLATE_DEBUG_MODE 0 #define VP_TEMPLATE_DEBUG_MODE 0
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#define __TIME_DEPENDENCY_INIT(sig, dep) \ #define __TIME_DEPENDENCY_INIT(sig, dep) \
leader(*sig), dependencies(), updateFromAllChildren(ALL_READY_DEFAULT), dependencyType(dep), \ leader(*sig), dependencies(), updateFromAllChildren(ALL_READY_DEFAULT), \
periodTime(PERIOD_TIME_DEFAULT) dependencyType(dep), periodTime(PERIOD_TIME_DEFAULT)
namespace dynamicgraph { namespace dynamicgraph {
template <class Time> template <class Time>
TimeDependency<Time>::TimeDependency(SignalBase<Time>* sig, const DependencyType dep) TimeDependency<Time>::TimeDependency(SignalBase<Time> *sig,
const DependencyType dep)
: __TIME_DEPENDENCY_INIT(sig, dep) {} : __TIME_DEPENDENCY_INIT(sig, dep) {}
template <class Time> template <class Time>
TimeDependency<Time>::TimeDependency(SignalBase<Time>* sig, const SignalArray_const<Time>& ar, TimeDependency<Time>::TimeDependency(SignalBase<Time> *sig,
const SignalArray_const<Time> &ar,
const DependencyType dep) const DependencyType dep)
: __TIME_DEPENDENCY_INIT(sig, 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) { for (unsigned int i = 0; i < ar.getSize(); ++i) {
addDependency(ar[i]); addDependency(ar[i]);
} }
return;
} }
/* -------------------------------------------------------------------------- */
template <class Time> template <class Time>
void TimeDependency<Time>::addDependency(const SignalBase<Time>& sig) { void TimeDependency<Time>::addDependency(const SignalBase<Time> &sig) {
dependencies.push_front(&sig); dependencies.push_front(&sig);
} }
template <class Time> template <class Time>
void TimeDependency<Time>::removeDependency(const SignalBase<Time>& sig) { void TimeDependency<Time>::removeDependency(const SignalBase<Time> &sig) {
dependencies.remove(&sig); dependencies.remove(&sig);
} }
template <class Time> template <class Time>
void TimeDependency<Time>::clearDependency() { void TimeDependency<Time>::clearDependency() {
dependencies.clear(); dependencies.clear();
} }
template <class Time> template <class Time>
bool TimeDependency<Time>::needUpdate(const Time& t1) const { bool TimeDependency<Time>::needUpdate(const Time &t1) const {
dgTDEBUG(15) << "# In {" << leader.getName() << " : (" << leader.getReady() << ") " << t1 << " >? " dgTDEBUG(15) << "# In {" << leader.getName() << " : (" << leader.getReady()
<< leader.getTime() << std::endl; << ") " << t1 << " >? " << leader.getTime() << std::endl;
if (leader.getReady()) { if (leader.getReady()) {
dgTDEBUGOUT(15); dgTDEBUGOUT(15);
...@@ -78,8 +86,9 @@ bool TimeDependency<Time>::needUpdate(const Time& t1) const { ...@@ -78,8 +86,9 @@ bool TimeDependency<Time>::needUpdate(const Time& t1) const {
bool res = updateFromAllChildren; bool res = updateFromAllChildren;
const typename Dependencies::const_iterator itend = dependencies.end(); const typename Dependencies::const_iterator itend = dependencies.end();
for (typename Dependencies::const_iterator it = dependencies.begin(); it != itend; ++it) { for (typename Dependencies::const_iterator it = dependencies.begin();
const SignalBase<Time>& sig = **it; it != itend; ++it) {
const SignalBase<Time> &sig = **it;
dgTDEBUG(15) << "Ask update for " << sig << std::endl; dgTDEBUG(15) << "Ask update for " << sig << std::endl;
if ((sig.getTime() > leader.getTime()) || (sig.needUpdate(t1))) { if ((sig.getTime() > leader.getTime()) || (sig.needUpdate(t1))) {
...@@ -104,26 +113,16 @@ bool TimeDependency<Time>::needUpdate(const Time& t1) const { ...@@ -104,26 +113,16 @@ bool TimeDependency<Time>::needUpdate(const Time& t1) const {
} }
template <class Time> template <class Time>
std::ostream& TimeDependency<Time>::writeGraph(std::ostream& os) const { 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;
}
}
return os; return os;
} }
template <class Time> template <class Time>
std::ostream& TimeDependency<Time>::displayDependencies(std::ostream& os, const int depth, std::string space, std::ostream &TimeDependency<Time>::displayDependencies(
std::string next1, std::string next2) const { std::ostream &os, const int depth, std::string space, std::string next1,
leader.SignalBase<Time>::displayDependencies(os, depth, space, next1, next2) << " ("; std::string next2) const {
leader.SignalBase<Time>::displayDependencies(os, depth, space, next1, next2)
<< " (";
switch (dependencyType) { switch (dependencyType) {
case ALWAYS_READY: case ALWAYS_READY:
os << "A"; os << "A";
...@@ -138,18 +137,20 @@ std::ostream& TimeDependency<Time>::displayDependencies(std::ostream& os, const ...@@ -138,18 +137,20 @@ std::ostream& TimeDependency<Time>::displayDependencies(std::ostream& os, const
os << ")"; //<<std::endl; os << ")"; //<<std::endl;
{ {
const typename Dependencies::const_iterator itend = dependencies.end(); const typename Dependencies::const_iterator itend = dependencies.end();
for (typename Dependencies::const_iterator it = dependencies.begin(); it != itend; ++it) for (typename Dependencies::const_iterator it = dependencies.begin();
it != itend; ++it)
if (depth != 0) { if (depth != 0) {
os << std::endl; os << std::endl;
std::string ajout = "|"; std::string ajout = "|";
std::string ajout2 = "|"; std::string ajout2 = "|";
typename Dependencies::const_iterator it2 = it; typename Dependencies::const_iterator it2 = it;
it2++; ++it2;
if (it2 == dependencies.end()) { if (it2 == dependencies.end()) {
ajout = "`"; ajout = "`";
ajout2 = " "; ajout2 = " ";
} }
(*it)->displayDependencies(os, depth - 1, space + next2 + " ", ajout, ajout2); (*it)->displayDependencies(os, depth - 1, space + next2 + " ", ajout,
ajout2);
} else { } else {
os << std::endl << space << " `-- ..."; os << std::endl << space << " `-- ...";
break; break;
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
#ifndef DYNAMIC_GRAPH_TRACER_REAL_TIME_H #ifndef DYNAMIC_GRAPH_TRACER_REAL_TIME_H
#define 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/tracer.h>
#include <dynamic-graph/config-tracer-real-time.hh> #include <dynamic-graph/config-tracer-real-time.hh>
#include <dynamic-graph/fwd.hh>
#include <sstream>
namespace dynamicgraph { namespace dynamicgraph {
/// \ingroup plugin /// \ingroup plugin
...@@ -17,7 +17,7 @@ namespace dynamicgraph { ...@@ -17,7 +17,7 @@ namespace dynamicgraph {
/// \brief Stream for the tracer real-time. /// \brief Stream for the tracer real-time.
class DG_TRACERREALTIME_DLLAPI OutStringStream : public std::ostringstream { class DG_TRACERREALTIME_DLLAPI OutStringStream : public std::ostringstream {
public: public:
char* buffer; char *buffer;
std::streamsize index; std::streamsize index;
std::streamsize bufferSize; std::streamsize bufferSize;
bool full; bool full;
...@@ -27,9 +27,9 @@ class DG_TRACERREALTIME_DLLAPI OutStringStream : public std::ostringstream { ...@@ -27,9 +27,9 @@ class DG_TRACERREALTIME_DLLAPI OutStringStream : public std::ostringstream {
OutStringStream(); OutStringStream();
~OutStringStream(); ~OutStringStream();
void resize(const std::streamsize& size); void resize(const std::streamsize &size);
bool addData(const char* data, const std::streamoff& size); bool addData(const char *data, const std::streamoff &size);
void dump(std::ostream& os); void dump(std::ostream &os);
void empty(); void empty();
}; };
...@@ -40,26 +40,29 @@ class DG_TRACERREALTIME_DLLAPI TracerRealTime : public Tracer { ...@@ -40,26 +40,29 @@ class DG_TRACERREALTIME_DLLAPI TracerRealTime : public Tracer {
DYNAMIC_GRAPH_ENTITY_DECL(); DYNAMIC_GRAPH_ENTITY_DECL();
public: public:
TracerRealTime(const std::string& n); TracerRealTime(const std::string &n);
virtual ~TracerRealTime() {} virtual ~TracerRealTime() {}
virtual void closeFiles(); virtual void closeFiles();
virtual void trace(); virtual void trace();
void display(std::ostream& os) const; void display(std::ostream &os) const;
DG_TRACERREALTIME_DLLAPI friend std::ostream& operator<<(std::ostream& os, const TracerRealTime& t); 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 emptyBuffers();
void setBufferSize(const int& SIZE) { bufferSize = SIZE; } void setBufferSize(const int &SIZE) { bufferSize = SIZE; }
const int &getBufferSize() { return bufferSize; }
protected:
virtual void openFile(const SignalBase<int> &sig,
const std::string &filename);
const int& getBufferSize() { return bufferSize; } virtual void recordSignal(std::ostream &os, const SignalBase<int> &sig);
typedef std::list<std::ofstream*> HardFileList; typedef std::list<std::ofstream *> HardFileList;
static const int BUFFER_SIZE_DEFAULT = 1048576; // 1Mo static const int BUFFER_SIZE_DEFAULT = 1048576; // 1Mo
int bufferSize; int bufferSize;
......
...@@ -5,17 +5,17 @@ ...@@ -5,17 +5,17 @@
#ifndef DYNAMIC_GRAPH_TRACER_H #ifndef DYNAMIC_GRAPH_TRACER_H
#define DYNAMIC_GRAPH_TRACER_H #define DYNAMIC_GRAPH_TRACER_H
#include <string> #include <dynamic-graph/entity.h>
#include <list> #include <dynamic-graph/exception-traces.h>
#include <boost/function.hpp>
#include <dynamic-graph/signal-base.h> #include <dynamic-graph/signal-base.h>
#include <dynamic-graph/signal-time-dependent.h> #include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/time-dependency.h> #include <dynamic-graph/time-dependency.h>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/exception-traces.h>
#include <boost/function.hpp>
#include <dynamic-graph/config-tracer.hh> #include <dynamic-graph/config-tracer.hh>
#include <list>
#include <mutex>
#include <string>
namespace dynamicgraph { namespace dynamicgraph {
/// \ingroup plugin /// \ingroup plugin
...@@ -25,16 +25,20 @@ class DG_TRACER_DLLAPI Tracer : public Entity { ...@@ -25,16 +25,20 @@ class DG_TRACER_DLLAPI Tracer : public Entity {
DYNAMIC_GRAPH_ENTITY_DECL(); DYNAMIC_GRAPH_ENTITY_DECL();
protected: protected:
typedef std::list<const SignalBase<int>*> SignalList; typedef std::list<const SignalBase<int> *> SignalList;
SignalList toTraceSignals; SignalList toTraceSignals;
std::mutex files_mtx;
public: public:
enum TraceStyle { enum TraceStyle {
WHEN_SAID /// Record, then trace to file only when said to. WHEN_SAID
/// Record, then trace to file only when said to.
, ,
EACH_TIME /// Record and trace to file immediately. EACH_TIME
/// Record and trace to file immediately.
, ,
FREQUENTLY /// Record X time then trace (X is tuned by setFrenquence () ). FREQUENTLY
/// Record X time then trace (X is tuned by setFrenquence () ).
}; };
TraceStyle traceStyle; TraceStyle traceStyle;
static const TraceStyle TRACE_STYLE_DEFAULT = EACH_TIME; static const TraceStyle TRACE_STYLE_DEFAULT = EACH_TIME;
...@@ -44,7 +48,7 @@ class DG_TRACER_DLLAPI Tracer : public Entity { ...@@ -44,7 +48,7 @@ class DG_TRACER_DLLAPI Tracer : public Entity {
std::string suffix; std::string suffix;
std::string rootdir; std::string rootdir;
bool namesSet; bool namesSet;
typedef std::list<std::ostream*> FileList; typedef std::list<std::ostream *> FileList;
FileList files; FileList files;
typedef std::list<std::string> NameList; typedef std::list<std::string> NameList;
NameList names; NameList names;
...@@ -55,26 +59,30 @@ class DG_TRACER_DLLAPI Tracer : public Entity { ...@@ -55,26 +59,30 @@ class DG_TRACER_DLLAPI Tracer : public Entity {
Tracer(const std::string n); Tracer(const std::string n);
virtual ~Tracer() { closeFiles(); } virtual ~Tracer() { closeFiles(); }
void addSignalToTrace(const SignalBase<int>& sig, const std::string& filename = ""); void addSignalToTrace(const SignalBase<int> &sig,
void addSignalToTraceByName(const std::string& signame, const std::string& filename = ""); const std::string &filename = "");
void addSignalToTraceByName(const std::string &signame,
const std::string &filename = "");
void clearSignalToTrace(); void clearSignalToTrace();
// void parasite( SignalBase<int>& sig ); // void parasite( SignalBase<int>& sig );
void openFiles(const std::string& rootdir, const std::string& basename, const std::string& suffix); void openFiles(const std::string &rootdir, const std::string &basename,
const std::string &suffix);
virtual void closeFiles(); virtual void closeFiles();
protected: protected:
virtual void openFile(const SignalBase<int>& sig, const std::string& filename); virtual void openFile(const SignalBase<int> &sig,
const std::string &filename);
public: public:
void setTraceStyle(const TraceStyle& style) { traceStyle = style; } void setTraceStyle(const TraceStyle &style) { traceStyle = style; }
TraceStyle getTraceStyle() { return traceStyle; } TraceStyle getTraceStyle() { return traceStyle; }
void setFrenquency(const double& frqu) { frequency = frqu; } void setFrenquency(const double &frqu) { frequency = frqu; }
double getFrequency() { return frequency; } double getFrequency() { return frequency; }
void record(); void record();
virtual void recordSignal(std::ostream& os, const SignalBase<int>& sig); virtual void recordSignal(std::ostream &os, const SignalBase<int> &sig);
int& recordTrigger(int& dummy, const int& time); int &recordTrigger(int &dummy, const int &time);
virtual void trace(); virtual void trace();
void start() { play = true; } void start() { play = true; }
...@@ -84,11 +92,12 @@ class DG_TRACER_DLLAPI Tracer : public Entity { ...@@ -84,11 +92,12 @@ class DG_TRACER_DLLAPI Tracer : public Entity {
// SignalTrigerer<int> triger; // SignalTrigerer<int> triger;
SignalTimeDependent<int, int> triger; SignalTimeDependent<int, int> triger;
/* --- DISPLAY ------------------------------------------------------------ */ /* --- DISPLAY --------------------------------------------------------- */
DG_TRACER_DLLAPI friend std::ostream& operator<<(std::ostream& os, const Tracer& t); DG_TRACER_DLLAPI friend std::ostream &operator<<(std::ostream &os,
const Tracer &t);
/* --- PARAMS --- */ /* --- PARAMS --- */
void display(std::ostream& os) const; void display(std::ostream &os) const;
}; };
} // end of namespace dynamicgraph } // end of namespace dynamicgraph
......
...@@ -7,53 +7,86 @@ ...@@ -7,53 +7,86 @@
#ifndef DYNAMIC_GRAPH_VALUE_H #ifndef DYNAMIC_GRAPH_VALUE_H
#define DYNAMIC_GRAPH_VALUE_H #define DYNAMIC_GRAPH_VALUE_H
#include <string> #include <dynamic-graph/linear-algebra.h>
#include <cassert> #include <cassert>
#include <string>
#include <typeinfo> #include <typeinfo>
#include <vector>
#include "dynamic-graph/dynamic-graph-api.h" #include "dynamic-graph/dynamic-graph-api.h"
#include <dynamic-graph/linear-algebra.h>
namespace dynamicgraph { namespace dynamicgraph {
namespace command { namespace command {
class Value; class Value;
typedef std::vector<Value> Values;
class DYNAMIC_GRAPH_DLLAPI EitherType { class DYNAMIC_GRAPH_DLLAPI EitherType {
public: public:
EitherType(const Value& value); EitherType(const Value &value);
~EitherType(); ~EitherType();
operator bool() const; operator bool() const;
operator unsigned() const; operator unsigned() const;
operator unsigned long int() const;
operator int() const; operator int() const;
operator long int() const;
operator float() const; operator float() const;
operator double() const; operator double() const;
operator std::string() const; operator std::string() const;
operator Vector() const; operator Vector() const;
operator Eigen::MatrixXd() const; operator Eigen::MatrixXd() const;
operator Eigen::Matrix4d() const; operator Eigen::Matrix4d() const;
operator Values() const;
private: private:
const Value* value_; const Value *value_;
}; };
/** \ingroup dgraph
\brief This class implements a variant design pattern to handle basic types
in Command.
*/
class DYNAMIC_GRAPH_DLLAPI Value { class DYNAMIC_GRAPH_DLLAPI Value {
public: public:
enum Type { NONE, BOOL, UNSIGNED, INT, FLOAT, DOUBLE, STRING, VECTOR, MATRIX, MATRIX4D, NB_TYPES }; enum Type {
NONE,
BOOL,
UNSIGNED,
UNSIGNEDLONGINT,
INT,
LONGINT,
FLOAT,
DOUBLE,
STRING,
VECTOR,
MATRIX,
MATRIX4D,
VALUES,
NB_TYPES
};
~Value(); ~Value();
void deleteValue(); void deleteValue();
explicit Value(const bool& value); explicit Value(const bool &value);
explicit Value(const unsigned& value); explicit Value(const unsigned &value);
explicit Value(const int& value); explicit Value(const unsigned long int &value);
explicit Value(const float& value); explicit Value(const int &value);
explicit Value(const double& value); explicit Value(const long int &value);
explicit Value(const std::string& value); explicit Value(const float &value);
explicit Value(const Vector& value); explicit Value(const double &value);
explicit Value(const Eigen::MatrixXd& value); explicit Value(const std::string &value);
explicit Value(const Eigen::Matrix4d& value); explicit Value(const Vector &value);
explicit Value(const Eigen::MatrixXd &value);
explicit Value(const Eigen::Matrix4d &value);
explicit Value(const Values &value);
/// Copy constructor /// Copy constructor
Value(const Value& value); Value(const Value &value);
// Construct an empty value (None) // Construct an empty value (None)
explicit Value(); explicit Value();
// operator assignement // operator assignement
Value operator=(const Value& value); Value operator=(const Value &value);
// Equality operator
bool operator==(const Value &other) const;
/// Return the type of the value /// Return the type of the value
Type type() const; Type type() const;
...@@ -73,21 +106,26 @@ class DYNAMIC_GRAPH_DLLAPI Value { ...@@ -73,21 +106,26 @@ class DYNAMIC_GRAPH_DLLAPI Value {
static std::string typeName(Type type); static std::string typeName(Type type);
/// Output in a stream /// Output in a stream
DYNAMIC_GRAPH_DLLAPI friend std::ostream& operator<<(std::ostream& os, const Value& value); DYNAMIC_GRAPH_DLLAPI friend std::ostream &operator<<(std::ostream &os,
const Value &value);
public: public:
friend class EitherType; friend class EitherType;
bool boolValue() const; bool boolValue() const;
unsigned unsignedValue() const; unsigned unsignedValue() const;
unsigned long int unsignedlongintValue() const;
int intValue() const; int intValue() const;
long int longintValue() const;
float floatValue() const; float floatValue() const;
double doubleValue() const; double doubleValue() const;
std::string stringValue() const; std::string stringValue() const;
Vector vectorValue() const; Vector vectorValue() const;
Eigen::MatrixXd matrixXdValue() const; Eigen::MatrixXd matrixXdValue() const;
Eigen::Matrix4d matrix4dValue() const; Eigen::Matrix4d matrix4dValue() const;
Values valuesValue() const;
const Values &constValuesValue() const;
Type type_; Type type_;
const void* const value_; const void *const value_;
}; };
/* ---- HELPER ---------------------------------------------------------- */ /* ---- HELPER ---------------------------------------------------------- */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<script> <script>
function renderDOTFile() { function renderDOTFile() {
var fileInputElement = document.getElementById("fileInputElement"); var fileInputElement = document.getElementById("fileInputElement");
var reader = new FileReader(); var reader = new FileReader();
var graphtextres = "" var graphtextres = ""
reader.onloadend = function(e) { reader.onloadend = function(e) {
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
.catch(error => { .catch(error => {
// Create a new Viz instance (@see Caveats page for more info) // Create a new Viz instance (@see Caveats page for more info)
viz = new Viz(); viz = new Viz();
// Possibly display the error // Possibly display the error
console.error(error); console.error(error);
}); });
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
</script> </script>
<input type="file" id="fileInputElement"> <input type="file" id="fileInputElement">
<input id="Rendering" type="button" value="Rendering" onclick="renderDOTFile();" /> <input id="Rendering" type="button" value="Rendering" onclick="renderDOTFile();" />
<script> <script>
var el = document.getElementById("Rendering"); var el = document.getElementById("Rendering");
...@@ -49,4 +49,3 @@ ...@@ -49,4 +49,3 @@
</body> </body>
</html> </html>