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 592 additions and 584 deletions
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
// //
#include "dynamic-graph/command.h" #include "dynamic-graph/command.h"
#include "dynamic-graph/exception-abstract.h"
#include <sstream> #include <sstream>
#include "dynamic-graph/exception-abstract.h"
namespace dynamicgraph { namespace dynamicgraph {
namespace command { namespace command {
...@@ -51,5 +53,5 @@ Value Command::execute() { return doExecute(); } ...@@ -51,5 +53,5 @@ Value Command::execute() { return doExecute(); }
Entity &Command::owner() { return owner_; } Entity &Command::owner() { return owner_; }
std::string Command::getDocstring() const { return docstring_; } std::string Command::getDocstring() const { return docstring_; }
} // namespace command } // namespace command
} // namespace dynamicgraph } // namespace dynamicgraph
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
// //
#include "dynamic-graph/value.h" #include "dynamic-graph/value.h"
#include "dynamic-graph/exception-abstract.h" #include "dynamic-graph/exception-abstract.h"
namespace dynamicgraph { namespace dynamicgraph {
...@@ -21,7 +22,11 @@ EitherType::~EitherType() { ...@@ -21,7 +22,11 @@ EitherType::~EitherType() {
EitherType::operator bool() const { return value_->boolValue(); } EitherType::operator bool() const { return value_->boolValue(); }
EitherType::operator unsigned() const { return value_->unsignedValue(); } EitherType::operator unsigned() const { return value_->unsignedValue(); }
EitherType::operator unsigned long int() const {
return value_->unsignedlongintValue();
}
EitherType::operator int() const { return value_->intValue(); } EitherType::operator int() const { return value_->intValue(); }
EitherType::operator long int() const { return value_->longintValue(); }
EitherType::operator float() const { return value_->floatValue(); } EitherType::operator float() const { return value_->floatValue(); }
EitherType::operator double() const { return value_->doubleValue(); } EitherType::operator double() const { return value_->doubleValue(); }
EitherType::operator std::string() const { return value_->stringValue(); } EitherType::operator std::string() const { return value_->stringValue(); }
...@@ -29,37 +34,51 @@ EitherType::operator Vector() const { return value_->vectorValue(); } ...@@ -29,37 +34,51 @@ EitherType::operator Vector() const { return value_->vectorValue(); }
EitherType::operator Eigen::MatrixXd() const { return value_->matrixXdValue(); } EitherType::operator Eigen::MatrixXd() const { return value_->matrixXdValue(); }
EitherType::operator Eigen::Matrix4d() const { return value_->matrix4dValue(); } EitherType::operator Eigen::Matrix4d() const { return value_->matrix4dValue(); }
EitherType::operator Values() const { return value_->valuesValue(); }
void Value::deleteValue() { void Value::deleteValue() {
switch (type_) { switch (type_) {
case BOOL: case BOOL:
delete (const bool *)value_; delete (const bool *)value_;
break; break;
case UNSIGNED: case UNSIGNED:
delete (const unsigned *)value_; delete (const unsigned *)value_;
break; break;
case INT: case UNSIGNEDLONGINT:
delete (const int *)value_; delete (const unsigned long int *)value_;
break; break;
case FLOAT: case INT:
delete (const float *)value_; delete (const int *)value_;
break; break;
case DOUBLE: case LONGINT:
delete (const double *)value_; delete (const long int *)value_;
break; break;
case STRING: case FLOAT:
delete (const std::string *)value_; delete (const float *)value_;
break; break;
case VECTOR: case DOUBLE:
delete (const Vector *)value_; delete (const double *)value_;
break; break;
case MATRIX: case STRING:
delete (const Eigen::MatrixXd *)value_; delete (const std::string *)value_;
break; break;
case MATRIX4D: case VECTOR:
delete (const Eigen::Matrix4d *)value_; delete (const Vector *)value_;
break; break;
default:; case MATRIX:
delete (const Eigen::MatrixXd *)value_;
break;
case MATRIX4D:
delete (const Eigen::Matrix4d *)value_;
break;
case VALUES:
delete (const Values *)value_;
break;
case NONE: /* Equivalent to void */
break;
default:
throw "Value::deleteValue : Undefined type";
;
} }
} }
...@@ -68,6 +87,8 @@ Value::~Value() { deleteValue(); } ...@@ -68,6 +87,8 @@ Value::~Value() { deleteValue(); }
Value::Value(const bool &value) : type_(BOOL), value_(new bool(value)) {} Value::Value(const bool &value) : type_(BOOL), value_(new bool(value)) {}
Value::Value(const unsigned &value) Value::Value(const unsigned &value)
: type_(UNSIGNED), value_(new unsigned(value)) {} : type_(UNSIGNED), value_(new unsigned(value)) {}
Value::Value(const unsigned long int &value)
: type_(UNSIGNEDLONGINT), value_(new unsigned long int(value)) {}
Value::Value(const int &value) : type_(INT), value_(new int(value)) {} Value::Value(const int &value) : type_(INT), value_(new int(value)) {}
Value::Value(const float &value) : type_(FLOAT), value_(new float(value)) {} Value::Value(const float &value) : type_(FLOAT), value_(new float(value)) {}
Value::Value(const double &value) : type_(DOUBLE), value_(new double(value)) {} Value::Value(const double &value) : type_(DOUBLE), value_(new double(value)) {}
...@@ -78,6 +99,7 @@ Value::Value(const Eigen::MatrixXd &value) ...@@ -78,6 +99,7 @@ Value::Value(const Eigen::MatrixXd &value)
: type_(MATRIX), value_(new Eigen::MatrixXd(value)) {} : type_(MATRIX), value_(new Eigen::MatrixXd(value)) {}
Value::Value(const Eigen::Matrix4d &value) Value::Value(const Eigen::Matrix4d &value)
: type_(MATRIX4D), value_(new Eigen::Matrix4d(value)) {} : type_(MATRIX4D), value_(new Eigen::Matrix4d(value)) {}
Value::Value(const Values &value) : type_(VALUES), value_(new Values(value)) {}
Value::Value(const Value &value) Value::Value(const Value &value)
: type_(value.type_), value_(copyValue(value)) {} : type_(value.type_), value_(copyValue(value)) {}
...@@ -85,39 +107,47 @@ Value::Value(const Value &value) ...@@ -85,39 +107,47 @@ Value::Value(const Value &value)
void *copyValue(const Value &value) { void *copyValue(const Value &value) {
void *copy; void *copy;
switch (value.type()) { switch (value.type()) {
case Value::NONE:
case Value::NONE: copy = NULL;
copy = NULL; break;
break; case Value::BOOL:
case Value::BOOL: copy = new bool(value.boolValue());
copy = new bool(value.boolValue()); break;
break; case Value::UNSIGNED:
case Value::UNSIGNED: copy = new unsigned(value.unsignedValue());
copy = new unsigned(value.unsignedValue()); break;
break; case Value::UNSIGNEDLONGINT:
case Value::INT: copy = new unsigned long int(value.unsignedlongintValue());
copy = new int(value.intValue()); break;
break; case Value::INT:
case Value::FLOAT: copy = new int(value.intValue());
copy = new float(value.floatValue()); break;
break; case Value::LONGINT:
case Value::DOUBLE: copy = new long int(value.longintValue());
copy = new double(value.doubleValue()); break;
break; case Value::FLOAT:
case Value::STRING: copy = new float(value.floatValue());
copy = new std::string(value.stringValue()); break;
break; case Value::DOUBLE:
case Value::VECTOR: copy = new double(value.doubleValue());
copy = new Vector(value.vectorValue()); break;
break; case Value::STRING:
case Value::MATRIX: copy = new std::string(value.stringValue());
copy = new Eigen::MatrixXd(value.matrixXdValue()); break;
break; case Value::VECTOR:
case Value::MATRIX4D: copy = new Vector(value.vectorValue());
copy = new Eigen::Matrix4d(value.matrix4dValue()); break;
break; case Value::MATRIX:
default: copy = new Eigen::MatrixXd(value.matrixXdValue());
abort(); break;
case Value::MATRIX4D:
copy = new Eigen::Matrix4d(value.matrix4dValue());
break;
case Value::VALUES:
copy = new Values(value.valuesValue());
break;
default:
abort();
} }
return copy; return copy;
} }
...@@ -126,8 +156,7 @@ Value::Value() : type_(NONE), value_(NULL) {} ...@@ -126,8 +156,7 @@ Value::Value() : type_(NONE), value_(NULL) {}
Value Value::operator=(const Value &value) { Value Value::operator=(const Value &value) {
if (&value != this) { if (&value != this) {
if (value_ != 0x0) if (value_ != 0x0) deleteValue();
deleteValue();
type_ = value.type_; type_ = value.type_;
void **ptValue = const_cast<void **>(&value_); void **ptValue = const_cast<void **>(&value_);
*ptValue = copyValue(value); *ptValue = copyValue(value);
...@@ -135,27 +164,68 @@ Value Value::operator=(const Value &value) { ...@@ -135,27 +164,68 @@ Value Value::operator=(const Value &value) {
return *this; return *this;
} }
bool Value::operator==(const Value &other) const {
if (type_ != other.type_) return false;
switch (type_) {
case Value::BOOL:
return boolValue() == other.boolValue();
case Value::UNSIGNED:
return unsignedValue() == other.unsignedValue();
case Value::UNSIGNEDLONGINT:
return unsignedlongintValue() == other.unsignedlongintValue();
case Value::INT:
return intValue() == other.intValue();
case Value::DOUBLE:
return doubleValue() == other.doubleValue();
case Value::FLOAT:
return floatValue() == other.floatValue();
case Value::STRING:
return stringValue() == other.stringValue();
case Value::VECTOR:
return vectorValue() == other.vectorValue();
case Value::MATRIX:
return matrixXdValue() == other.matrixXdValue();
case Value::MATRIX4D:
return matrix4dValue() == other.matrix4dValue();
case Value::VALUES:
return constValuesValue() == other.constValuesValue();
case Value::NONE:
break;
default:
break;
}
return false;
}
const EitherType Value::value() const { return EitherType(*this); } const EitherType Value::value() const { return EitherType(*this); }
Value::Type Value::type() const { return type_; } Value::Type Value::type() const { return type_; }
bool Value::boolValue() const { bool Value::boolValue() const {
if (type_ == BOOL) if (type_ == BOOL) return *((const bool *)value_);
return *((const bool *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an bool"); throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an bool");
} }
unsigned Value::unsignedValue() const { unsigned Value::unsignedValue() const {
if (type_ == UNSIGNED) if (type_ == UNSIGNED) return *((const unsigned *)value_);
return *((const unsigned *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an unsigned int"); "value is not an unsigned int");
} }
unsigned long int Value::unsignedlongintValue() const {
if (type_ == UNSIGNEDLONGINT) return *((const unsigned long int *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an unsigned long int");
}
long int Value::longintValue() const {
if (type_ == LONGINT) return *((const long int *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an long int");
}
int Value::intValue() const { int Value::intValue() const {
if (type_ == INT) if (type_ == INT) return *((const int *)value_);
return *((const int *)value_); throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an int");
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an int int");
} }
float Value::floatValue() const { float Value::floatValue() const {
...@@ -175,103 +245,138 @@ double Value::doubleValue() const { ...@@ -175,103 +245,138 @@ double Value::doubleValue() const {
} }
std::string Value::stringValue() const { std::string Value::stringValue() const {
if (type_ == STRING) if (type_ == STRING) return *((const std::string *)value_);
return *((const std::string *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an string"); throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an string");
} }
Vector Value::vectorValue() const { Vector Value::vectorValue() const {
if (type_ == VECTOR) if (type_ == VECTOR) return *((const Vector *)value_);
return *((const Vector *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an vector"); throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an vector");
} }
Eigen::MatrixXd Value::matrixXdValue() const { Eigen::MatrixXd Value::matrixXdValue() const {
if (type_ == MATRIX) if (type_ == MATRIX) return *((const Eigen::MatrixXd *)value_);
return *((const Eigen::MatrixXd *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a Eigen matrixXd"); "value is not a Eigen matrixXd");
} }
Eigen::Matrix4d Value::matrix4dValue() const { Eigen::Matrix4d Value::matrix4dValue() const {
if (type_ == MATRIX4D) if (type_ == MATRIX4D) return *((const Eigen::Matrix4d *)value_);
return *((const Eigen::Matrix4d *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a Eigen matrix4d"); "value is not a Eigen matrix4d");
} }
Values Value::valuesValue() const {
if (type_ == VALUES) return *((const Values *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a vector of Value");
}
const Values &Value::constValuesValue() const {
if (type_ == VALUES) return *((const Values *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a vector of Value");
}
std::string Value::typeName(Type type) { std::string Value::typeName(Type type) {
switch (type) { switch (type) {
case BOOL: case BOOL:
return std::string("bool"); return std::string("bool");
case UNSIGNED: case UNSIGNED:
return std::string("unsigned int"); return std::string("unsigned int");
case INT: case UNSIGNEDLONGINT:
return std::string("int"); return std::string("unsigned long int");
case FLOAT: case INT:
return std::string("float"); return std::string("int");
case DOUBLE: case FLOAT:
return std::string("double"); return std::string("float");
case STRING: case DOUBLE:
return std::string("string"); return std::string("double");
case VECTOR: case STRING:
return std::string("vector"); return std::string("string");
case MATRIX: case VECTOR:
return std::string("matrixXd"); return std::string("vector");
case MATRIX4D: case MATRIX:
return std::string("matrix4d"); return std::string("matrixXd");
default: case MATRIX4D:
return std::string("unknown"); return std::string("matrix4d");
case VALUES:
return std::string("values");
default:
return std::string("unknown");
} }
} }
std::ostream &operator<<(std::ostream &os, const Value &value) { std::ostream &operator<<(std::ostream &os, const Value &value) {
os << "Type=" << Value::typeName(value.type_) << ", value="; os << "Type=" << Value::typeName(value.type_) << ", value=";
switch (value.type_) { switch (value.type_) {
case Value::BOOL: case Value::BOOL:
os << value.boolValue(); os << value.boolValue();
break; break;
case Value::UNSIGNED: case Value::UNSIGNED:
os << value.unsignedValue(); os << value.unsignedValue();
break; break;
case Value::INT: case Value::UNSIGNEDLONGINT:
os << value.intValue(); os << value.unsignedlongintValue();
break; break;
case Value::DOUBLE: case Value::INT:
os << value.doubleValue(); os << value.intValue();
break; break;
case Value::FLOAT: case Value::DOUBLE:
os << value.floatValue(); os << value.doubleValue();
break; break;
case Value::STRING: case Value::FLOAT:
os << value.stringValue(); os << value.floatValue();
break; break;
case Value::VECTOR: case Value::STRING:
os << value.vectorValue(); os << value.stringValue();
break; break;
case Value::MATRIX: case Value::VECTOR:
os << value.matrixXdValue(); os << value.vectorValue();
break; break;
case Value::MATRIX4D: case Value::MATRIX:
os << value.matrix4dValue(); os << value.matrixXdValue();
break; break;
default: case Value::MATRIX4D:
return os; os << value.matrix4dValue();
break;
case Value::VALUES: {
const std::vector<Value> &vals = value.constValuesValue();
os << "[ ";
for (std::size_t i = 0; i < vals.size(); ++i)
os << "Value(" << vals[i] << "), ";
os << "]";
} break;
default:
return os;
} }
return os; return os;
} }
template <> const Value::Type ValueHelper<bool>::TypeID = Value::BOOL; template <>
template <> const Value::Type ValueHelper<unsigned>::TypeID = Value::UNSIGNED; const Value::Type ValueHelper<bool>::TypeID = Value::BOOL;
template <> const Value::Type ValueHelper<int>::TypeID = Value::INT; template <>
template <> const Value::Type ValueHelper<float>::TypeID = Value::FLOAT; const Value::Type ValueHelper<unsigned>::TypeID = Value::UNSIGNED;
template <> const Value::Type ValueHelper<double>::TypeID = Value::DOUBLE; template <>
template <> const Value::Type ValueHelper<std::string>::TypeID = Value::STRING; const Value::Type ValueHelper<unsigned long int>::TypeID =
template <> const Value::Type ValueHelper<Vector>::TypeID = Value::VECTOR; Value::UNSIGNEDLONGINT;
template <>
const Value::Type ValueHelper<int>::TypeID = Value::INT;
template <>
const Value::Type ValueHelper<float>::TypeID = Value::FLOAT;
template <>
const Value::Type ValueHelper<double>::TypeID = Value::DOUBLE;
template <>
const Value::Type ValueHelper<std::string>::TypeID = Value::STRING;
template <>
const Value::Type ValueHelper<Vector>::TypeID = Value::VECTOR;
template <> template <>
const Value::Type ValueHelper<Eigen::MatrixXd>::TypeID = Value::MATRIX; const Value::Type ValueHelper<Eigen::MatrixXd>::TypeID = Value::MATRIX;
template <> template <>
const Value::Type ValueHelper<Eigen::Matrix4d>::TypeID = Value::MATRIX4D; const Value::Type ValueHelper<Eigen::Matrix4d>::TypeID = Value::MATRIX4D;
template <>
const Value::Type ValueHelper<Values>::TypeID = Value::VALUES;
} // namespace command } // namespace command
} // namespace dynamicgraph } // namespace dynamicgraph
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <fstream> #include <fstream>
#include <ios> #include <ios>
...@@ -32,7 +33,7 @@ std::ofstream dg_debugfile("/tmp/dynamic-graph-traces.txt", ...@@ -32,7 +33,7 @@ std::ofstream dg_debugfile("/tmp/dynamic-graph-traces.txt",
#else #else
std::ofstream dg_debugfile; std::ofstream dg_debugfile;
class dgDebug_init { class dgDebug_init {
public: public:
dgDebug_init() { dg_debugfile.setstate(std::ios::failbit); } dgDebug_init() { dg_debugfile.setstate(std::ios::failbit); }
}; };
dgDebug_init dgDebug_initialisator; dgDebug_init dgDebug_initialisator;
...@@ -42,11 +43,10 @@ dgDebug_init dgDebug_initialisator; ...@@ -42,11 +43,10 @@ dgDebug_init dgDebug_initialisator;
namespace dynamicgraph { namespace dynamicgraph {
DebugTrace dgDEBUGFLOW(dg_debugfile); DebugTrace dgDEBUGFLOW(dg_debugfile);
DebugTrace dgERRORFLOW(dg_debugfile); DebugTrace dgERRORFLOW(dg_debugfile);
} // namespace dynamicgraph } // namespace dynamicgraph
void DebugTrace::openFile(const char *filename) { void DebugTrace::openFile(const char *filename) {
if (dg_debugfile.good() && dg_debugfile.is_open()) if (dg_debugfile.good() && dg_debugfile.is_open()) dg_debugfile.close();
dg_debugfile.close();
dg_debugfile.clear(); dg_debugfile.clear();
dg_debugfile.open(filename, std::ios::trunc & std::ios::out); dg_debugfile.open(filename, std::ios::trunc & std::ios::out);
} }
......
...@@ -13,19 +13,18 @@ ...@@ -13,19 +13,18 @@
#define ENABLE_RT_LOG #define ENABLE_RT_LOG
#include <dynamic-graph/logger.h> #include <dynamic-graph/logger.h>
#include <iomanip> // std::setprecision #include <dynamic-graph/real-time-logger.h>
#include <iostream>
#include <sstream>
#include <stdio.h> #include <stdio.h>
#include <dynamic-graph/real-time-logger.h> #include <iomanip> // std::setprecision
#include <iostream>
#include <sstream>
namespace dynamicgraph { namespace dynamicgraph {
using namespace std;
Logger::Logger(double timeSample, double streamPrintPeriod) Logger::Logger(double timeSample, double streamPrintPeriod)
: m_timeSample(timeSample), m_streamPrintPeriod(streamPrintPeriod), : m_timeSample(timeSample),
m_streamPrintPeriod(streamPrintPeriod),
m_printCountdown(0.0) { m_printCountdown(0.0) {
m_lv = VERBOSITY_ERROR; m_lv = VERBOSITY_ERROR;
} }
...@@ -36,55 +35,29 @@ void Logger::setVerbosity(LoggerVerbosity lv) { m_lv = lv; } ...@@ -36,55 +35,29 @@ void Logger::setVerbosity(LoggerVerbosity lv) { m_lv = lv; }
LoggerVerbosity Logger::getVerbosity() { return m_lv; } LoggerVerbosity Logger::getVerbosity() { return m_lv; }
void Logger::countdown() { void Logger::countdown() {
if (m_printCountdown < 0.0) if (m_printCountdown < 0.0) m_printCountdown = m_streamPrintPeriod;
m_printCountdown = m_streamPrintPeriod;
m_printCountdown -= m_timeSample; m_printCountdown -= m_timeSample;
} }
void Logger::sendMsg(string msg, MsgType type, const char *file, int line) { void Logger::sendMsg(std::string msg, MsgType type, const std::string &lineId) {
if (m_lv == VERBOSITY_NONE || stream(type, lineId) << msg << '\n';
(m_lv == VERBOSITY_ERROR && !isErrorMsg(type)) || }
(m_lv == VERBOSITY_WARNING_ERROR &&
!(isWarningMsg(type) || isErrorMsg(type))) || void Logger::sendMsg(std::string msg, MsgType type, const std::string &file,
(m_lv == VERBOSITY_INFO_WARNING_ERROR && isDebugMsg(type))) int line) {
return; std::ostringstream oss;
oss << file << line;
// if print is allowed by current verbosity level stream(type, oss.str()) << msg << '\n';
if (isStreamMsg(type)) {
// check whether counter already exists
std::ostringstream oss;
oss << file << line;
std::string id(oss.str());
map<string, double>::iterator it = m_stream_msg_counters.find(id);
if (it == m_stream_msg_counters.end()) {
// if counter doesn't exist then add one
m_stream_msg_counters.insert(make_pair(id, 0.0));
it = m_stream_msg_counters.find(id);
}
// if counter is greater than 0 then decrement it and do not print
if (it->second > 0.0) {
it->second -= m_timeSample;
if (it->second <= 0.0)
it->second = m_streamPrintPeriod;
else
return;
} else // otherwise reset counter and print
it->second = m_streamPrintPeriod;
}
dgRTLOG() << msg.c_str() << "\n";
} }
bool Logger::setTimeSample(double t) { bool Logger::setTimeSample(double t) {
if (t <= 0.0) if (t <= 0.0) return false;
return false;
m_timeSample = t; m_timeSample = t;
return true; return true;
} }
bool Logger::setStreamPrintPeriod(double s) { bool Logger::setStreamPrintPeriod(double s) {
if (s <= 0.0) if (s <= 0.0) return false;
return false;
m_streamPrintPeriod = s; m_streamPrintPeriod = s;
return true; return true;
} }
...@@ -92,4 +65,21 @@ bool Logger::setStreamPrintPeriod(double s) { ...@@ -92,4 +65,21 @@ bool Logger::setStreamPrintPeriod(double s) {
double Logger::getTimeSample() { return m_timeSample; } double Logger::getTimeSample() { return m_timeSample; }
double Logger::getStreamPrintPeriod() { return m_streamPrintPeriod; } double Logger::getStreamPrintPeriod() { return m_streamPrintPeriod; }
} // namespace dynamicgraph
bool Logger::checkStreamPeriod(const std::string &lineId) {
// insert element with value 0 if it does not exist.
// otherwise, return a counter to the existing one.
std::pair<StreamCounterMap_t::iterator, bool> result =
m_stream_msg_counters.insert(std::make_pair(lineId, 0.));
// if counter is greater than 0 then decrement it and do not print
double &counter = result.first->second;
counter -= m_timeSample;
if (counter > 0.0) {
return false;
} else // otherwise reset counter and print
counter = m_streamPrintPeriod;
return true;
}
} // namespace dynamicgraph
...@@ -13,21 +13,21 @@ ...@@ -13,21 +13,21 @@
namespace dynamicgraph { namespace dynamicgraph {
RealTimeLogger::RealTimeLogger(const std::size_t &bufferSize) RealTimeLogger::RealTimeLogger(const std::size_t &bufferSize)
: buffer_(bufferSize, NULL), frontIdx_(0), backIdx_(0), oss_(NULL), : buffer_(bufferSize, NULL),
frontIdx_(0),
backIdx_(0),
oss_(NULL),
nbDiscarded_(0) { nbDiscarded_(0) {
for (std::size_t i = 0; i < buffer_.size(); ++i) for (std::size_t i = 0; i < buffer_.size(); ++i) buffer_[i] = new Data;
buffer_[i] = new Data;
} }
RealTimeLogger::~RealTimeLogger() { RealTimeLogger::~RealTimeLogger() {
// Check that we are not spinning... // Check that we are not spinning...
for (std::size_t i = 0; i < buffer_.size(); ++i) for (std::size_t i = 0; i < buffer_.size(); ++i) delete buffer_[i];
delete buffer_[i];
} }
bool RealTimeLogger::spinOnce() { bool RealTimeLogger::spinOnce() {
if (empty()) if (empty()) return false;
return false;
Data *data = buffer_[frontIdx_]; Data *data = buffer_[frontIdx_];
frontIdx_ = (frontIdx_ + 1) % buffer_.size(); frontIdx_ = (frontIdx_ + 1) % buffer_.size();
std::string str = data->buf.str(); std::string str = data->buf.str();
...@@ -59,12 +59,6 @@ RTLoggerStream RealTimeLogger::front() { ...@@ -59,12 +59,6 @@ RTLoggerStream RealTimeLogger::front() {
return RTLoggerStream(this, oss_); return RTLoggerStream(this, oss_);
} }
RTLoggerStream::~RTLoggerStream() {
os_ << std::ends;
if (logger_ != NULL)
logger_->frontReady();
}
struct RealTimeLogger::thread { struct RealTimeLogger::thread {
bool requestShutdown_; bool requestShutdown_;
int threadPolicy_; int threadPolicy_;
...@@ -72,22 +66,25 @@ struct RealTimeLogger::thread { ...@@ -72,22 +66,25 @@ struct RealTimeLogger::thread {
bool changedThreadParams; bool changedThreadParams;
boost::thread t_; boost::thread t_;
thread(RealTimeLogger *logger) explicit thread(RealTimeLogger *logger)
: requestShutdown_(false), threadPolicy_(SCHED_OTHER), threadPriority_(0), : requestShutdown_(false),
changedThreadParams(true), t_(&thread::spin, this, logger) {} threadPolicy_(SCHED_OTHER),
threadPriority_(0),
changedThreadParams(true),
t_(&thread::spin, this, logger) {}
void setThreadPolicy(int policy) { // void setThreadPolicy(int policy) {
threadPolicy_ = policy; // threadPolicy_ = policy;
changedThreadParams = true; // changedThreadParams = true;
} // }
void setPriority(int priority) { // void setPriority(int priority) {
threadPriority_ = priority; // threadPriority_ = priority;
changedThreadParams = true; // changedThreadParams = true;
} // }
int getThreadPolicy() { return threadPolicy_; } // int getThreadPolicy() { return threadPolicy_; }
int getThreadPriority() { return threadPriority_; } // int getThreadPriority() { return threadPriority_; }
void changeThreadParams() { void changeThreadParams() {
int threadPolicy; int threadPolicy;
...@@ -113,8 +110,7 @@ struct RealTimeLogger::thread { ...@@ -113,8 +110,7 @@ struct RealTimeLogger::thread {
// Do a pause // Do a pause
if (!logger->spinOnce()) if (!logger->spinOnce())
boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
if (changedThreadParams) if (changedThreadParams) changeThreadParams();
changeThreadParams();
} }
} }
}; };
...@@ -131,11 +127,10 @@ RealTimeLogger &RealTimeLogger::instance() { ...@@ -131,11 +127,10 @@ RealTimeLogger &RealTimeLogger::instance() {
} }
void RealTimeLogger::destroy() { void RealTimeLogger::destroy() {
if (instance_ == NULL) if (instance_ == NULL) return;
return;
thread_->requestShutdown_ = true; thread_->requestShutdown_ = true;
thread_->t_.join(); thread_->t_.join();
delete instance_; delete instance_;
delete thread_; delete thread_;
} }
} // namespace dynamicgraph } // namespace dynamicgraph
...@@ -14,9 +14,10 @@ ...@@ -14,9 +14,10 @@
#include <dynamic-graph/pool.h> #include <dynamic-graph/pool.h>
/*! System includes */ /*! System includes */
#include <sstream>
#include <stdlib.h> #include <stdlib.h>
#include <sstream>
using namespace std; using namespace std;
using namespace dynamicgraph; using namespace dynamicgraph;
using dynamicgraph::command::Command; using dynamicgraph::command::Command;
...@@ -46,7 +47,7 @@ Entity::Entity(const string &name__) : name(name__) { ...@@ -46,7 +47,7 @@ Entity::Entity(const string &name__) : name(name__) {
Entity::~Entity() { Entity::~Entity() {
dgDEBUG(25) << "# In (" << name << " { " << endl; dgDEBUG(25) << "# In (" << name << " { " << endl;
for (std::map<const std::string, Command *>::iterator it = commandMap.begin(); for (std::map<const std::string, Command *>::iterator it = commandMap.begin();
it != commandMap.end(); it++) { it != commandMap.end(); ++it) {
delete it->second; delete it->second;
} }
dgDEBUGOUT(25); dgDEBUGOUT(25);
...@@ -68,7 +69,7 @@ void Entity::signalRegistration(const SignalArray<int> &signals) { ...@@ -68,7 +69,7 @@ void Entity::signalRegistration(const SignalArray<int> &signals) {
const string &signame(buffer); const string &signame(buffer);
SignalMap::iterator sigkey = signalMap.find(signame); SignalMap::iterator sigkey = signalMap.find(signame);
if (sigkey != signalMap.end()) // key does exist if (sigkey != signalMap.end()) // key does exist
{ {
dgERRORF("Key %s already exist in the signalMap.", signame.c_str()); dgERRORF("Key %s already exist in the signalMap.", signame.c_str());
if (sigkey->second != &sig) { if (sigkey->second != &sig) {
...@@ -87,7 +88,7 @@ void Entity::signalRegistration(const SignalArray<int> &signals) { ...@@ -87,7 +88,7 @@ void Entity::signalRegistration(const SignalArray<int> &signals) {
void Entity::signalDeregistration(const std::string &signame) { void Entity::signalDeregistration(const std::string &signame) {
SignalMap::iterator sigkey = signalMap.find(signame); SignalMap::iterator sigkey = signalMap.find(signame);
if (sigkey == signalMap.end()) // key does not exist if (sigkey == signalMap.end()) // key does not exist
{ {
dgERRORF("Key %s does not exist in the signalMap.", signame.c_str()); dgERRORF("Key %s does not exist in the signalMap.", signame.c_str());
throw ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL, throw ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL,
...@@ -105,14 +106,14 @@ std::string Entity::getDocString() const { ...@@ -105,14 +106,14 @@ std::string Entity::getDocString() const {
return docString; return docString;
} }
#define __DG_ENTITY_GET_SIGNAL__(ITER_TYPE) \ #define __DG_ENTITY_GET_SIGNAL__(ITER_TYPE) \
SignalMap::ITER_TYPE sigkey = signalMap.find(signame); \ SignalMap::ITER_TYPE sigkey = signalMap.find(signame); \
if (sigkey == signalMap.end()) /* key does NOT exist */ \ if (sigkey == signalMap.end()) /* key does NOT exist */ \
{ \ { \
throw ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL, \ throw ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL, \
"The requested signal is not registered", ": %s", \ "The requested signal is not registered", ": %s", \
signame.c_str()); \ signame.c_str()); \
} \ } \
return *(sigkey->second); return *(sigkey->second);
bool Entity::hasSignal(const string &signame) const { bool Entity::hasSignal(const string &signame) const {
...@@ -185,9 +186,9 @@ const std::string &Entity::getCommandList() const { ...@@ -185,9 +186,9 @@ const std::string &Entity::getCommandList() const {
/// Add a command to Entity /// Add a command to Entity
void Entity::addCommand(const std::string &inName, Command *command) { void Entity::addCommand(const std::string &inName, Command *command) {
if (commandMap.count(inName) != 0) { if (commandMap.count(inName) != 0) {
DG_THROW ExceptionFactory(ExceptionFactory::OBJECT_CONFLICT, DG_THROW ExceptionFactory(
"Command " + inName + ExceptionFactory::OBJECT_CONFLICT,
" already registered in Entity."); "Command " + inName + " already registered in Entity.");
} }
std::pair<const std::string, Command *> item(inName, command); std::pair<const std::string, Command *> item(inName, command);
commandMap.insert(item); commandMap.insert(item);
...@@ -200,14 +201,14 @@ std::map<const std::string, Command *> Entity::getNewStyleCommandMap() { ...@@ -200,14 +201,14 @@ std::map<const std::string, Command *> Entity::getNewStyleCommandMap() {
Command *Entity::getNewStyleCommand(const std::string &commandName) { Command *Entity::getNewStyleCommand(const std::string &commandName) {
if (commandMap.count(commandName) != 1) { if (commandMap.count(commandName) != 1) {
DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_FUNCTION, DG_THROW ExceptionFactory(
"Command <" + commandName + ExceptionFactory::UNREFERED_FUNCTION,
"> is not registered in Entity."); "Command <" + commandName + "> is not registered in Entity.");
} }
return commandMap[commandName]; return commandMap[commandName];
} }
void Entity::sendMsg(const std::string &msg, MsgType t, const char *file, void Entity::sendMsg(const std::string &msg, MsgType t,
int line) { const std::string &lineId) {
logger_.sendMsg("[" + name + "]" + msg, t, file, line); logger_.stream(t, lineId) << "[" << name << "]" << msg << '\n';
} }
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
// JRL, CNRS/AIST. // JRL, CNRS/AIST.
// //
#include "dynamic-graph/factory.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include "dynamic-graph/debug.h" #include "dynamic-graph/debug.h"
#include "dynamic-graph/factory.h"
using namespace std; using namespace std;
using namespace dynamicgraph; using namespace dynamicgraph;
...@@ -39,9 +40,10 @@ void FactoryStorage::registerEntity(const std::string &entname, ...@@ -39,9 +40,10 @@ void FactoryStorage::registerEntity(const std::string &entname,
"Another entity class already defined with the same name. ", "Another entity class already defined with the same name. ",
"(while adding entity class <%s> inside the factory).", "(while adding entity class <%s> inside the factory).",
entname.c_str()); entname.c_str());
dgERRORF("Another entity class already defined with the same name. " dgERRORF(
"(while adding entity class <%s> inside the factory).", "Another entity class already defined with the same name. "
entname.c_str()); "(while adding entity class <%s> inside the factory).",
entname.c_str());
} else { } else {
if (!ent) { if (!ent) {
// FIXME: we should have a better error code for that. // FIXME: we should have a better error code for that.
...@@ -118,4 +120,4 @@ EntityRegisterer::~EntityRegisterer() { ...@@ -118,4 +120,4 @@ EntityRegisterer::~EntityRegisterer() {
// The global factory. // The global factory.
FactoryStorage *FactoryStorage::instance_ = NULL; FactoryStorage *FactoryStorage::instance_ = NULL;
} // end of namespace dynamicgraph. } // end of namespace dynamicgraph.
...@@ -13,13 +13,15 @@ ...@@ -13,13 +13,15 @@
/* --- DYNAMIC-GRAPH --- */ /* --- DYNAMIC-GRAPH --- */
#include "dynamic-graph/pool.h" #include "dynamic-graph/pool.h"
#include "dynamic-graph/debug.h"
#include "dynamic-graph/entity.h"
#include <list> #include <list>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <typeinfo> #include <typeinfo>
#include "dynamic-graph/debug.h"
#include "dynamic-graph/entity.h"
using namespace dynamicgraph; using namespace dynamicgraph;
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
...@@ -57,7 +59,7 @@ PoolStorage::~PoolStorage() { ...@@ -57,7 +59,7 @@ PoolStorage::~PoolStorage() {
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
void PoolStorage::registerEntity(const std::string &entname, Entity *ent) { void PoolStorage::registerEntity(const std::string &entname, Entity *ent) {
Entities::iterator entkey = entityMap.find(entname); Entities::iterator entkey = entityMap.find(entname);
if (entkey != entityMap.end()) // key does exist if (entkey != entityMap.end()) // key does exist
{ {
throw ExceptionFactory( throw ExceptionFactory(
ExceptionFactory::OBJECT_CONFLICT, ExceptionFactory::OBJECT_CONFLICT,
...@@ -72,7 +74,7 @@ void PoolStorage::registerEntity(const std::string &entname, Entity *ent) { ...@@ -72,7 +74,7 @@ void PoolStorage::registerEntity(const std::string &entname, Entity *ent) {
void PoolStorage::deregisterEntity(const std::string &entname) { void PoolStorage::deregisterEntity(const std::string &entname) {
Entities::iterator entkey = entityMap.find(entname); Entities::iterator entkey = entityMap.find(entname);
if (entkey == entityMap.end()) // key doesnot exist if (entkey == entityMap.end()) // key doesnot exist
{ {
throw ExceptionFactory(ExceptionFactory::OBJECT_CONFLICT, throw ExceptionFactory(ExceptionFactory::OBJECT_CONFLICT,
"Entity not defined yet. ", "Entity name is <%s>.", "Entity not defined yet. ", "Entity name is <%s>.",
...@@ -207,7 +209,7 @@ static bool objectNameParser(std::istringstream &cmdparse, std::string &objName, ...@@ -207,7 +209,7 @@ static bool objectNameParser(std::istringstream &cmdparse, std::string &objName,
char buffer[SIZE]; char buffer[SIZE];
cmdparse >> std::ws; cmdparse >> std::ws;
cmdparse.getline(buffer, SIZE, '.'); cmdparse.getline(buffer, SIZE, '.');
if (!cmdparse.good()) // The callback is not an object method if (!cmdparse.good()) // The callback is not an object method
return false; return false;
objName = buffer; objName = buffer;
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
// JRL, CNRS/AIST. // JRL, CNRS/AIST.
// //
#include <cstring>
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-abstract.h> #include <dynamic-graph/exception-abstract.h>
#include <cstring>
namespace dynamicgraph { namespace dynamicgraph {
const std::string ExceptionAbstract::EXCEPTION_NAME = "Abstract"; const std::string ExceptionAbstract::EXCEPTION_NAME = "Abstract";
...@@ -23,8 +24,7 @@ const std::string &ExceptionAbstract::getStringMessage() const { ...@@ -23,8 +24,7 @@ const std::string &ExceptionAbstract::getStringMessage() const {
int ExceptionAbstract::getCode() const { return this->code; } int ExceptionAbstract::getCode() const { return this->code; }
ExceptionAbstract::Param &ExceptionAbstract::Param::initCopy(const Param &p) { ExceptionAbstract::Param &ExceptionAbstract::Param::initCopy(const Param &p) {
if (&p == this) if (&p == this) return *this;
return *this;
dgDEBUGIN(25); dgDEBUGIN(25);
if (p.pointersSet) { if (p.pointersSet) {
...@@ -53,9 +53,9 @@ std::ostream &operator<<(std::ostream &os, const ExceptionAbstract &error) { ...@@ -53,9 +53,9 @@ std::ostream &operator<<(std::ostream &os, const ExceptionAbstract &error) {
if (error.p.set) if (error.p.set)
os << "Thrown from " << error.p.file << ": " << error.p.function << " (#" os << "Thrown from " << error.p.file << ": " << error.p.function << " (#"
<< error.p.line << ")" << std::endl; << error.p.line << ")" << std::endl;
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM #endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
return os; return os;
} }
} // end of namespace dynamicgraph. } // end of namespace dynamicgraph.
...@@ -7,11 +7,12 @@ ...@@ -7,11 +7,12 @@
* *
*/ */
#include <cstdio>
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-factory.h> #include <dynamic-graph/exception-factory.h>
#include <stdarg.h> #include <stdarg.h>
#include <cstdio>
using namespace dynamicgraph; using namespace dynamicgraph;
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
......
...@@ -7,10 +7,11 @@ ...@@ -7,10 +7,11 @@
* *
*/ */
#include <cstdio>
#include <dynamic-graph/exception-signal.h> #include <dynamic-graph/exception-signal.h>
#include <stdarg.h> #include <stdarg.h>
#include <cstdio>
using namespace dynamicgraph; using namespace dynamicgraph;
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
......
...@@ -7,10 +7,11 @@ ...@@ -7,10 +7,11 @@
* *
*/ */
#include <cstdio>
#include <dynamic-graph/exception-traces.h> #include <dynamic-graph/exception-traces.h>
#include <stdarg.h> #include <stdarg.h>
#include <cstdio>
using namespace dynamicgraph; using namespace dynamicgraph;
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --- CLASS ----------------------------------------------------------- */ /* --- CLASS ----------------------------------------------------------- */
......
...@@ -2,17 +2,24 @@ ...@@ -2,17 +2,24 @@
* Author: O. Stasse, 2019 * Author: O. Stasse, 2019
* See LICENSE file in the root directory of this repository. * See LICENSE file in the root directory of this repository.
*/ */
#include <dynamic-graph/process-list.hh>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <dynamic-graph/process-list.hh>
using namespace dynamicgraph::CPU; using namespace dynamicgraph::CPU;
CPUData::CPUData() CPUData::CPUData()
: user_mode_time_(0), nice_time_(0), system_time_(0), idle_time_(0), : user_mode_time_(0),
iowait_time_(0), irq_time_(0), softirq_time_(0), steal_time_(0), nice_time_(0),
guest_time_(0), guest_nice_time_(0), percent_(0.0) {} system_time_(0),
idle_time_(0),
iowait_time_(0),
irq_time_(0),
softirq_time_(0),
steal_time_(0),
guest_time_(0),
guest_nice_time_(0),
percent_(0.0) {}
void CPUData::ProcessLine(std::istringstream &aCPULine) { void CPUData::ProcessLine(std::istringstream &aCPULine) {
unsigned long long int luser_mode_time = 0, lnice_time = 0, lsystem_time = 0, unsigned long long int luser_mode_time = 0, lnice_time = 0, lsystem_time = 0,
...@@ -129,8 +136,7 @@ void System::readProcStat() { ...@@ -129,8 +136,7 @@ void System::readProcStat() {
// If we did not initialize // If we did not initialize
if (!init_) { if (!init_) {
// Count the number of CPU. // Count the number of CPU.
if (lcpunb > cpuNb_) if (lcpunb > cpuNb_) cpuNb_ = lcpunb;
cpuNb_ = lcpunb;
} else } else
// Otherwise process the line. // Otherwise process the line.
ProcessCPULine(lcpunb, anISSLine); ProcessCPULine(lcpunb, anISSLine);
...@@ -141,8 +147,8 @@ void System::readProcStat() { ...@@ -141,8 +147,8 @@ void System::readProcStat() {
if (!init_) { if (!init_) {
/// The number of CPU has been detected by going through /proc/stat. /// The number of CPU has been detected by going through /proc/stat.
vCPUData_.resize(cpuNb_ + 1); vCPUData_.resize(cpuNb_ + 1);
for (int i = 0; i < (int)cpuNb_; i++) for (unsigned long i = 0; i < (unsigned long)cpuNb_; i++)
vCPUData_[i].cpu_id_ = i; vCPUData_[i].cpu_id_ = (int)i;
} }
aif.close(); aif.close();
} }
// -*- c++-mode -*-
// Copyright 2010 François Bleibel
// Thomas Moulard,
// Olivier Stasse,
// Nicolas Mansard
//
#include <algorithm>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/lambda/bind.hpp>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/signal-cast-helper.h>
#include <dynamic-graph/signal-caster.h>
#include <exception>
#include <sstream>
#include <string>
namespace dynamicgraph {
// Define a custom implementation of the DefaultCastRegisterer
// 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 <>
inline boost::any DefaultCastRegisterer<double>::cast(std::istringstream &iss) {
std::string tmp;
iss >> tmp;
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());
}
}
/* Specialize Matrix and Vector traces. */
template <>
void DefaultCastRegisterer<dynamicgraph::Vector>::trace(
const boost::any &object, std::ostream &os) {
const dynamicgraph::Vector &v = boost::any_cast<dynamicgraph::Vector>(object);
for (int i = 0; i < v.size(); ++i) {
os << "\t" << v(i);
}
}
template <>
void DefaultCastRegisterer<dynamicgraph::Matrix>::trace(
const boost::any &object, std::ostream &os) {
const dynamicgraph::Matrix &m = boost::any_cast<dynamicgraph::Matrix>(object);
for (int i = 0; i < m.rows(); ++i)
for (int j = 0; j < m.cols(); ++j) {
os << "\t" << m(i, j);
}
}
/// Registers useful casts
namespace {
DefaultCastRegisterer<double> double_reg;
DefaultCastRegisterer<int> int_reg;
DefaultCastRegisterer<unsigned int> uint_reg;
DefaultCastRegisterer<bool> bool_reg;
DefaultCastRegisterer<dynamicgraph::Vector> vectorCastRegisterer;
DefaultCastRegisterer<dynamicgraph::Matrix> matrixCastRegisterer;
DefaultCastRegisterer<boost::posix_time::ptime> ptimeCastRegisterer;
} // end of anonymous namespace.
} // namespace dynamicgraph
// -*- c++-mode -*-
// Copyright 2010 François Bleibel
// Thomas Moulard,
// Olivier Stasse
//
#include <algorithm>
#include <boost/lambda/bind.hpp>
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/signal-caster.h>
#include <exception>
#include <sstream>
#include <string>
#include <dynamic-graph/linear-algebra.h>
namespace dynamicgraph {
SignalCaster::SignalCaster() {}
SignalCaster::~SignalCaster() {}
void SignalCaster::destroy() {
delete instance_;
instance_ = 0;
}
void SignalCaster::registerCast(const std::type_info &type,
SignalCaster::displayer_type displayer,
SignalCaster::caster_type caster,
SignalCaster::tracer_type tracer) {
if (existsCast(type)) {
// If type name has already been registered for same type, do not throw.
if (type_info_[type.name()] != &type) {
std::string typeName(type.name());
std::ostringstream os;
os << "cast already registered for typename " << typeName << "\n"
<< "and types differ: " << &type << " != " << type_info_[type.name()]
<< ".\n"
<< "A possible reason is that the dynamic"
<< " library defining this type\n"
<< "has been loaded several times, defining different symbols"
<< " for the same type.";
throw ExceptionSignal(ExceptionSignal::GENERIC, os.str());
}
}
functions_[type.name()] = cast_functions_type(displayer, caster, tracer);
type_info_[type.name()] = &type;
}
void SignalCaster::unregisterCast(const std::type_info &type) {
size_t n = functions_.erase(type.name());
if (0 == n) // erase did not find element
// TODO: throw Cast not registered exception
throw ExceptionSignal(ExceptionSignal::GENERIC);
}
bool SignalCaster::existsCast(const std::type_info &type) const {
return functions_.find(type.name()) != functions_.end();
}
SignalCaster::cast_functions_type &
SignalCaster::getCast(const std::string &type_name) {
std::map<std::string, cast_functions_type>::iterator it =
functions_.find(type_name);
if (it == functions_.end())
// TODO: throw "cast not registered" exception
throw ExceptionSignal(ExceptionSignal::BAD_CAST, "Cast not registered");
return it->second;
}
void SignalCaster::disp(const boost::any &object, std::ostream &os) {
getCast(object.type().name()).get<0>()(object, os);
}
void SignalCaster::trace(const boost::any &object, std::ostream &os) {
getCast(object.type().name()).get<2>()(object, os);
}
std::vector<std::string> SignalCaster::listTypenames() const {
std::vector<std::string> typeList;
for (std::map<std::string, cast_functions_type>::const_iterator iter =
functions_.begin();
iter != functions_.end(); iter++)
typeList.push_back(iter->first);
return typeList;
}
boost::any SignalCaster::cast(const std::type_info &type,
std::istringstream &iss) {
return getCast(type.name()).get<1>()(iss);
}
/// Singleton on the library-wide instance of SignalCaster
SignalCaster *SignalCaster::getInstance(void) {
if (instance_ == 0) {
instance_ = new SignalCaster;
}
return instance_;
}
SignalCaster *SignalCaster::instance_ = 0;
} // namespace dynamicgraph
...@@ -12,15 +12,15 @@ ...@@ -12,15 +12,15 @@
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* DG */ /* DG */
#include <boost/bind.hpp>
#include <iomanip>
#include <dynamic-graph/all-commands.h> #include <dynamic-graph/all-commands.h>
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <dynamic-graph/factory.h> #include <dynamic-graph/factory.h>
#include <dynamic-graph/pool.h> #include <dynamic-graph/pool.h>
#include <dynamic-graph/tracer-real-time.h> #include <dynamic-graph/tracer-real-time.h>
#include <boost/bind.hpp>
#include <iomanip>
using namespace std; using namespace std;
using namespace dynamicgraph; using namespace dynamicgraph;
...@@ -103,7 +103,7 @@ TracerRealTime::TracerRealTime(const std::string &n) ...@@ -103,7 +103,7 @@ TracerRealTime::TracerRealTime(const std::string &n)
addCommand("setBufferSize", addCommand("setBufferSize",
makeDirectSetter(*this, &bufferSize, makeDirectSetter(*this, &bufferSize,
docDirectSetter("bufferSize", "int"))); docDirectSetter("bufferSize", "int")));
} // using namespace command } // using namespace command
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
...@@ -125,12 +125,18 @@ void TracerRealTime::openFile(const SignalBase<int> &sig, ...@@ -125,12 +125,18 @@ void TracerRealTime::openFile(const SignalBase<int> &sig,
string filename = rootdir + basename + signame + suffix; string filename = rootdir + basename + signame + suffix;
dgDEBUG(5) << "Sig <" << sig.getName() << ">: new file " << filename << endl; dgDEBUG(5) << "Sig <" << sig.getName() << ">: new file " << filename << endl;
std::ofstream *newfile = new std::ofstream(filename.c_str()); std::ofstream *newfile = new std::ofstream(filename.c_str());
if (!newfile->good()) {
delete newfile;
DG_THROW ExceptionTraces(
ExceptionTraces::NOT_OPEN,
"Could not open file " + filename + " for signal " + signame, "");
}
dgDEBUG(5) << "Newfile:" << (void *)newfile << endl; dgDEBUG(5) << "Newfile:" << (void *)newfile << endl;
hardFiles.push_back(newfile); hardFiles.push_back(newfile);
dgDEBUG(5) << "Creating Outstringstream" << endl; dgDEBUG(5) << "Creating Outstringstream" << endl;
// std::stringstream * newbuffer = new std::stringstream (); // std::stringstream * newbuffer = new std::stringstream ();
OutStringStream *newbuffer = new OutStringStream(); // std::stringstream (); OutStringStream *newbuffer = new OutStringStream(); // std::stringstream ();
newbuffer->resize(bufferSize); newbuffer->resize(bufferSize);
newbuffer->givenname = givenname; newbuffer->givenname = givenname;
files.push_back(newbuffer); files.push_back(newbuffer);
...@@ -140,6 +146,7 @@ void TracerRealTime::openFile(const SignalBase<int> &sig, ...@@ -140,6 +146,7 @@ void TracerRealTime::openFile(const SignalBase<int> &sig,
void TracerRealTime::closeFiles() { void TracerRealTime::closeFiles() {
dgDEBUGIN(15); dgDEBUGIN(15);
std::lock_guard<std::mutex> files_lock(files_mtx);
FileList::iterator iter = files.begin(); FileList::iterator iter = files.begin();
HardFileList::iterator hardIter = hardFiles.begin(); HardFileList::iterator hardIter = hardFiles.begin();
...@@ -180,7 +187,7 @@ void TracerRealTime::trace() { ...@@ -180,7 +187,7 @@ void TracerRealTime::trace() {
""); "");
} }
// std::stringstream & file = * dynamic_cast< stringstream* >(os); // std::stringstream & file = * dynamic_cast< stringstream* >(os);
OutStringStream *file = dynamic_cast<OutStringStream *>(os); // segfault OutStringStream *file = dynamic_cast<OutStringStream *>(os); // segfault
if (NULL == file) { if (NULL == file) {
DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
"The buffer is not open", ""); "The buffer is not open", "");
...@@ -193,29 +200,9 @@ void TracerRealTime::trace() { ...@@ -193,29 +200,9 @@ void TracerRealTime::trace() {
} }
if ((hardFile.good()) && (NULL != file)) { if ((hardFile.good()) && (NULL != file)) {
// const unsigned int SIZE = 1024*8;
// char buffer[SIZE];
// streambuf * pbuf = file.rdbuf ();
// pbuf->pubseekpos(0);
// const unsigned int NB_BYTE = pbuf->in_avail ();
// dgDEBUG(35) << "Bytes in buffer: " << NB_BYTE << endl;
// //dgDEBUG(35) << "Copie" <<endl<<file.str ()<< endl;
// for( unsigned int index=0;index<NB_BYTE;index+=SIZE )
// {
// pbuf->pubseekpos( index );
// int nget = pbuf->sgetn( buffer,SIZE );
// dgDEBUG(35) << "Copie ["<<nget<<"] " <<buffer<<endl;
// hardFile.write( buffer,nget );
// }
// hardFile << file.str () << flush;
// file.seekp(0);
file->dump(hardFile); file->dump(hardFile);
file->empty(); file->empty();
hardFile.flush(); hardFile.flush();
// file.str("");
} }
++iter; ++iter;
...@@ -241,13 +228,6 @@ void TracerRealTime::emptyBuffers() { ...@@ -241,13 +228,6 @@ void TracerRealTime::emptyBuffers() {
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
// void TracerRealTime::
// emptyBuffer( std::stringstream & file )
// {
// streambuf * pbuf = file.rdbuf ();
// pbuf->file.rdbuf () ->pubsetbuf( fileBuffer,10 );
// }
void TracerRealTime::recordSignal(std::ostream &os, void TracerRealTime::recordSignal(std::ostream &os,
const SignalBase<int> &sig) { const SignalBase<int> &sig) {
dgDEBUGIN(15); dgDEBUGIN(15);
...@@ -264,7 +244,7 @@ void TracerRealTime::recordSignal(std::ostream &os, ...@@ -264,7 +244,7 @@ void TracerRealTime::recordSignal(std::ostream &os,
<< "> " << endl; << "> " << endl;
} catch (ExceptionAbstract &exc) { } catch (ExceptionAbstract &exc) {
throw exc; throw;
} catch (...) { } catch (...) {
DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
"The buffer is not open", ""); "The buffer is not open", "");
...@@ -289,8 +269,7 @@ void TracerRealTime::display(std::ostream &os) const { ...@@ -289,8 +269,7 @@ void TracerRealTime::display(std::ostream &os) const {
dgDEBUG(35) << "Next" << endl; dgDEBUG(35) << "Next" << endl;
const OutStringStream *file = dynamic_cast<OutStringStream *>(*iterFile); const OutStringStream *file = dynamic_cast<OutStringStream *>(*iterFile);
os << " -> " << (*iter)->getName(); os << " -> " << (*iter)->getName();
if (file->givenname.length()) if (file->givenname.length()) os << " (in " << file->givenname << ")";
os << " (in " << file->givenname << ")";
os << "\t"; os << "\t";
if (file) { if (file) {
const std::streamsize PRECISION = os.precision(); const std::streamsize PRECISION = os.precision();
...@@ -312,12 +291,11 @@ void TracerRealTime::display(std::ostream &os) const { ...@@ -312,12 +291,11 @@ void TracerRealTime::display(std::ostream &os) const {
<< (((double)SIZE + 0.0) / (1 << dec)) << unit << "/" << (((double)SIZE + 0.0) / (1 << dec)) << unit << "/"
<< std::setprecision(2) << (((double)MSIZE + 0.0) / (1 << dec)) << unit << std::setprecision(2) << (((double)MSIZE + 0.0) / (1 << dec)) << unit
<< "]\t"; << "]\t";
if (file->full) if (file->full) os << "(FULL)";
os << "(FULL)";
os.precision(PRECISION); os.precision(PRECISION);
} }
os << endl; os << endl;
iterFile++; ++iterFile;
} }
} }
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* DG */ /* DG */
#include <boost/bind.hpp>
#include <dynamic-graph/all-commands.h> #include <dynamic-graph/all-commands.h>
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <dynamic-graph/factory.h> #include <dynamic-graph/factory.h>
...@@ -20,6 +19,8 @@ ...@@ -20,6 +19,8 @@
#include <dynamic-graph/tracer.h> #include <dynamic-graph/tracer.h>
#include <dynamic-graph/value.h> #include <dynamic-graph/value.h>
#include <boost/bind.hpp>
using namespace std; using namespace std;
using namespace dynamicgraph; using namespace dynamicgraph;
using namespace dynamicgraph::command; using namespace dynamicgraph::command;
...@@ -31,9 +32,18 @@ DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(Tracer, "Tracer"); ...@@ -31,9 +32,18 @@ DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(Tracer, "Tracer");
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
Tracer::Tracer(const std::string n) Tracer::Tracer(const std::string n)
: Entity(n), toTraceSignals(), traceStyle(TRACE_STYLE_DEFAULT), : Entity(n),
frequency(1), basename(), suffix(".dat"), rootdir(), namesSet(false), toTraceSignals(),
files(), names(), play(false), timeStart(0), traceStyle(TRACE_STYLE_DEFAULT),
frequency(1),
basename(),
suffix(".dat"),
rootdir(),
namesSet(false),
files(),
names(),
play(false),
timeStart(0),
triger(boost::bind(&Tracer::recordTrigger, this, _1, _2), sotNOSIGNAL, triger(boost::bind(&Tracer::recordTrigger, this, _1, _2), sotNOSIGNAL,
"Tracer(" + n + ")::triger") { "Tracer(" + n + ")::triger") {
signalRegistration(triger); signalRegistration(triger);
...@@ -62,8 +72,9 @@ Tracer::Tracer(const std::string n) ...@@ -62,8 +72,9 @@ Tracer::Tracer(const std::string n)
doc = docCommandVoid0("Close all the open files."); doc = docCommandVoid0("Close all the open files.");
addCommand("close", makeCommandVoid0(*this, &Tracer::closeFiles, doc)); addCommand("close", makeCommandVoid0(*this, &Tracer::closeFiles, doc));
doc = docCommandVoid0("If necessary, dump " doc = docCommandVoid0(
"(can be done automatically for some traces type)."); "If necessary, dump "
"(can be done automatically for some traces type).");
addCommand("dump", makeCommandVoid0(*this, &Tracer::trace, doc)); addCommand("dump", makeCommandVoid0(*this, &Tracer::trace, doc));
doc = docCommandVoid0("Start the tracing process."); doc = docCommandVoid0("Start the tracing process.");
...@@ -78,7 +89,7 @@ Tracer::Tracer(const std::string n) ...@@ -78,7 +89,7 @@ Tracer::Tracer(const std::string n)
addCommand("setTimeStart", addCommand("setTimeStart",
makeDirectSetter(*this, &timeStart, makeDirectSetter(*this, &timeStart,
docDirectSetter("timeStart", "int"))); docDirectSetter("timeStart", "int")));
} // using namespace command } // using namespace command
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
...@@ -88,11 +99,11 @@ Tracer::Tracer(const std::string n) ...@@ -88,11 +99,11 @@ Tracer::Tracer(const std::string n)
void Tracer::addSignalToTrace(const SignalBase<int> &sig, void Tracer::addSignalToTrace(const SignalBase<int> &sig,
const string &filename) { const string &filename) {
dgDEBUGIN(15); dgDEBUGIN(15);
// openFile may throw so it should be called first.
if (namesSet) openFile(sig, filename);
toTraceSignals.push_back(&sig); toTraceSignals.push_back(&sig);
dgDEBUGF(15, "%p", &sig); dgDEBUGF(15, "%p", &sig);
names.push_back(filename); names.push_back(filename);
if (namesSet)
openFile(sig, filename);
triger.addDependency(sig); triger.addDependency(sig);
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
...@@ -128,14 +139,12 @@ void Tracer::openFiles(const std::string &rootdir_, ...@@ -128,14 +139,12 @@ void Tracer::openFiles(const std::string &rootdir_,
dgDEBUGIN(15); dgDEBUGIN(15);
std::basic_string<char>::size_type n = rootdir_.length(); std::basic_string<char>::size_type n = rootdir_.length();
rootdir = rootdir_; rootdir = rootdir_;
if ((0 < n) & ('/' != rootdir[n - 1])) if ((0 < n) & ('/' != rootdir[n - 1])) rootdir += '/';
rootdir += '/';
basename = basename_; basename = basename_;
suffix = suffix_; suffix = suffix_;
if (files.size()) if (files.size()) closeFiles();
closeFiles();
SignalList::const_iterator iter = toTraceSignals.begin(); SignalList::const_iterator iter = toTraceSignals.begin();
NameList::const_iterator iterName = names.begin(); NameList::const_iterator iterName = names.begin();
...@@ -170,6 +179,7 @@ void Tracer::openFile(const SignalBase<int> &sig, const string &givenname) { ...@@ -170,6 +179,7 @@ void Tracer::openFile(const SignalBase<int> &sig, const string &givenname) {
void Tracer::closeFiles() { void Tracer::closeFiles() {
dgDEBUGIN(15); dgDEBUGIN(15);
std::lock_guard<std::mutex> files_lock(files_mtx);
for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) { for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) {
std::ostream *filePtr = *iter; std::ostream *filePtr = *iter;
...@@ -192,6 +202,14 @@ void Tracer::record() { ...@@ -192,6 +202,14 @@ void Tracer::record() {
dgDEBUGIN(15); dgDEBUGIN(15);
// Ensure record() never hangs. If the attempt to acquire the lock fails,
// then closeFiles() is active and we shouldn't write to files anyways.
std::unique_lock<std::mutex> files_lock(files_mtx, std::try_to_lock);
if (!files_lock.owns_lock()) {
dgDEBUGOUT(15);
return;
}
if (files.size() != toTraceSignals.size()) { if (files.size() != toTraceSignals.size()) {
DG_THROW DG_THROW
ExceptionTraces(ExceptionTraces::NOT_OPEN, "No files open for tracing", ExceptionTraces(ExceptionTraces::NOT_OPEN, "No files open for tracing",
......
# Copyright 2010, Olivier Stasse, JRL, CNRS/AIST # Copyright 2010-2020, Olivier Stasse, Guilhem Saurel, JRL, CNRS/AIST, LAAS-CNRS
#
ADD_DEFINITIONS(-DDEBUG=2) add_definitions(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
# Add Boost path to include directories. add_definitions(-DTESTS_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data")
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) add_definitions(-DTESTS_PLUGINDIR="${LIBRARY_OUTPUT_PATH}")
add_definitions(-DTESTS_DYNLIBSUFFIX="${CMAKE_SHARED_LIBRARY_SUFFIX}")
# Make Boost.Test generates the main function in test cases.
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
ADD_DEFINITIONS(-DTESTS_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data")
ADD_DEFINITIONS(-DTESTS_PLUGINDIR="${LIBRARY_OUTPUT_PATH}")
ADD_DEFINITIONS(-DTESTS_DYNLIBSUFFIX="${CMAKE_SHARED_LIBRARY_SUFFIX}")
# DYNAMIC_GRAPH_TEST(NAME)
# ------------------------
#
# Define a test named `NAME'.
#
# This macro will create a binary from `NAME.cpp', link it against
# Boost and add it to the test suite.
#
MACRO(DYNAMIC_GRAPH_TEST NAME)
ADD_EXECUTABLE(${NAME} ${NAME}.cpp)
ADD_TEST(${NAME} ${RUNTIME_OUTPUT_DIRECTORY}/${NAME})
TARGET_LINK_LIBRARIES(${NAME} ${PROJECT_NAME})
ADD_DEPENDENCIES(${NAME} ${PROJECT_NAME})
# Link against Boost.
TARGET_LINK_LIBRARIES(${NAME} ${Boost_LIBRARIES})
ENDMACRO(DYNAMIC_GRAPH_TEST)
macro(DYNAMIC_GRAPH_TEST NAME)
add_unit_test(${NAME} "${NAME}.cpp")
target_link_libraries(${NAME} PRIVATE ${PROJECT_NAME}
Boost::unit_test_framework)
endmacro(DYNAMIC_GRAPH_TEST)
# Signal cast test. # Signal cast test.
SET(signalcast_libs signal-cast-registerer-libA signal-cast-registerer-libB) set(signalcast_libs signal-cast-registerer-libA signal-cast-registerer-libB)
FOREACH(lib ${signalcast_libs}) foreach(lib ${signalcast_libs})
ADD_LIBRARY(${lib} SHARED ${lib}.cpp) add_library(${lib} SHARED "${lib}.cpp")
target_link_libraries(${lib} PRIVATE ${PROJECT_NAME})
endforeach()
TARGET_LINK_LIBRARIES(${lib} ${PROJECT_NAME}) dynamic_graph_test(signal-cast-registerer)
ADD_DEPENDENCIES(${lib} ${PROJECT_NAME})
ENDFOREACH()
DYNAMIC_GRAPH_TEST(signal-cast-registerer)
# Unit testing. # Unit testing.
IF(NOT APPLE) if(NOT APPLE)
DYNAMIC_GRAPH_TEST(entity) dynamic_graph_test(entity)
ENDIF(NOT APPLE) endif(NOT APPLE)
DYNAMIC_GRAPH_TEST(custom-entity) dynamic_graph_test(custom-entity)
DYNAMIC_GRAPH_TEST(factory) dynamic_graph_test(factory)
DYNAMIC_GRAPH_TEST(pool) dynamic_graph_test(pool)
DYNAMIC_GRAPH_TEST(signal-time-dependent) dynamic_graph_test(signal-time-dependent)
DYNAMIC_GRAPH_TEST(value) dynamic_graph_test(value)
DYNAMIC_GRAPH_TEST(signal-ptr) dynamic_graph_test(signal-ptr)
DYNAMIC_GRAPH_TEST(real-time-logger) dynamic_graph_test(real-time-logger)
DYNAMIC_GRAPH_TEST(debug-trace) dynamic_graph_test(debug-trace)
DYNAMIC_GRAPH_TEST(debug-tracer) dynamic_graph_test(debug-tracer)
TARGET_LINK_LIBRARIES(debug-tracer tracer) target_link_libraries(debug-tracer PRIVATE tracer)
DYNAMIC_GRAPH_TEST(debug-logger) dynamic_graph_test(debug-real-time-tracer)
DYNAMIC_GRAPH_TEST(debug-logger-winit) target_link_libraries(debug-real-time-tracer PRIVATE tracer-real-time tracer)
DYNAMIC_GRAPH_TEST(signal-all) dynamic_graph_test(debug-logger)
DYNAMIC_GRAPH_TEST(command-test) dynamic_graph_test(debug-logger-winit)
DYNAMIC_GRAPH_TEST(test-mt) dynamic_graph_test(signal-all)
TARGET_LINK_LIBRARIES(test-mt tracer) dynamic_graph_test(command-test)
\ No newline at end of file dynamic_graph_test(test-mt)
target_link_libraries(test-mt PRIVATE tracer)
dynamic_graph_test(exceptions)
...@@ -5,21 +5,27 @@ ...@@ -5,21 +5,27 @@
* See LICENSE file * See LICENSE file
* *
*/ */
#include "dynamic-graph/command-bind.h"
#include "dynamic-graph/factory.h"
#include "dynamic-graph/pool.h"
#include <dynamic-graph/entity.h> #include <dynamic-graph/entity.h>
#include <dynamic-graph/exception-factory.h> #include <dynamic-graph/exception-factory.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "dynamic-graph/command-bind.h"
#include "dynamic-graph/factory.h"
#include "dynamic-graph/pool.h"
#define ENABLE_RT_LOG #define ENABLE_RT_LOG
#include <dynamic-graph/logger.h> #include <dynamic-graph/logger.h>
#include <dynamic-graph/real-time-logger.h> #include <dynamic-graph/real-time-logger.h>
#define BOOST_TEST_MODULE debug - logger #define BOOST_TEST_MODULE debug - logger
#if BOOST_VERSION >= 105900
#include <boost/test/tools/output_test_stream.hpp>
#else
#include <boost/test/output_test_stream.hpp> #include <boost/test/output_test_stream.hpp>
#endif
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
using boost::test_tools::output_test_stream; using boost::test_tools::output_test_stream;
...@@ -28,21 +34,25 @@ using namespace dynamicgraph::command; ...@@ -28,21 +34,25 @@ using namespace dynamicgraph::command;
namespace dynamicgraph { namespace dynamicgraph {
class CustomEntity : public Entity { class CustomEntity : public Entity {
public: public:
static const std::string CLASS_NAME; static const std::string CLASS_NAME;
bool test_zero_arg_; bool test_zero_arg_;
bool test_one_arg_; bool test_one_arg_;
bool test_two_args_; bool test_two_args_;
bool test_three_args_; bool test_three_args_;
bool test_four_args_; bool test_four_args_;
bool test_one_arg_ret_;
bool test_two_args_ret_;
virtual const std::string &getClassName() const { return CLASS_NAME; } virtual const std::string &getClassName() const { return CLASS_NAME; }
CustomEntity(const std::string n) : Entity(n) { explicit CustomEntity(const std::string &n) : Entity(n) {
test_zero_arg_ = false; test_zero_arg_ = false;
test_one_arg_ = false; test_one_arg_ = false;
test_two_args_ = false; test_two_args_ = false;
test_three_args_ = false; test_three_args_ = false;
test_four_args_ = false; test_four_args_ = false;
test_one_arg_ret_ = false;
test_two_args_ret_ = false;
addCommand("0_arg", makeCommandVoid0(*this, &CustomEntity::zero_arg, addCommand("0_arg", makeCommandVoid0(*this, &CustomEntity::zero_arg,
docCommandVoid0("zero arg"))); docCommandVoid0("zero arg")));
...@@ -62,6 +72,29 @@ public: ...@@ -62,6 +72,29 @@ public:
makeCommandVoid4( makeCommandVoid4(
*this, &CustomEntity::four_args, *this, &CustomEntity::four_args,
docCommandVoid4("four args", "int", "int", "int", "int"))); docCommandVoid4("four args", "int", "int", "int", "int")));
addCommand("1_arg_r",
makeCommandReturnType1(*this, &CustomEntity::one_arg_ret,
docCommandVoid1("one arg", "int")));
addCommand("2_args_r", makeCommandReturnType2(
*this, &CustomEntity::two_args_ret,
docCommandVoid2("two args", "int", "int")));
addCommand(
"cmd_verbose",
makeCommandVerbose(*this, &CustomEntity::cmd_verbose,
docCommandVerbose("Display some information")));
/// Generating an exception by adding a command which already exist
bool res = false;
std::string e_1_arg("1_arg");
try {
addCommand(e_1_arg, getNewStyleCommand(e_1_arg));
} catch (dynamicgraph::ExceptionFactory &aef) {
res = (aef.getCode() == dynamicgraph::ExceptionFactory::OBJECT_CONFLICT);
}
BOOST_CHECK(res);
} }
~CustomEntity() {} ~CustomEntity() {}
...@@ -79,15 +112,31 @@ public: ...@@ -79,15 +112,31 @@ public:
void four_args(const int &, const int &, const int &, const int &) { void four_args(const int &, const int &, const int &, const int &) {
test_four_args_ = true; test_four_args_ = true;
} }
int one_arg_ret(const int &) {
test_one_arg_ret_ = true;
return 2;
}
std::string two_args_ret(const int &, const int &) {
test_two_args_ret_ = true;
return std::string("return");
}
void cmd_verbose(std::ostream &oss) {
std::string as("print verbose");
oss << as;
}
}; };
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CustomEntity, "CustomEntity"); DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CustomEntity, "CustomEntity");
} // namespace dynamicgraph } // namespace dynamicgraph
BOOST_AUTO_TEST_CASE(command_test) { BOOST_AUTO_TEST_CASE(command_test) {
dynamicgraph::CustomEntity &entity = dynamicgraph::CustomEntity *ptr_entity =
*(dynamic_cast<dynamicgraph::CustomEntity *>( (dynamic_cast<dynamicgraph::CustomEntity *>(
dynamicgraph::FactoryStorage::getInstance()->newEntity("CustomEntity", dynamicgraph::FactoryStorage::getInstance()->newEntity("CustomEntity",
"my-entity"))); "my-entity")));
dynamicgraph::CustomEntity &entity = *ptr_entity;
std::map<const std::string, Command *> aCommandMap = std::map<const std::string, Command *> aCommandMap =
entity.getNewStyleCommandMap(); entity.getNewStyleCommandMap();
...@@ -95,8 +144,7 @@ BOOST_AUTO_TEST_CASE(command_test) { ...@@ -95,8 +144,7 @@ BOOST_AUTO_TEST_CASE(command_test) {
std::map<const std::string, Command *>::iterator it_map; std::map<const std::string, Command *>::iterator it_map;
it_map = aCommandMap.find("0_arg"); it_map = aCommandMap.find("0_arg");
if (it_map == aCommandMap.end()) if (it_map == aCommandMap.end()) BOOST_CHECK(false);
BOOST_CHECK(false);
it_map->second->execute(); it_map->second->execute();
BOOST_CHECK(entity.test_zero_arg_); BOOST_CHECK(entity.test_zero_arg_);
...@@ -111,15 +159,81 @@ BOOST_AUTO_TEST_CASE(command_test) { ...@@ -111,15 +159,81 @@ BOOST_AUTO_TEST_CASE(command_test) {
for (unsigned int i = 0; i < 4; i++) { for (unsigned int i = 0; i < 4; i++) {
it_map = aCommandMap.find(vec_fname[i]); it_map = aCommandMap.find(vec_fname[i]);
if (it_map == aCommandMap.end()) if (it_map == aCommandMap.end()) BOOST_CHECK(false);
BOOST_CHECK(false);
values.push_back(aValue); values.push_back(aValue);
it_map->second->setParameterValues(values); it_map->second->setParameterValues(values);
it_map->second->execute(); it_map->second->execute();
it_map->second->owner();
it_map->second->getDocstring();
} }
BOOST_CHECK(entity.test_one_arg_); BOOST_CHECK(entity.test_one_arg_);
BOOST_CHECK(entity.test_two_args_); BOOST_CHECK(entity.test_two_args_);
BOOST_CHECK(entity.test_three_args_); BOOST_CHECK(entity.test_three_args_);
BOOST_CHECK(entity.test_four_args_); BOOST_CHECK(entity.test_four_args_);
// With return type.
vec_fname.clear();
vec_fname.push_back(std::string("1_arg_r"));
vec_fname.push_back(std::string("2_args_r"));
values.clear();
for (unsigned int i = 0; i < 2; i++) {
it_map = aCommandMap.find(vec_fname[i]);
if (it_map == aCommandMap.end()) {
BOOST_CHECK(false);
exit(-1);
}
values.push_back(aValue);
it_map->second->setParameterValues(values);
Value aValue = it_map->second->execute();
it_map->second->owner();
it_map->second->getDocstring();
}
BOOST_CHECK(entity.test_one_arg_ret_);
BOOST_CHECK(entity.test_two_args_ret_);
std::vector<Value> values_two;
values_two.push_back(aValue);
/// Wrong number of arguments
bool res = false;
it_map = aCommandMap.find(std::string("2_args"));
try {
it_map->second->setParameterValues(values_two);
} catch (const dynamicgraph::ExceptionAbstract &aea) {
res = (aea.getCode() == dynamicgraph::ExceptionAbstract::ABSTRACT);
}
BOOST_CHECK(res);
double snd_arg_db = 10.0;
Value aValue2(snd_arg_db);
values_two.push_back(aValue2);
/// Wrong types of arguments
res = false;
it_map = aCommandMap.find(std::string("2_args"));
try {
it_map->second->setParameterValues(values_two);
} catch (const dynamicgraph::ExceptionAbstract &aea) {
res = (aea.getCode() == dynamicgraph::ExceptionAbstract::TOOLS);
}
BOOST_CHECK(res);
/// Try to find the command 1_arg
res = false;
entity.getNewStyleCommand(vec_fname[0]);
BOOST_CHECK(true);
/// Generate an exception by searching a command with an empty name.w
std::string empty("");
try {
entity.getNewStyleCommand(empty);
} catch (dynamicgraph::ExceptionFactory &aef) {
res = (aef.getCode() == dynamicgraph::ExceptionFactory::UNREFERED_FUNCTION);
}
BOOST_CHECK(res);
/// delete the entity.
delete ptr_entity;
} }
...@@ -5,11 +5,16 @@ ...@@ -5,11 +5,16 @@
#include <dynamic-graph/exception-factory.h> #include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/factory.h> #include <dynamic-graph/factory.h>
#include <dynamic-graph/pool.h> #include <dynamic-graph/pool.h>
#include <sstream> #include <sstream>
#define BOOST_TEST_MODULE customEntity #define BOOST_TEST_MODULE customEntity
#if BOOST_VERSION >= 105900
#include <boost/test/tools/output_test_stream.hpp>
#else
#include <boost/test/output_test_stream.hpp> #include <boost/test/output_test_stream.hpp>
#endif
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
using boost::test_tools::output_test_stream; using boost::test_tools::output_test_stream;
...@@ -19,7 +24,7 @@ struct CustomEntity : public dynamicgraph::Entity { ...@@ -19,7 +24,7 @@ struct CustomEntity : public dynamicgraph::Entity {
virtual const std::string &getClassName() const { return CLASS_NAME; } virtual const std::string &getClassName() const { return CLASS_NAME; }
CustomEntity(const std::string n) : Entity(n) {} explicit CustomEntity(const std::string &n) : Entity(n) {}
virtual ~CustomEntity() {} virtual ~CustomEntity() {}
......