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
Select Git revision

Target

Select target project
  • cberge/dynamic-graph
  • ostasse/dynamic-graph
  • gsaurel/dynamic-graph
  • stack-of-tasks/dynamic-graph
4 results
Select Git revision
Show changes
Showing
with 603 additions and 469 deletions
......@@ -7,13 +7,15 @@
#ifndef DYNAMIC_GRAPH_COMMAND_H
#define DYNAMIC_GRAPH_COMMAND_H
#include <vector>
#include "dynamic-graph/dynamic-graph-api.h"
#include "dynamic-graph/value.h"
#include <vector>
namespace dynamicgraph {
class Entity;
namespace command {
/// \ingroup dgraph
/// Abstract class for entity commands
///
/// This class provide a mean to control entities from external
......@@ -31,7 +33,7 @@ namespace command {
/// vector of Values the types of which should fit the vector specified
/// at construction.
class DYNAMIC_GRAPH_DLLAPI Command {
public:
public:
virtual ~Command();
/// Store the owner entity and a vector of value types
/// \param entity reference to Entity owning this command.
......@@ -52,20 +54,20 @@ public:
/// Get documentation string
std::string getDocstring() const;
protected:
protected:
/// Specific action performed by the command
virtual Value doExecute() = 0;
private:
private:
Entity &owner_;
std::vector<Value::Type> valueTypeVector_;
std::vector<Value> valueVector_;
std::string docstring_;
public:
public:
static const std::vector<Value::Type> EMPTY_ARG;
};
} // namespace command
} // namespace dynamicgraph
} // namespace command
} // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_COMMAND_H
#endif // DYNAMIC_GRAPH_COMMAND_H
......@@ -5,29 +5,29 @@
#ifndef DYNAMIC_GRAPH_DEBUG_HH
#define DYNAMIC_GRAPH_DEBUG_HH
#include <dynamic-graph/dynamic-graph-api.h>
#include <cstdarg>
#include <cstdio>
#include <dynamic-graph/fwd.hh>
#include <fstream>
#include <sstream>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/fwd.hh>
#ifndef VP_DEBUG_MODE
#define VP_DEBUG_MODE 0
#endif //! VP_DEBUG_MODE
#endif //! VP_DEBUG_MODE
#ifndef VP_TEMPLATE_DEBUG_MODE
#define VP_TEMPLATE_DEBUG_MODE 0
#endif //! VP_TEMPLATE_DEBUG_MODE
#define DG_COMMON_TRACES \
do { \
va_list arg; \
va_start(arg, format); \
vsnprintf(charbuffer, SIZE, format, arg); \
va_end(arg); \
outputbuffer << tmpbuffer.str() << charbuffer << std::endl; \
#endif //! VP_TEMPLATE_DEBUG_MODE
#define DG_COMMON_TRACES \
do { \
va_list arg; \
va_start(arg, format); \
vsnprintf(charbuffer, SIZE, format, arg); \
va_end(arg); \
outputbuffer << tmpbuffer.str() << charbuffer << std::endl; \
} while (0)
namespace dynamicgraph {
......@@ -38,7 +38,7 @@ namespace dynamicgraph {
/// This class should never be used directly, please use the
/// debugging macro instead.
class DYNAMIC_GRAPH_DLLAPI DebugTrace {
public:
public:
static const int SIZE = 512;
std::stringstream tmpbuffer;
......@@ -50,8 +50,7 @@ public:
DebugTrace(std::ostream &os) : outputbuffer(os) {}
inline void trace(const int level, const char *format, ...) {
if (level <= traceLevel)
DG_COMMON_TRACES;
if (level <= traceLevel) DG_COMMON_TRACES;
tmpbuffer.str("");
}
......@@ -68,8 +67,7 @@ public:
}
inline void traceTemplate(const int level, const char *format, ...) {
if (level <= traceLevelTemplate)
DG_COMMON_TRACES;
if (level <= traceLevelTemplate) DG_COMMON_TRACES;
tmpbuffer.str("");
}
......@@ -92,57 +90,57 @@ public:
DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgDEBUGFLOW;
DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgERRORFLOW;
} // end of namespace dynamicgraph
} // end of namespace dynamicgraph
#ifdef VP_DEBUG
#define dgPREDEBUG __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :"
#define dgPREERROR \
#define dgPREERROR \
"\t!! " << __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :"
#define dgDEBUG(level) \
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
#define dgDEBUG(level) \
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
dgDEBUGFLOW.outputbuffer << dgPREDEBUG
#define dgDEBUGMUTE(level) \
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
#define dgDEBUGMUTE(level) \
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
dgDEBUGFLOW.outputbuffer
#define dgERROR \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
#define dgERROR \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgERRORFLOW.outputbuffer << dgPREERROR
#define dgDEBUGF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
#define dgDEBUGF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgDEBUGFLOW.pre(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_DEBUG_MODE).trace
#define dgERRORF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
#define dgERRORF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgERRORFLOW.pre(dgERRORFLOW.tmpbuffer << dgPREERROR).trace
// TEMPLATE
#define dgTDEBUG(level) \
if ((level > VP_TEMPLATE_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
#define dgTDEBUG(level) \
if ((level > VP_TEMPLATE_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
dgDEBUGFLOW.outputbuffer << dgPREDEBUG
#define dgTDEBUGF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgDEBUGFLOW \
.pre(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_TEMPLATE_DEBUG_MODE) \
#define dgTDEBUGF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgDEBUGFLOW \
.pre(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_TEMPLATE_DEBUG_MODE) \
.trace
inline bool dgDEBUG_ENABLE(const int &level) { return level <= VP_DEBUG_MODE; }
......@@ -151,19 +149,19 @@ inline bool dgTDEBUG_ENABLE(const int &level) {
return level <= VP_TEMPLATE_DEBUG_MODE;
}
#else // VP_DEBUG
#else // VP_DEBUG
#define dgPREERROR \
#define dgPREERROR \
"\t!! " << __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :"
#define dgDEBUG(level) \
if (1) \
; \
else \
#define dgDEBUG(level) \
if (1) \
; \
else \
::dynamicgraph::__null_stream()
#define dgDEBUGMUTE \
(level) if (1); \
#define dgDEBUGMUTE \
(level) if (1); \
else ::dynamicgraph::__null_stream()
#define dgERROR dgERRORFLOW.outputbuffer << dgPREERROR
......@@ -183,13 +181,13 @@ inline std::ostream &__null_stream() {
static std::ostream os(NULL);
return os;
}
} // namespace dynamicgraph
} // namespace dynamicgraph
// TEMPLATE
#define dgTDEBUG(level) \
if (1) \
; \
else \
#define dgTDEBUG(level) \
if (1) \
; \
else \
::dynamicgraph::__null_stream()
inline void dgTDEBUGF(const int, const char *, ...) { return; }
......@@ -199,7 +197,7 @@ inline void dgTDEBUGF(const char *, ...) { return; }
#define dgDEBUG_ENABLE(level) false
#define dgTDEBUG_ENABLE(level) false
#endif //! VP_DEBUG
#endif //! VP_DEBUG
#define dgDEBUGIN(level) dgDEBUG(level) << "# In {" << std::endl
......@@ -213,4 +211,4 @@ inline void dgTDEBUGF(const char *, ...) { return; }
#define dgTDEBUGINOUT(level) dgTDEBUG(level) << "# In/Out { }" << std::endl
#endif //! DYNAMIC_GRAPH_DEBUG_HH
#endif //! DYNAMIC_GRAPH_DEBUG_HH
......@@ -6,4 +6,4 @@
#ifndef DYNAMIC_GRAPH_API_H
#define DYNAMIC_GRAPH_API_H
#include <dynamic-graph/config.hh>
#endif //! DYNAMIC_GRAPH_API_H
#endif //! DYNAMIC_GRAPH_API_H
......@@ -7,13 +7,13 @@
#ifndef DYNAMIC_GRAPH_EIGEN_IO_H
#define DYNAMIC_GRAPH_EIGEN_IO_H
#include <boost/format.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <Eigen/Geometry>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/linear-algebra.h>
#include <Eigen/Geometry>
#include <boost/format.hpp>
#include <boost/numeric/conversion/cast.hpp>
using dynamicgraph::ExceptionSignal;
// TODO: Eigen 3.3 onwards has a global Eigen::Index definition.
......@@ -32,8 +32,9 @@ inline std::istringstream &operator>>(std::istringstream &iss,
unsigned int _size;
double _dbl_val;
char _ch;
boost::format fmt("Failed to enter %s as vector."
" Reenter as [N](val1,val2,val3,...,valN)");
boost::format fmt(
"Failed to enter %s as vector."
" Reenter as [N](val1,val2,val3,...,valN)");
fmt % iss.str();
if (iss >> _ch && _ch != '[') {
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
......@@ -50,8 +51,7 @@ inline std::istringstream &operator>>(std::istringstream &iss,
else {
for (unsigned int i = 0; i < _size; i++) {
iss >> _dbl_val;
if (iss.peek() == ',' || iss.peek() == ' ')
iss.ignore();
if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
inst(i) = _dbl_val;
}
if (iss >> _ch && _ch != ')')
......@@ -76,17 +76,17 @@ inline std::istringstream &operator>>(std::istringstream &iss,
unsigned int _rowsize;
double _dbl_val;
char _ch;
boost::format fmt("Failed to enter %s as matrix. Reenter as "
"((val11,val12,val13,...,val1N),"
"...,(valM1,valM2,...,valMN))");
boost::format fmt(
"Failed to enter %s as matrix. Reenter as "
"((val11,val12,val13,...,val1N),"
"...,(valM1,valM2,...,valMN))");
MatrixXd _tmp_matrix;
fmt % iss.str();
if (iss >> _ch && _ch != '[') {
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
} else {
iss >> _rowsize;
if (iss.peek() == ',' || iss.peek() == ' ')
iss.ignore();
if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
iss >> _colsize;
if (iss.fail())
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
......@@ -103,14 +103,12 @@ inline std::istringstream &operator>>(std::istringstream &iss,
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
for (unsigned int i = 0; i < _colsize; i++) {
iss >> _dbl_val;
if (iss.peek() == ',' || iss.peek() == ' ')
iss.ignore();
if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
_tmp_matrix(j, i) = _dbl_val;
}
if (iss >> _ch && _ch != ')')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
if (iss.peek() == ',' || iss.peek() == ' ')
iss.ignore();
if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
}
if (iss >> _ch && _ch != ')')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
......@@ -163,6 +161,6 @@ inline std::istringstream &operator>>(std::istringstream &iss,
return iss;
}
} // namespace Eigen
} // namespace Eigen
#endif // DYNAMIC_GRAPH_EIGEN_IO_H
#endif // DYNAMIC_GRAPH_EIGEN_IO_H
......@@ -8,11 +8,12 @@
namespace dynamicgraph {
template <typename Ent> struct EntityHelper {
template <typename Ent>
struct EntityHelper {
typedef Ent EntityClassName;
// static const std::string CLASS_NAME; TO BE ADDED IN DG DIRECTLY
};
} // namespace dynamicgraph
} // namespace dynamicgraph
#endif // __sot_core_entity_helper_H__
#endif // __sot_core_entity_helper_H__
......@@ -5,20 +5,19 @@
#ifndef DYNAMIC_GRAPH_ENTITY_H
#define DYNAMIC_GRAPH_ENTITY_H
#include <iosfwd>
#include <map>
#include <sstream>
#include <string>
#include <boost/noncopyable.hpp>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/fwd.hh>
#include <dynamic-graph/logger.h>
#include <dynamic-graph/signal-array.h>
#include <dynamic-graph/signal-base.h>
#include <boost/noncopyable.hpp>
#include <dynamic-graph/fwd.hh>
#include <iosfwd>
#include <map>
#include <sstream>
#include <string>
/// \brief Helper macro for entity declaration.
///
/// This macro should be called in the declaration of all entities.
......@@ -36,9 +35,9 @@
/// Caution: you *MUST* call DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN in the
/// associated source file to ensure that the attributes generated by
/// this macro are correctly initialized.
#define DYNAMIC_GRAPH_ENTITY_DECL() \
public: \
virtual const std::string &getClassName() const { return CLASS_NAME; } \
#define DYNAMIC_GRAPH_ENTITY_DECL() \
public: \
virtual const std::string &getClassName() const { return CLASS_NAME; } \
static const std::string CLASS_NAME
namespace dynamicgraph {
......@@ -51,7 +50,7 @@ namespace dynamicgraph {
/// computation graph. To declare a new entity, please see the
/// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro in factory.h.
class DYNAMIC_GRAPH_DLLAPI Entity : private boost::noncopyable {
public:
public:
typedef std::map<std::string, SignalBase<int> *> SignalMap;
typedef std::map<const std::string, command::Command *> CommandMap_t;
......@@ -63,14 +62,50 @@ public:
static std::string ret("Entity");
return ret;
}
/** \brief Returns the Entity documentation
\return The documentation is provided as std::string object.
*/
virtual std::string getDocString() const;
/** \brief Test if a signal of name signame is present.
\return True if the signal is present, False otherwise
*/
bool hasSignal(const std::string &signame) const;
/** \brief Provides a reference to the signal named signalName.
\param signalName: Name of the signal
\return A reference to the signal with a temporal dependency.
*/
SignalBase<int> &getSignal(const std::string &signalName);
/** \brief Provides a const reference to the signal named signalName.
\param signalName: Name of the signal
\return A const reference to the signal with a temporal dependency.
*/
const SignalBase<int> &getSignal(const std::string &signalName) const;
/** \brief Display the list of signals of this entity in output stream os.
\param os: the output stream where to display the list of signals.
\returns The output stream given in parameter.
*/
std::ostream &displaySignalList(std::ostream &os) const;
/** \brief This method is used to write down in os the edges of the graph
by calling the signals writeGraph method.
\param os: The output stream where to write the informations.
\return os: The output stream.
*/
virtual std::ostream &writeGraph(std::ostream &os) const;
/** \brief This method is used write in the output stream os the
signals names and the commands of the entity.
\param os: The output stream where to write the list of objects
related to the entity.
*/
virtual std::ostream &writeCompletionList(std::ostream &os) const;
/** \brief Display information on the entity inside the output stream os.
*/
virtual void display(std::ostream &os) const;
virtual SignalBase<int> *test() { return 0; }
......@@ -78,17 +113,32 @@ public:
virtual void test2(SignalBase<int> *) { return; }
const std::string &getCommandList() const;
/** \brief Provides the std::map where all the commands are registered
\returns A map of pointers towards Command objects
*/
CommandMap_t getNewStyleCommandMap();
/** \brief Provides the pointer towards the Command object cmdName.
\param cmdName: Name of the command
*/
command::Command *getNewStyleCommand(const std::string &cmdName);
/** \brief Provides a map of all the signals.
\returns A copy of the map with all the pointers towards
the entity signals.
*/
SignalMap getSignalMap() const;
/** \name Logger related methods */
/** \{*/
/// \name Logger related methods
/// \{
Logger &logger() { return logger_; };
Logger const &logger() const { return logger_; };
/// \brief Send messages \c msg with level \c t.
/// Add string file and line to message.
void sendMsg(const std::string &msg, MsgType t = MSG_TYPE_INFO,
const char *file = "", int line = 0);
const std::string &lineId = "");
/// \brief Specify the verbosity level of the logger.
void setLoggerVerbosityLevel(LoggerVerbosity lv) { logger_.setVerbosity(lv); }
......@@ -110,7 +160,9 @@ public:
/// \brief Get the period of the stream period
double getStreamPrintPeriod() { return logger_.getStreamPrintPeriod(); }
protected:
/// \}
protected:
void addCommand(const std::string &name, command::Command *command);
void entityRegistration();
......@@ -127,6 +179,6 @@ protected:
DYNAMIC_GRAPH_DLLAPI std::ostream &operator<<(std::ostream &os,
const dynamicgraph::Entity &ent);
} // end of namespace dynamicgraph
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_ENTITY_H
#endif //! DYNAMIC_GRAPH_ENTITY_H
......@@ -5,42 +5,47 @@
#ifndef DYNAMIC_GRAPH_EXCEPTION_ABSTRACT_H
#define DYNAMIC_GRAPH_EXCEPTION_ABSTRACT_H
#include <string>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/fwd.hh>
#include <string>
// Uncomment this macros to have lines parameter on the throw display
// #define DYNAMIC-GRAPH_EXCEPTION_PASSING_PARAM
#define DG_RETHROW \
#define DG_RETHROW \
(const ::dynamicgraph::ExceptionAbstract &err) { throw err; }
#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
#define DG_THROW \
throw ::dynamicgraph::ExceptionAbstract::Param(__LINE__, __FUNCTION__, \
#define DG_THROW \
throw ::dynamicgraph::ExceptionAbstract::Param(__LINE__, __FUNCTION__, \
__FILE__) +
#else
#define DG_THROW throw
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
namespace dynamicgraph {
/// \ingroup error
///
/// \brief Abstract root class for all dynamic-graph exceptions.
class DYNAMIC_GRAPH_DLLAPI ExceptionAbstract : public std::exception {
public:
public:
/// \ingroup error
///
/// \brief Class owned by exceptions to store error locations.
class Param {
public:
public:
static const int BUFFER_SIZE = 80;
Param(const int &_line, const char *_function, const char *_file);
Param()
: functionPTR(), function(), line(), filePTR(), file(),
pointersSet(false), set(false) {}
: functionPTR(),
function(),
line(),
filePTR(),
file(),
pointersSet(false),
set(false) {}
Param &initCopy(const Param &p);
const char *functionPTR;
......@@ -91,10 +96,10 @@ public:
}
/// \brief Print the error structure.
DYNAMIC_GRAPH_DLLAPI friend std::ostream &
operator<<(std::ostream &os, const ExceptionAbstract &err);
DYNAMIC_GRAPH_DLLAPI friend std::ostream &operator<<(
std::ostream &os, const ExceptionAbstract &err);
protected:
protected:
/// \brief Error code.
/// \sa ErrorCodeEnum
int code;
......@@ -121,12 +126,12 @@ protected:
return e;
}
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
private:
private:
/// \brief Forbid the empty constructor (private).
ExceptionAbstract();
};
} // end of namespace dynamicgraph
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_EXCEPTION_ABSTRACT_H
#endif //! DYNAMIC_GRAPH_EXCEPTION_ABSTRACT_H
......@@ -5,18 +5,18 @@
#ifndef DYNAMIC_GRAPH_EXCEPTION_FACTORY_H
#define DYNAMIC_GRAPH_EXCEPTION_FACTORY_H
#include <string>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/fwd.hh>
#include <string>
namespace dynamicgraph {
/// \ingroup error
///
/// \brief Generic error class.
class DYNAMIC_GRAPH_DLLAPI ExceptionFactory : public ExceptionAbstract {
public:
public:
enum ErrorCodeEnum {
GENERIC = ExceptionAbstract::FACTORY,
UNREFERED_OBJECT,
......@@ -44,6 +44,6 @@ public:
return ExceptionFactory::EXCEPTION_NAME;
}
};
} // end of namespace dynamicgraph
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_EXCEPTION_FACTORY_H
#endif //! DYNAMIC_GRAPH_EXCEPTION_FACTORY_H
......@@ -8,6 +8,7 @@
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/fwd.hh>
namespace dynamicgraph {
......@@ -16,7 +17,7 @@ namespace dynamicgraph {
/// \brief Exceptions raised when an error related to signals
/// happen.
class DYNAMIC_GRAPH_DLLAPI ExceptionSignal : public ExceptionAbstract {
public:
public:
enum ErrorCodeEnum {
GENERIC = ExceptionAbstract::SIGNAL,
READWRITE_LOCK,
......@@ -38,6 +39,6 @@ public:
virtual const std::string &getExceptionName() const { return EXCEPTION_NAME; }
};
} // end of namespace dynamicgraph
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_EXCEPTION_SIGNAL_H
#endif //! DYNAMIC_GRAPH_EXCEPTION_SIGNAL_H
......@@ -5,18 +5,18 @@
#ifndef DYNAMIC_GRAPH_EXCEPTION_TRACES_H
#define DYNAMIC_GRAPH_EXCEPTION_TRACES_H
#include <string>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/fwd.hh>
#include <string>
namespace dynamicgraph {
/// \ingroup error
///
/// \brief Exceptions raised when an error related to traces happen.
class DYNAMIC_GRAPH_DLLAPI ExceptionTraces : public ExceptionAbstract {
public:
public:
enum ErrorCodeEnum { GENERIC = ExceptionAbstract::TRACES, NOT_OPEN };
static const std::string EXCEPTION_NAME;
......@@ -29,6 +29,6 @@ public:
virtual const std::string &getExceptionName() const { return EXCEPTION_NAME; }
};
} // end of namespace dynamicgraph.
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_EXCEPTION_TRACES_H
#endif //! DYNAMIC_GRAPH_EXCEPTION_TRACES_H
......@@ -5,15 +5,14 @@
#ifndef DYNAMIC_GRAPH_FACTORY_HH
#define DYNAMIC_GRAPH_FACTORY_HH
#include <map>
#include <string>
#include <vector>
#include <boost/noncopyable.hpp>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-factory.h>
#include <boost/noncopyable.hpp>
#include <dynamic-graph/fwd.hh>
#include <map>
#include <string>
#include <vector>
/// \ingroup dgraph
///
......@@ -24,16 +23,16 @@
/// \param CLASSNAME the name of the Entity to be registered (this must
/// be a std::string or a type implicitly castable into a std::string
/// such as classic C string delimited by double quotes).
#define DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CLASSTYPE, CLASSNAME) \
const std::string CLASSTYPE::CLASS_NAME = CLASSNAME; \
extern "C" { \
::dynamicgraph::Entity * \
EntityMaker_##CLASSTYPE(const std::string &objname) { \
return new CLASSTYPE(objname); \
} \
::dynamicgraph::EntityRegisterer reg_##CLASSTYPE(CLASSNAME, \
&EntityMaker_##CLASSTYPE); \
} \
#define DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CLASSTYPE, CLASSNAME) \
const std::string CLASSTYPE::CLASS_NAME = CLASSNAME; \
extern "C" { \
::dynamicgraph::Entity *EntityMaker_##CLASSTYPE( \
const std::string &objname) { \
return new CLASSTYPE(objname); \
} \
::dynamicgraph::EntityRegisterer reg_##CLASSTYPE(CLASSNAME, \
&EntityMaker_##CLASSTYPE); \
} \
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
namespace dynamicgraph {
......@@ -80,7 +79,7 @@ namespace dynamicgraph {
/// instance of this class enforces this behavior, instantiating one
/// yourself would break this property.
class DYNAMIC_GRAPH_DLLAPI FactoryStorage : private boost::noncopyable {
public:
public:
/// \brief Function pointer providing an entity instance from its
/// name.
typedef Entity *(*EntityConstructor_ptr)(const std::string &);
......@@ -151,7 +150,7 @@ public:
/// \param list Available entities will be appended to list.
void listEntities(std::vector<std::string> &list) const;
private:
private:
/// \brief Constructor the factory.
///
/// After the initialization, no entities will be available.
......@@ -183,7 +182,7 @@ private:
/// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro and is of little interest
/// by itself.
class DYNAMIC_GRAPH_DLLAPI EntityRegisterer : private boost::noncopyable {
public:
public:
/// \brief Register entity to the global factory.
explicit EntityRegisterer(const std::string &entityClassName,
FactoryStorage::EntityConstructor_ptr maker);
......@@ -191,13 +190,13 @@ public:
/// \brief Unregister entity to the global factory.
~EntityRegisterer();
private:
private:
/// \brief Name of the entity registered when the instance has
/// been initialized.
const std::string entityName;
};
} // end of namespace dynamicgraph
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_FACTORY_HH
#endif //! DYNAMIC_GRAPH_FACTORY_HH
// LocalWords: unregister
......@@ -5,7 +5,18 @@
#ifndef DYNAMIC_GRAPH_FWD_HH
#define DYNAMIC_GRAPH_FWD_HH
#include <boost/smart_ptr.hpp>
namespace dynamicgraph {
// to be replace by std:: when we switch to C++11 and later
using boost::const_pointer_cast;
using boost::dynamic_pointer_cast;
using boost::make_shared;
using boost::shared_ptr;
using boost::static_pointer_cast;
using boost::weak_ptr;
class DebugTrace;
class PluginRefMap;
......@@ -17,36 +28,39 @@ class ExceptionSignal;
class ExceptionTraces;
class FactoryStorage;
class Interpreter;
typedef shared_ptr<Interpreter> InterpreterShPtr_t;
class InterpreterHelper;
class Logger;
class OutStringStream;
class PluginLoader;
class PoolStorage;
class SignalCaster;
class SignalCastRegisterer;
class Tracer;
class TracerRealTime;
template <typename T> class DefaultCastRegisterer;
template <typename T, typename Time> class Signal;
template <typename T, typename Time>
class Signal;
template <typename Time> class SignalArray;
template <typename Time>
class SignalArray;
template <typename Time> class SignalArray_const;
template <typename Time>
class SignalArray_const;
template <typename Time> class SignalBase;
template <typename Time>
class SignalBase;
template <typename T, typename Time> class SignalPtr;
template <typename T, typename Time> class SignalTimeDependent;
template <typename Time> class TimeDependency;
template <typename T, typename Time>
class SignalPtr;
template <typename T, typename Time>
class SignalTimeDependent;
template <typename Time>
class TimeDependency;
namespace command {
class Command;
} // end of namespace command.
} // end of namespace command.
} // end of namespace dynamicgraph.
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_FWD_HH
#endif //! DYNAMIC_GRAPH_FWD_HH
......@@ -12,6 +12,6 @@
namespace dynamicgraph {
typedef Eigen::MatrixXd Matrix;
typedef Eigen::VectorXd Vector;
} // namespace dynamicgraph
} // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
#endif // DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
......@@ -27,26 +27,34 @@ namespace dynamicgraph {
/** Enum representing the different kind of messages.
*/
enum MsgType {
MSG_TYPE_DEBUG = 0,
MSG_TYPE_INFO = 1,
MSG_TYPE_WARNING = 2,
MSG_TYPE_ERROR = 3,
MSG_TYPE_DEBUG_STREAM = 4,
MSG_TYPE_INFO_STREAM = 5,
MSG_TYPE_WARNING_STREAM = 6,
MSG_TYPE_ERROR_STREAM = 7
MSG_TYPE_TYPE_BITS = 1 << 0 | 1 << 1 | 1 << 2 | 1 << 3, // 15
MSG_TYPE_STREAM_BIT = 1 << 4, // 16
MSG_TYPE_DEBUG = 1 << 3, // 1
MSG_TYPE_INFO = 1 << 2, // 2
MSG_TYPE_WARNING = 1 << 1, // 4
MSG_TYPE_ERROR = 1 << 0, // 8
MSG_TYPE_DEBUG_STREAM = MSG_TYPE_DEBUG | MSG_TYPE_STREAM_BIT, // 17
MSG_TYPE_INFO_STREAM = MSG_TYPE_INFO | MSG_TYPE_STREAM_BIT, // 18
MSG_TYPE_WARNING_STREAM = MSG_TYPE_WARNING | MSG_TYPE_STREAM_BIT, // 20
MSG_TYPE_ERROR_STREAM = MSG_TYPE_ERROR | MSG_TYPE_STREAM_BIT // 24
};
} // namespace dynamicgraph
} // namespace dynamicgraph
/* --------------------------------------------------------------------- */
/* --- INCLUDE --------------------------------------------------------- */
/* --------------------------------------------------------------------- */
#include "boost/assign.hpp"
#include <map>
/// \todo These 3 headers should be removed.
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/real-time-logger-def.h>
#include <boost/assign.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <dynamic-graph/deprecated.hh>
#include <fstream>
#include <iomanip> // std::setprecision
#include <map>
#include <iomanip> // std::setprecision
#include <sstream>
namespace dynamicgraph {
......@@ -54,13 +62,35 @@ namespace dynamicgraph {
//#define LOGGER_VERBOSITY_INFO_WARNING_ERROR
#define LOGGER_VERBOSITY_ALL
#define SEND_MSG(msg, type) sendMsg(msg, type, __FILE__, __LINE__)
#define SEND_MSG(msg, type) \
sendMsg(msg, type, __FILE__ ":" BOOST_PP_STRINGIZE(__LINE__))
#define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_DEBUG_STREAM)
#define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_INFO_STREAM)
#define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING_STREAM)
#define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR_STREAM)
#define _DYNAMIC_GRAPH_ENTITY_MSG(entity, type) \
(entity).logger().stream(type, __FILE__ BOOST_PP_STRINGIZE(__LINE__))
#define DYNAMIC_GRAPH_ENTITY_DEBUG(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_DEBUG)
#define DYNAMIC_GRAPH_ENTITY_INFO(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_INFO)
#define DYNAMIC_GRAPH_ENTITY_WARNING(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_WARNING)
#define DYNAMIC_GRAPH_ENTITY_ERROR(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_ERROR)
#define DYNAMIC_GRAPH_ENTITY_DEBUG_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_DEBUG_STREAM)
#define DYNAMIC_GRAPH_ENTITY_INFO_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_INFO_STREAM)
#define DYNAMIC_GRAPH_ENTITY_WARNING_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_WARNING_STREAM)
#define DYNAMIC_GRAPH_ENTITY_ERROR_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_ERROR_STREAM)
template <typename T>
std::string toString(const T &v, const int precision = 3,
const int width = -1) {
......@@ -111,11 +141,11 @@ std::string toString(const Eigen::MatrixBase<T> &v, const int precision = 3,
}
enum LoggerVerbosity {
VERBOSITY_ALL,
VERBOSITY_INFO_WARNING_ERROR,
VERBOSITY_WARNING_ERROR,
VERBOSITY_ERROR,
VERBOSITY_NONE
VERBOSITY_ALL = MSG_TYPE_DEBUG,
VERBOSITY_INFO_WARNING_ERROR = MSG_TYPE_INFO,
VERBOSITY_WARNING_ERROR = MSG_TYPE_WARNING,
VERBOSITY_ERROR = MSG_TYPE_ERROR,
VERBOSITY_NONE = 0
};
/// \ingroup debug
......@@ -139,14 +169,22 @@ enum LoggerVerbosity {
/// VERBOSITY_WARNING_ERROR;
/// entity.setLoggerVerbosityLevel(aLoggerVerbosityLevel);
/// ...
/// std::string aMsg=aBaseMsg+" WARNING";
/// entity.sendMsg(aMsg,dynamicgraph::MSG_TYPE_WARNING, __FILE__,__LINE__);
/// // using macros
/// DYNAMIC_GRAPH_ENTITY_WARNING(entity) << "your message\n";
///
/// \endcode
/// // or the equivalent code without macros:
/// // Please use '\n' instead of std::endl and flushing will have no effect
/// entity.logger.stream(dynamicgraph::MSG_TYPE_WARNING,
/// __FILE__ BOOST_PP_STRINGIZE(__LINE__))
/// << your message << '\n';
///
/// \endcode
///
/// \todo remove m_timeSample and streamPrintPeriod to rather use a simple
/// integer counting the number of calls. This will achieve exactly the
/// same behaviour without rouding numerical errors.
class Logger {
public:
public:
/** Constructor */
Logger(double timeSample = 0.001, double streamPrintPeriod = 1.0);
......@@ -157,13 +195,40 @@ public:
* to decrement the internal Logger's counter. */
void countdown();
/** Get an output stream independently of the debug level.
*/
RTLoggerStream stream() {
return ::dynamicgraph::RealTimeLogger::instance().front();
}
/** Print the specified message on standard output if the verbosity level
* allows it. The file name and the line number are used to identify
* the point where sendMsg is called so that streaming messages are
* printed only every streamPrintPeriod iterations.
* allows it. The lineId is used to identify the point where sendMsg is
* called so that streaming messages are printed only every streamPrintPeriod
* iterations.
* \param type specifies the verbosity level, for instance MSG_TYPE_DEBUG
* \param lineId typically __FILE__ ":" BOOST_PP_STRINGIZE(__LINE__)
*/
void sendMsg(std::string msg, MsgType type, const char *file = "",
int line = 0);
RTLoggerStream stream(MsgType type, const std::string &lineId = "") {
RealTimeLogger &rtlogger = ::dynamicgraph::RealTimeLogger::instance();
if (acceptMsg(type, lineId)) return rtlogger.front();
return rtlogger.emptyStream();
}
/** \deprecated instead, use
* \code
* stream(type, lineId) << msg << '\n';
* \endcode
*/
[[deprecated("use stream(type, lineId) << msg")]] void sendMsg(
std::string msg, MsgType type, const std::string &lineId = "");
/** \deprecated instead, use
* \code
* stream(type, lineId) << msg << '\n';
* \endcode
*/
[[deprecated("use stream(type, lineId) << msg")]] void sendMsg(
std::string msg, MsgType type, const std::string &file, int line);
/** Set the sampling time at which the method countdown()
* is going to be called. */
......@@ -185,40 +250,40 @@ public:
/** Get the verbosity level of the logger. */
LoggerVerbosity getVerbosity();
protected:
LoggerVerbosity m_lv; /// verbosity of the logger
protected:
LoggerVerbosity m_lv; /// verbosity of the logger
double m_timeSample;
/// specify the period of call of the countdown method
double m_streamPrintPeriod; /// specify the time period of the stream prints
double m_streamPrintPeriod; /// specify the time period of the stream prints
double m_printCountdown;
/// every time this is < 0 (i.e. every _streamPrintPeriod sec) print stuff
typedef std::map<std::string, double> StreamCounterMap_t;
/** Pointer to the dynamic structure which holds
the collection of streaming messages */
std::map<std::string, double> m_stream_msg_counters;
bool isStreamMsg(MsgType m) {
return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_DEBUG_STREAM ||
m == MSG_TYPE_INFO_STREAM || m == MSG_TYPE_WARNING_STREAM;
}
StreamCounterMap_t m_stream_msg_counters;
bool isDebugMsg(MsgType m) {
return m == MSG_TYPE_DEBUG_STREAM || m == MSG_TYPE_DEBUG;
}
inline bool isStreamMsg(MsgType m) { return (m & MSG_TYPE_STREAM_BIT); }
bool isInfoMsg(MsgType m) {
return m == MSG_TYPE_INFO_STREAM || m == MSG_TYPE_INFO;
}
/** Check whether a message of type \p m and from \p c lineId should be
* accepted. \note If \p m is a stream type, the internal counter associated
* to \p lineId is updated.
*/
bool acceptMsg(MsgType m, const std::string &lineId) {
// If more verbose than the current verbosity level
if ((m & MSG_TYPE_TYPE_BITS) > m_lv) return false;
bool isWarningMsg(MsgType m) {
return m == MSG_TYPE_WARNING_STREAM || m == MSG_TYPE_WARNING;
// if print is allowed by current verbosity level
if (isStreamMsg(m)) return checkStreamPeriod(lineId);
return true;
}
bool isErrorMsg(MsgType m) {
return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_ERROR;
}
/** Check whether a message from \c lineId should be accepted.
* \note The internal counter associated to \c lineId is updated.
*/
bool checkStreamPeriod(const std::string &lineId);
};
} // namespace dynamicgraph
} // namespace dynamicgraph
#endif // #ifndef __sot_torque_control_logger_H__
#endif // #ifndef __sot_torque_control_logger_H__
// Copyright 2010, Thomas Moulard, JRL, CNRS/AIST
//
#ifndef DYNAMIC_GRAPH_NULL_PTR_HH
#define DYNAMIC_GRAPH_NULL_PTR_HH
namespace dynamicgraph {
/// \cond
const class {
public:
template <class T> operator T *() const { return 0; }
template <class C, class T> operator T C::*() const { return 0; }
private:
void operator&() const;
} nullptr = {};
/// \endcond
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_NULL_PTR_HH
......@@ -5,15 +5,15 @@
#ifndef DYNAMIC_GRAPH_POOL_H
#define DYNAMIC_GRAPH_POOL_H
#include <map>
#include <sstream>
#include <string>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/fwd.hh>
#include <dynamic-graph/signal-base.h>
#include <dynamic-graph/fwd.hh>
#include <map>
#include <sstream>
#include <string>
namespace dynamicgraph {
/*! @ingroup dgraph
\brief Singleton that keeps track of all the entities.
......@@ -31,7 +31,7 @@ namespace dynamicgraph {
*/
class DYNAMIC_GRAPH_DLLAPI PoolStorage {
public:
public:
/*! \name Define types to simplify the writing
@{
*/
......@@ -98,7 +98,7 @@ public:
void writeGraph(const std::string &aFileName);
void writeCompletionList(std::ostream &os);
protected:
protected:
/*! \name Fields of the class to manage the three entities.
Also the name is singular, those are true sets.
@{
......@@ -106,13 +106,13 @@ protected:
/*! \brief Set of basic objects of the SoT */
Entities entityMap;
private:
private:
PoolStorage() {}
static PoolStorage *instance_;
};
inline PoolStorage &g_pool() { return *PoolStorage::getInstance(); }
} // end of namespace dynamicgraph.
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_POOL_H
#endif //! DYNAMIC_GRAPH_POOL_H
......@@ -4,13 +4,13 @@
*/
#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_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/fwd.hh>
namespace dynamicgraph {
......@@ -18,14 +18,14 @@ namespace CPU {
class DYNAMIC_GRAPH_DLLAPI ProcessData {};
class DYNAMIC_GRAPH_DLLAPI ProcessList {
public:
public:
ProcessList();
};
/// This class gather information on a specific CPU.
///
class DYNAMIC_GRAPH_DLLAPI CPUData {
public:
public:
CPUData();
int cpu_id_;
......@@ -126,10 +126,10 @@ public:
/// This class gathers information on a computer.
/// This includes a list of CPU
class DYNAMIC_GRAPH_DLLAPI System {
private:
private:
bool init_;
public:
public:
System();
/// Read /proc/state file to extract CPU count.
......@@ -160,7 +160,7 @@ public:
ar &vCPUData_;
}
};
} // namespace CPU
} // namespace dynamicgraph
} // namespace CPU
} // namespace dynamicgraph
#endif /* DYNAMIC_GRAPH_PROCESS_LIST_H_ */
// -*- mode: c++ -*-
// Copyright 2018, Joseph Mirabel LAAS-CNRS
//
#ifndef DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
#define DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <dynamic-graph/config.hh>
#include <sstream>
#include <vector>
namespace dynamicgraph {
/// \ingroup debug
///
/// \brief Stream for the real-time logger.
///
/// You should inherit from this class in order to redirect the logs where you
/// want.
/// \sa LoggerIOStream
class LoggerStream {
public:
virtual void write(const char *c) = 0;
};
/// Write to an ostream object.
///
/// The easieast is to use the macro dgADD_OSTREAM_TO_RTLOG(ostr) where
/// `ostr` can be `std::cout` or an std::ofstream...
class LoggerIOStream : public LoggerStream {
public:
LoggerIOStream(std::ostream &os) : os_(os) {}
virtual ~LoggerIOStream() {}
virtual void write(const char *c) { os_ << c; }
private:
std::ostream &os_;
};
typedef boost::shared_ptr<LoggerStream> LoggerStreamPtr_t;
class RealTimeLogger;
/// \cond DEVEL
/// \brief write entries to intenal buffer.
///
/// The entry starts when an instance is created and ends when is is deleted.
/// This class is only used by RealTimeLogger.
class RTLoggerStream {
public:
inline RTLoggerStream(RealTimeLogger *logger, std::ostream &os)
: ok_(logger != NULL), logger_(logger), os_(os) {}
template <typename T>
inline RTLoggerStream &operator<<(T t) {
if (ok_) os_ << t;
return *this;
}
inline RTLoggerStream &operator<<(std::ostream &(*pf)(std::ostream &)) {
if (ok_) os_ << pf;
return *this;
}
inline ~RTLoggerStream();
inline bool isNull() { return !ok_; }
private:
const bool ok_;
RealTimeLogger *logger_;
std::ostream &os_;
};
/// \endcond DEVEL
/// \ingroup debug
///
/// \brief Main class of the real-time logger.
///
/// It is intended to be used like this:
/// \code
/// #define ENABLE_RT_LOG
/// #include <dynamic-graph/real-time-logger.h>
///
/// // Somewhere in the main function of your executable
/// int main (int argc, char** argv) {
/// dgADD_OSTREAM_TO_RTLOG (std::cout);
/// }
///
/// // Somewhere in your library
/// dgRTLOG() << "your message. Prefer to use \n than std::endl."
/// \endcode
///
/// \note Thread safety. This class expects to have:
/// - only one reader: the one who take the log entries and write them
/// somewhere.
/// - one writer at a time. Writing to the logs is **never** a blocking
/// operation. If the resource is busy, the log entry is discarded.
class DYNAMIC_GRAPH_DLLAPI RealTimeLogger {
public:
static RealTimeLogger &instance();
static void destroy();
/// \todo add an argument to preallocate the internal string
/// to a given size.
RealTimeLogger(const std::size_t &bufferSize);
inline void clearOutputStreams() { outputs_.clear(); }
inline void addOutputStream(const LoggerStreamPtr_t &os) {
outputs_.push_back(os);
}
/// Write next message to output.
/// It does nothing if the buffer is empty.
/// \return true if it wrote something
bool spinOnce();
/// Return an object onto which a real-time thread can write.
/// The message is considered finished when the object is destroyed.
RTLoggerStream front();
/// Return an empty stream object.
RTLoggerStream emptyStream() { return RTLoggerStream(NULL, oss_); }
inline void frontReady() {
backIdx_ = (backIdx_ + 1) % buffer_.size();
wmutex.unlock();
}
inline bool empty() const { return frontIdx_ == backIdx_; }
inline bool full() const {
return ((backIdx_ + 1) % buffer_.size()) == frontIdx_;
}
inline std::size_t size() const {
if (frontIdx_ <= backIdx_)
return backIdx_ - frontIdx_;
else
return backIdx_ + buffer_.size() - frontIdx_;
}
inline std::size_t getBufferSize() { return buffer_.size(); }
~RealTimeLogger();
private:
struct Data {
std::stringbuf buf;
};
std::vector<LoggerStreamPtr_t> outputs_;
std::vector<Data *> buffer_;
/// Index of the next value to be read.
std::size_t frontIdx_;
/// Index of the slot where to write next value
/// (does not contain valid data).
std::size_t backIdx_;
std::ostream oss_;
/// The writer mutex.
boost::mutex wmutex;
std::size_t nbDiscarded_;
struct thread;
static RealTimeLogger *instance_;
static thread *thread_;
};
RTLoggerStream::~RTLoggerStream() {
if (ok_) {
os_ << std::ends;
logger_->frontReady();
}
}
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
......@@ -4,182 +4,23 @@
#ifndef DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
#define DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
#include <sstream>
#include <vector>
#include <boost/circular_buffer.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <dynamic-graph/config.hh>
#include <dynamic-graph/debug.h>
namespace dynamicgraph {
/// \ingroup debug
///
/// \brief Stream for the real-time logger.
///
/// You should inherit from this class in order to redirect the logs where you
/// want.
/// \sa LoggerIOStream
class LoggerStream {
public:
virtual void write(const char *c) = 0;
};
/// Write to an ostream object.
///
/// The easieast is to use the macro \ref dgADD_OSTREAM_TO_RTLOG(ostr) where
/// `ostr` can be `std::cout` or an std::ofstream...
class LoggerIOStream : public LoggerStream {
public:
LoggerIOStream(std::ostream &os) : os_(os) {}
virtual void write(const char *c) { os_ << c; }
private:
std::ostream &os_;
};
typedef boost::shared_ptr<LoggerStream> LoggerStreamPtr_t;
class RealTimeLogger;
/// \cond DEVEL
/// \brief write entries to intenal buffer.
///
/// The entry starts when an instance is created and ends when is is deleted.
/// This class is only used by RealTimeLogger.
class RTLoggerStream {
public:
RTLoggerStream(RealTimeLogger *logger, std::ostream &os)
: logger_(logger), os_(os) {}
template <typename T> inline RTLoggerStream &operator<<(T t) {
if (logger_ != NULL)
os_ << t;
return *this;
}
inline RTLoggerStream &operator<<(std::ostream &(*pf)(std::ostream &)) {
if (logger_ != NULL)
os_ << pf;
return *this;
}
~RTLoggerStream();
private:
RealTimeLogger *logger_;
std::ostream &os_;
};
/// \endcond DEVEL
/// \ingroup debug
///
/// \brief Main class of the real-time logger.
///
/// It is intended to be used like this:
/// \code
/// #define ENABLE_RT_LOG
/// #include <dynamic-graph/real-time-logger.h>
///
/// // Somewhere in the main function of your executable
/// int main (int argc, char** argv) {
/// dgADD_OSTREAM_TO_RTLOG (std::cout);
/// }
///
/// // Somewhere in your library
/// dgRTLOG() << "your message. Prefer to use \n than std::endl."
/// \endcode
///
/// \note Thread safety. This class expects to have:
/// - only one reader: the one who take the log entries and write them
/// somewhere.
/// - one writer at a time. Writing to the logs is **never** a blocking
/// operation. If the resource is busy, the log entry is discarded.
class DYNAMIC_GRAPH_DLLAPI RealTimeLogger {
public:
static RealTimeLogger &instance();
static void destroy();
/// \todo add an argument to preallocate the internal string
/// to a given size.
RealTimeLogger(const std::size_t &bufferSize);
inline void clearOutputStreams() { outputs_.clear(); }
inline void addOutputStream(const LoggerStreamPtr_t &os) {
outputs_.push_back(os);
}
/// Write next message to output.
/// It does nothing if the buffer is empty.
/// \return true if it wrote something
bool spinOnce();
/// Return an object onto which a real-time thread can write.
/// The message is considered finished when the object is destroyed.
RTLoggerStream front();
inline void frontReady() {
backIdx_ = (backIdx_ + 1) % buffer_.size();
wmutex.unlock();
}
inline bool empty() const { return frontIdx_ == backIdx_; }
inline bool full() const {
return ((backIdx_ + 1) % buffer_.size()) == frontIdx_;
}
inline std::size_t size() const {
if (frontIdx_ <= backIdx_)
return backIdx_ - frontIdx_;
else
return backIdx_ + buffer_.size() - frontIdx_;
}
inline std::size_t getBufferSize() { return buffer_.size(); }
~RealTimeLogger();
private:
struct Data {
std::stringbuf buf;
};
std::vector<LoggerStreamPtr_t> outputs_;
std::vector<Data *> buffer_;
/// Index of the next value to be read.
std::size_t frontIdx_;
/// Index of the slot where to write next value
/// (does not contain valid data).
std::size_t backIdx_;
std::ostream oss_;
/// The writer mutex.
boost::mutex wmutex;
std::size_t nbDiscarded_;
struct thread;
static RealTimeLogger *instance_;
static thread *thread_;
};
} // end of namespace dynamicgraph
#ifdef ENABLE_RT_LOG
#define dgADD_OSTREAM_TO_RTLOG(ostr) \
::dynamicgraph::RealTimeLogger::instance().addOutputStream( \
::dynamicgraph::LoggerStreamPtr_t( \
#define dgADD_OSTREAM_TO_RTLOG(ostr) \
::dynamicgraph::RealTimeLogger::instance().addOutputStream( \
::dynamicgraph::LoggerStreamPtr_t( \
new ::dynamicgraph::LoggerIOStream(ostr)))
#define dgRTLOG() ::dynamicgraph::RealTimeLogger::instance().front()
#else // ENABLE_RT_LOG
#else // ENABLE_RT_LOG
#define dgADD_OSTREAM_TO_RTLOG(ostr) struct __end_with_semicolon
#define dgRTLOG() \
if (1) \
; \
else \
#define dgRTLOG() \
if (1) \
; \
else \
__null_stream()
#endif
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
#include <dynamic-graph/real-time-logger-def.h>
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
......@@ -8,6 +8,7 @@
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/signal-base.h>
#include <stdio.h>
#include <vector>
namespace dynamicgraph {
......@@ -15,16 +16,16 @@ namespace dynamicgraph {
/// \ingroup dgraph
///
/// \brief TODO
template <class Time> class SignalArray_const {
public:
template <class Time>
class SignalArray_const {
public:
static const int DEFAULT_SIZE = 20;
protected:
protected:
std::vector<const SignalBase<Time> *> const_array;
unsigned int size, rank;
public:
public:
SignalArray_const<Time>(const unsigned int &sizeARG = DEFAULT_SIZE)
: const_array(sizeARG), size(sizeARG), rank(0) {}
......@@ -34,22 +35,22 @@ public:
}
SignalArray_const<Time>(const SignalArray<Time> &siga)
: const_array(siga.getSize()), size(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)
: const_array(siga.getSize()), size(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>() {}
protected:
protected:
void addElmt(const SignalBase<Time> *el) {
if (rank >= size) {
size += DEFAULT_SIZE;
......@@ -58,13 +59,13 @@ protected:
const_array[rank++] = el;
}
public:
public:
virtual SignalArray_const<Time> &operator<<(const SignalBase<Time> &sig) {
addElmt(&sig);
return *this;
}
public:
public:
virtual const SignalBase<Time> &operator[](const unsigned int &idx) const {
return *const_array[idx];
}
......@@ -82,16 +83,17 @@ SignalArray_const<Time> operator<<(const SignalBase<Time> &sig1,
/// \ingroup dgraph
///
/// \brief TODO
template <class Time> class SignalArray : public SignalArray_const<Time> {
public:
template <class Time>
class SignalArray : public SignalArray_const<Time> {
public:
using SignalArray_const<Time>::DEFAULT_SIZE;
using SignalArray_const<Time>::size;
using SignalArray_const<Time>::rank;
protected:
protected:
mutable std::vector<SignalBase<Time> *> array;
public:
public:
SignalArray<Time>(const unsigned int &sizeARG = DEFAULT_SIZE)
: SignalArray_const<Time>(0), array(sizeARG) {
size = sizeARG;
......@@ -106,13 +108,12 @@ public:
SignalArray<Time>(const SignalArray<Time> &siga)
: SignalArray_const<Time>(siga.getSize()), array(siga.getSize()) {
rank = siga.getSize();
for (unsigned int i = 0; i < rank; ++i)
array[i] = &siga[i];
for (unsigned int i = 0; i < rank; ++i) array[i] = &siga[i];
}
virtual ~SignalArray<Time>() {}
protected:
protected:
void addElmt(SignalBase<Time> *el) {
if (rank >= size) {
size += DEFAULT_SIZE;
......@@ -121,14 +122,14 @@ protected:
array[rank++] = el;
}
public:
public:
virtual SignalArray<Time> &operator<<(SignalBase<Time> &sig) {
addElmt(&sig);
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);
res << sig;
return res;
......@@ -148,6 +149,6 @@ SignalArray<Time> operator<<(SignalBase<Time> &sig1, SignalBase<Time> &sig2) {
DYNAMIC_GRAPH_DLLAPI extern SignalArray<int> sotNOSIGNAL;
} // end of namespace dynamicgraph.
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_ARRAY_H
#endif //! DYNAMIC_GRAPH_SIGNAL_ARRAY_H