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 1434 additions and 2229 deletions
...@@ -3,80 +3,55 @@ ...@@ -3,80 +3,55 @@
// //
// Author: Florent Lamiraux // Author: Florent Lamiraux
// //
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
// dynamic-graph is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details. You should
// have received a copy of the GNU Lesser General Public License along
// with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <sstream>
#include "dynamic-graph/command.h" #include "dynamic-graph/command.h"
#include "dynamic-graph/exception-abstract.h"
namespace dynamicgraph {
namespace command {
const std::vector<Value::Type> Command::EMPTY_ARG = std::vector<Value::Type>(); #include <sstream>
Command::~Command() {}
Command::Command(Entity& entity,
const std::vector<Value::Type>& valueTypes,
const std::string& docstring) :
owner_(entity), valueTypeVector_(valueTypes), docstring_(docstring)
{
}
const std::vector<Value::Type>& Command::valueTypes() const #include "dynamic-graph/exception-abstract.h"
{
return valueTypeVector_;
}
void Command::setParameterValues(const std::vector<Value>& values) namespace dynamicgraph {
{ namespace command {
const std::vector<Value::Type>& paramTypes = valueTypes();
// Check that number of parameters is correct const std::vector<Value::Type> Command::EMPTY_ARG = std::vector<Value::Type>();
if (values.size() != paramTypes.size()) {
throw ExceptionAbstract(ExceptionAbstract::ABSTRACT, Command::~Command() {}
"wrong number of parameters"); Command::Command(Entity &entity, const std::vector<Value::Type> &valueTypes,
} const std::string &docstring)
// Check that each parameter is of correct type : owner_(entity), valueTypeVector_(valueTypes), docstring_(docstring) {}
for (unsigned int iParam=0; iParam < values.size(); iParam++) {
if (values[iParam].type() != paramTypes[iParam]) { const std::vector<Value::Type> &Command::valueTypes() const {
std::stringstream ss; return valueTypeVector_;
ss << "argument " << iParam << " is of wrong type: " }
<< Value::typeName(paramTypes[iParam]) << " expected, got "
<< Value::typeName(values[iParam].type()); void Command::setParameterValues(const std::vector<Value> &values) {
throw ExceptionAbstract(ExceptionAbstract::TOOLS, ss.str()); const std::vector<Value::Type> &paramTypes = valueTypes();
} // Check that number of parameters is correct
} if (values.size() != paramTypes.size()) {
// Copy vector of values in private part throw ExceptionAbstract(ExceptionAbstract::ABSTRACT,
valueVector_ = values; "wrong number of parameters");
}
// Check that each parameter is of correct type
for (unsigned int iParam = 0; iParam < values.size(); iParam++) {
if (values[iParam].type() != paramTypes[iParam]) {
std::stringstream ss;
ss << "argument " << iParam
<< " is of wrong type: " << Value::typeName(paramTypes[iParam])
<< " expected, got " << Value::typeName(values[iParam].type());
throw ExceptionAbstract(ExceptionAbstract::TOOLS, ss.str());
} }
}
// Copy vector of values in private part
valueVector_ = values;
}
const std::vector<Value>& Command::getParameterValues() const const std::vector<Value> &Command::getParameterValues() const {
{ return valueVector_;
return valueVector_; }
}
Value Command::execute() Value Command::execute() { return doExecute(); }
{
return doExecute();
}
Entity& Command::owner() Entity &Command::owner() { return owner_; }
{ std::string Command::getDocstring() const { return docstring_; }
return owner_; } // namespace command
} } // namespace dynamicgraph
std::string Command::getDocstring() const
{
return docstring_;
}
} // namespace command
} //namespace dynamicgraph
...@@ -3,369 +3,380 @@ ...@@ -3,369 +3,380 @@
// //
// Author: Florent Lamiraux // Author: Florent Lamiraux
// //
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
// dynamic-graph is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details. You should
// have received a copy of the GNU Lesser General Public License along
// with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#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 {
namespace command { namespace command {
static void* copyValue(const Value& value); static void *copyValue(const Value &value);
EitherType::EitherType(const Value& value) : value_(new Value(value)) EitherType::EitherType(const Value &value) : value_(new Value(value)) {}
{
} EitherType::~EitherType() {
delete value_;
EitherType::~EitherType() value_ = NULL;
{ }
delete value_;
value_ = NULL; EitherType::operator bool() const { return value_->boolValue(); }
} EitherType::operator unsigned() const { return value_->unsignedValue(); }
EitherType::operator unsigned long int() const {
EitherType::operator bool() const return value_->unsignedlongintValue();
{ }
return value_->boolValue(); EitherType::operator int() const { return value_->intValue(); }
} EitherType::operator long int() const { return value_->longintValue(); }
EitherType::operator unsigned() const EitherType::operator float() const { return value_->floatValue(); }
{ EitherType::operator double() const { return value_->doubleValue(); }
return value_->unsignedValue(); EitherType::operator std::string() const { return value_->stringValue(); }
} EitherType::operator Vector() const { return value_->vectorValue(); }
EitherType::operator int() const EitherType::operator Eigen::MatrixXd() const { return value_->matrixXdValue(); }
{
return value_->intValue(); EitherType::operator Eigen::Matrix4d() const { return value_->matrix4dValue(); }
} EitherType::operator Values() const { return value_->valuesValue(); }
EitherType::operator float() const
{ void Value::deleteValue() {
return value_->floatValue(); switch (type_) {
} case BOOL:
EitherType::operator double() const delete (const bool *)value_;
{ break;
return value_->doubleValue(); case UNSIGNED:
} delete (const unsigned *)value_;
EitherType::operator std::string() const break;
{ case UNSIGNEDLONGINT:
return value_->stringValue(); delete (const unsigned long int *)value_;
} break;
EitherType::operator Vector() const case INT:
{ delete (const int *)value_;
return value_->vectorValue(); break;
} case LONGINT:
EitherType::operator Eigen::MatrixXd() const delete (const long int *)value_;
{ break;
return value_->matrixXdValue(); case FLOAT:
} delete (const float *)value_;
break;
EitherType::operator Eigen::Matrix4d() const case DOUBLE:
{ delete (const double *)value_;
return value_->matrix4dValue(); break;
} case STRING:
delete (const std::string *)value_;
void Value::deleteValue () break;
{ case VECTOR:
switch(type_) { delete (const Vector *)value_;
case BOOL: break;
delete(const bool*)value_; case MATRIX:
break; delete (const Eigen::MatrixXd *)value_;
case UNSIGNED: break;
delete(const unsigned*)value_; case MATRIX4D:
break; delete (const Eigen::Matrix4d *)value_;
case INT: break;
delete(const int*)value_; case VALUES:
break; delete (const Values *)value_;
case FLOAT: break;
delete(const float*)value_; case NONE: /* Equivalent to void */
break; break;
case DOUBLE: default:
delete(const double*)value_; throw "Value::deleteValue : Undefined type";
break; ;
case STRING: }
delete(const std::string*)value_; }
break;
case VECTOR: Value::~Value() { deleteValue(); }
delete(const Vector*)value_;
break; Value::Value(const bool &value) : type_(BOOL), value_(new bool(value)) {}
case MATRIX: Value::Value(const unsigned &value)
delete(const Eigen::MatrixXd*)value_; : type_(UNSIGNED), value_(new unsigned(value)) {}
break; Value::Value(const unsigned long int &value)
case MATRIX4D: : type_(UNSIGNEDLONGINT), value_(new unsigned long int(value)) {}
delete(const Eigen::Matrix4d*)value_; Value::Value(const int &value) : type_(INT), value_(new int(value)) {}
break; Value::Value(const float &value) : type_(FLOAT), value_(new float(value)) {}
default:; Value::Value(const double &value) : type_(DOUBLE), value_(new double(value)) {}
} Value::Value(const std::string &value)
} : type_(STRING), value_(new std::string(value)) {}
Value::Value(const Vector &value) : type_(VECTOR), value_(new Vector(value)) {}
Value::~Value() Value::Value(const Eigen::MatrixXd &value)
{ : type_(MATRIX), value_(new Eigen::MatrixXd(value)) {}
deleteValue (); Value::Value(const Eigen::Matrix4d &value)
} : type_(MATRIX4D), value_(new Eigen::Matrix4d(value)) {}
Value::Value(const Values &value) : type_(VALUES), value_(new Values(value)) {}
Value::Value(const bool& value) : type_(BOOL), value_(new bool(value))
{ Value::Value(const Value &value)
} : type_(value.type_), value_(copyValue(value)) {}
Value::Value(const unsigned& value) : type_(UNSIGNED),
value_(new unsigned(value)) void *copyValue(const Value &value) {
{ void *copy;
} switch (value.type()) {
Value::Value(const int& value) : type_(INT), case Value::NONE:
value_(new int(value)) copy = NULL;
{ break;
} case Value::BOOL:
Value::Value(const float& value) : type_(FLOAT), copy = new bool(value.boolValue());
value_(new float(value)) break;
{ case Value::UNSIGNED:
} copy = new unsigned(value.unsignedValue());
Value::Value(const double& value) : type_(DOUBLE), break;
value_(new double(value)) case Value::UNSIGNEDLONGINT:
{ copy = new unsigned long int(value.unsignedlongintValue());
} break;
Value::Value(const std::string& value) : type_(STRING), case Value::INT:
value_(new std::string(value)) copy = new int(value.intValue());
{ break;
} case Value::LONGINT:
Value::Value(const Vector& value) : type_(VECTOR), copy = new long int(value.longintValue());
value_(new Vector(value)) break;
{ case Value::FLOAT:
} copy = new float(value.floatValue());
Value::Value(const Eigen::MatrixXd& value) : type_(MATRIX), break;
value_(new Eigen::MatrixXd(value)) case Value::DOUBLE:
{ copy = new double(value.doubleValue());
} break;
Value::Value(const Eigen::Matrix4d& value) : type_(MATRIX4D), case Value::STRING:
value_(new Eigen::Matrix4d(value)) copy = new std::string(value.stringValue());
{ break;
} case Value::VECTOR:
copy = new Vector(value.vectorValue());
break;
Value::Value(const Value& value) : type_(value.type_), case Value::MATRIX:
value_(copyValue(value)) copy = new Eigen::MatrixXd(value.matrixXdValue());
{ break;
} case Value::MATRIX4D:
copy = new Eigen::Matrix4d(value.matrix4dValue());
void* copyValue(const Value& value) break;
{ case Value::VALUES:
void* copy; copy = new Values(value.valuesValue());
switch(value.type()) { break;
case Value::NONE: default:
copy = NULL; abort();
case Value::BOOL: }
copy = new bool(value.boolValue()); return copy;
break; }
case Value::UNSIGNED:
copy = new unsigned(value.unsignedValue()); Value::Value() : type_(NONE), value_(NULL) {}
break;
case Value::INT: Value Value::operator=(const Value &value) {
copy = new int(value.intValue()); if (&value != this) {
break; if (value_ != 0x0) deleteValue();
case Value::FLOAT: type_ = value.type_;
copy = new float(value.floatValue()); void **ptValue = const_cast<void **>(&value_);
break; *ptValue = copyValue(value);
case Value::DOUBLE: }
copy = new double(value.doubleValue()); return *this;
break; }
case Value::STRING:
copy = new std::string(value.stringValue()); bool Value::operator==(const Value &other) const {
break; if (type_ != other.type_) return false;
case Value::VECTOR: switch (type_) {
copy = new Vector(value.vectorValue()); case Value::BOOL:
break; return boolValue() == other.boolValue();
case Value::MATRIX: case Value::UNSIGNED:
copy = new Eigen::MatrixXd(value.matrixXdValue()); return unsignedValue() == other.unsignedValue();
break; case Value::UNSIGNEDLONGINT:
case Value::MATRIX4D: return unsignedlongintValue() == other.unsignedlongintValue();
copy = new Eigen::Matrix4d(value.matrix4dValue()); case Value::INT:
break; return intValue() == other.intValue();
default: case Value::DOUBLE:
abort(); return doubleValue() == other.doubleValue();
} case Value::FLOAT:
return copy; return floatValue() == other.floatValue();
} case Value::STRING:
return stringValue() == other.stringValue();
Value::Value() : type_(NONE), value_(NULL) case Value::VECTOR:
{ return vectorValue() == other.vectorValue();
} case Value::MATRIX:
return matrixXdValue() == other.matrixXdValue();
Value Value::operator=(const Value& value) case Value::MATRIX4D:
{ return matrix4dValue() == other.matrix4dValue();
if (&value != this) { case Value::VALUES:
if(value_ != 0x0) return constValuesValue() == other.constValuesValue();
deleteValue (); case Value::NONE:
type_ = value.type_; break;
void** ptValue = const_cast<void**>(&value_); default:
*ptValue = copyValue(value); break;
} }
return *this; return false;
} }
const EitherType Value::value() const const EitherType Value::value() const { return EitherType(*this); }
{
return EitherType(*this); Value::Type Value::type() const { return type_; }
}
bool Value::boolValue() const {
Value::Type Value::type() const if (type_ == BOOL) return *((const bool *)value_);
{ throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an bool");
return type_; }
}
unsigned Value::unsignedValue() const {
bool Value::boolValue() const if (type_ == UNSIGNED) return *((const unsigned *)value_);
{ throw ExceptionAbstract(ExceptionAbstract::TOOLS,
if(type_ == BOOL) "value is not an unsigned int");
return *((const bool*)value_); }
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an bool"); unsigned long int Value::unsignedlongintValue() const {
} if (type_ == UNSIGNEDLONGINT) return *((const unsigned long int *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
unsigned Value::unsignedValue() const "value is not an unsigned long int");
{ }
if(type_ == UNSIGNED)
return *((const unsigned*)value_); long int Value::longintValue() const {
throw ExceptionAbstract(ExceptionAbstract::TOOLS, if (type_ == LONGINT) return *((const long int *)value_);
"value is not an unsigned int"); throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an long int");
} }
int Value::intValue() const int Value::intValue() const {
{ if (type_ == INT) return *((const int *)value_);
if(type_ == INT) throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an int");
return *((const int*)value_); }
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an int int"); float Value::floatValue() const {
} float result;
if (FLOAT != type_)
float Value::floatValue() const throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a float");
{ result = *((const float *)value_);
float result; return result;
if(FLOAT != type_) }
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a float"); double Value::doubleValue() const {
result = *((const float*)value_); double result;
return result; if (DOUBLE != type_)
} throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a double");
result = *((const double *)value_);
double Value::doubleValue() const return result;
{ }
double result;
if(DOUBLE != type_) std::string Value::stringValue() const {
throw ExceptionAbstract(ExceptionAbstract::TOOLS, if (type_ == STRING) return *((const std::string *)value_);
"value is not a double"); throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an string");
result = *((const double*)value_); }
return result;
} Vector Value::vectorValue() const {
if (type_ == VECTOR) return *((const Vector *)value_);
std::string Value::stringValue() const throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an vector");
{ }
if(type_ == STRING)
return *((const std::string*)value_); Eigen::MatrixXd Value::matrixXdValue() const {
throw ExceptionAbstract(ExceptionAbstract::TOOLS, if (type_ == MATRIX) return *((const Eigen::MatrixXd *)value_);
"value is not an string"); throw ExceptionAbstract(ExceptionAbstract::TOOLS,
} "value is not a Eigen matrixXd");
}
Vector Value::vectorValue() const
{ Eigen::Matrix4d Value::matrix4dValue() const {
if(type_ == VECTOR) if (type_ == MATRIX4D) return *((const Eigen::Matrix4d *)value_);
return *((const Vector*)value_); throw ExceptionAbstract(ExceptionAbstract::TOOLS,
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a Eigen matrix4d");
"value is not an vector"); }
}
Values Value::valuesValue() const {
Eigen::MatrixXd Value::matrixXdValue() const if (type_ == VALUES) return *((const Values *)value_);
{ throw ExceptionAbstract(ExceptionAbstract::TOOLS,
if(type_ == MATRIX) "value is not a vector of Value");
return *((const Eigen::MatrixXd*)value_); }
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a Eigen matrixXd"); const Values &Value::constValuesValue() const {
} if (type_ == VALUES) return *((const Values *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
Eigen::Matrix4d Value::matrix4dValue() const "value is not a vector of Value");
{ }
if(type_ == MATRIX4D)
return *((const Eigen::Matrix4d*)value_); std::string Value::typeName(Type type) {
throw ExceptionAbstract(ExceptionAbstract::TOOLS, switch (type) {
"value is not a Eigen matrix4d"); case BOOL:
} return std::string("bool");
case UNSIGNED:
std::string Value::typeName(Type type) return std::string("unsigned int");
{ case UNSIGNEDLONGINT:
switch(type) { return std::string("unsigned long int");
case BOOL: case INT:
return std::string("bool"); return std::string("int");
case UNSIGNED: case FLOAT:
return std::string("unsigned int"); return std::string("float");
case INT: case DOUBLE:
return std::string("int"); return std::string("double");
case FLOAT: case STRING:
return std::string("float"); return std::string("string");
case DOUBLE: case VECTOR:
return std::string("double"); return std::string("vector");
case STRING: case MATRIX:
return std::string("string"); return std::string("matrixXd");
case VECTOR: case MATRIX4D:
return std::string("vector"); return std::string("matrix4d");
case MATRIX: case VALUES:
return std::string("matrixXd"); return std::string("values");
case MATRIX4D: default:
return std::string("matrix4d"); return std::string("unknown");
default: }
return std::string("unknown"); }
}
} std::ostream &operator<<(std::ostream &os, const Value &value) {
os << "Type=" << Value::typeName(value.type_) << ", value=";
std::ostream& operator<<(std::ostream& os, const Value& value) switch (value.type_) {
{ case Value::BOOL:
os << "Type=" << Value::typeName(value.type_) os << value.boolValue();
<< ", value="; break;
switch(value.type_) { case Value::UNSIGNED:
case Value::BOOL: os << value.unsignedValue();
os << value.boolValue(); break;
break; case Value::UNSIGNEDLONGINT:
case Value::UNSIGNED: os << value.unsignedlongintValue();
os << value.unsignedValue(); break;
break; case Value::INT:
case Value::INT: os << value.intValue();
os << value.intValue(); break;
break; case Value::DOUBLE:
case Value::DOUBLE: os << value.doubleValue();
os << value.doubleValue(); break;
break; case Value::FLOAT:
case Value::FLOAT: os << value.floatValue();
os << value.floatValue(); break;
break; case Value::STRING:
case Value::STRING: os << value.stringValue();
os << value.stringValue(); break;
break; case Value::VECTOR:
case Value::VECTOR: os << value.vectorValue();
os << value.vectorValue(); break;
break; case Value::MATRIX:
case Value::MATRIX: os << value.matrixXdValue();
os << value.matrixXdValue(); break;
break; case Value::MATRIX4D:
case Value::MATRIX4D: os << value.matrix4dValue();
os << value.matrix4dValue(); break;
break; case Value::VALUES: {
default: const std::vector<Value> &vals = value.constValuesValue();
return os; 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<> const Value::Type ValueHelper<unsigned>::TypeID = Value::UNSIGNED;
template<> const Value::Type ValueHelper<int>::TypeID = Value::INT; template <>
template<> const Value::Type ValueHelper<float>::TypeID = Value::FLOAT; const Value::Type ValueHelper<bool>::TypeID = Value::BOOL;
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>::TypeID = Value::UNSIGNED;
template<> const Value::Type ValueHelper<Vector>::TypeID = Value::VECTOR; template <>
template<> const Value::Type ValueHelper<Eigen::MatrixXd>::TypeID = Value::MATRIX; const Value::Type ValueHelper<unsigned long int>::TypeID =
template<> const Value::Type ValueHelper<Eigen::Matrix4d>::TypeID = Value::MATRIX4D; Value::UNSIGNEDLONGINT;
template <>
} // namespace command const Value::Type ValueHelper<int>::TypeID = Value::INT;
} //namespace dynamicgraph 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 <>
const Value::Type ValueHelper<Eigen::MatrixXd>::TypeID = Value::MATRIX;
template <>
const Value::Type ValueHelper<Eigen::Matrix4d>::TypeID = Value::MATRIX4D;
template <>
const Value::Type ValueHelper<Values>::TypeID = Value::VALUES;
} // namespace command
} // namespace dynamicgraph
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <dynamic-graph/contiifstream.h>
#include <dynamic-graph/debug.h>
namespace dynamicgraph
{
Contiifstream::Contiifstream (const std::string& n)
: filename (n),
cursor (0),
first (true)
{}
Contiifstream::~Contiifstream ()
{
dgDEBUGINOUT(5);
}
bool
Contiifstream::loop ()
{
dgDEBUGIN(25);
bool res = false;
std::fstream file (filename.c_str ());
file.seekg (cursor);
file.sync ();
while(1)
{
file.get (buffer,BUFFER_SIZE);
if (file.gcount ())
{
res = true;
std::string line (buffer);
if (! first)
reader.push_back (line);
cursor=file.tellg ();
++cursor;
file.get (*buffer); // get the last char ( = '\n')
dgDEBUG(15) << "line: "<< line<<std::endl;
}
else
break;
}
first = false;
dgDEBUGOUT(25);
return res;
}
std::string
Contiifstream::next ()
{
std::string res = *reader.begin ();
reader.pop_front ();
return res;
}
} // end of namespace dynamicgraph.
...@@ -5,71 +5,55 @@ ...@@ -5,71 +5,55 @@
* *
* CNRS/AIST * CNRS/AIST
* *
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <fstream> #include <fstream>
#include <ios> #include <ios>
using namespace dynamicgraph; using namespace dynamicgraph;
#ifdef WIN32 #ifdef WIN32
const char * DebugTrace::DEBUG_FILENAME_DEFAULT = "c:/tmp/dynamic-graph-traces.txt"; const char *DebugTrace::DEBUG_FILENAME_DEFAULT =
#else /*WIN32*/ "c:/tmp/dynamic-graph-traces.txt";
const char * DebugTrace::DEBUG_FILENAME_DEFAULT = "/tmp/dynamic-graph-traces.txt"; #else /*WIN32*/
#endif /*WIN32*/ const char *DebugTrace::DEBUG_FILENAME_DEFAULT =
"/tmp/dynamic-graph-traces.txt";
#endif /*WIN32*/
#ifdef VP_DEBUG #ifdef VP_DEBUG
#ifdef WIN32 #ifdef WIN32
std::ofstream dg_debugfile( "C:/tmp/dynamic-graph-traces.txt", std::ios::trunc&std::ios::out ); std::ofstream dg_debugfile("C:/tmp/dynamic-graph-traces.txt",
#else /*WIN32*/ std::ios::trunc &std::ios::out);
std::ofstream dg_debugfile( "/tmp/dynamic-graph-traces.txt", std::ios::trunc&std::ios::out ); #else /*WIN32*/
#endif /*WIN32*/ std::ofstream dg_debugfile("/tmp/dynamic-graph-traces.txt",
std::ios::trunc &std::ios::out);
#endif /*WIN32*/
#else #else
std::ofstream dg_debugfile; //( "/dev/null", std::ios::trunc&std::ios::out ); std::ofstream dg_debugfile;
class dgDebug_init class dgDebug_init {
{
public: public:
dgDebug_init () dgDebug_init() { dg_debugfile.setstate(std::ios::failbit); }
{ dg_debugfile.setstate( std::ios::failbit ) ; /* dg_debugfile.close (); */ } };
}; dgDebug_init dgDebug_initialisator;
dgDebug_init dgDebug_initialisator;
#endif #endif
namespace dynamicgraph { namespace dynamicgraph {
DebugTrace dgDEBUGFLOW(dg_debugfile); DebugTrace dgDEBUGFLOW(dg_debugfile);
DebugTrace dgERRORFLOW(dg_debugfile); DebugTrace dgERRORFLOW(dg_debugfile);
} // namespace dynamicgraph
void DebugTrace::openFile(const char *filename) {
if (dg_debugfile.good() && dg_debugfile.is_open()) dg_debugfile.close();
dg_debugfile.clear();
dg_debugfile.open(filename, std::ios::trunc & std::ios::out);
} }
void DebugTrace::openFile( const char * filename ) void DebugTrace::closeFile(const char *) {
{ 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.open( filename, std::ios::trunc&std::ios::out ); dg_debugfile.setstate(std::ios::failbit);
//std::cout << filename << dg_debugfile.good () << dg_debugfile.is_open () << std::endl;
} }
void DebugTrace::closeFile(const char *)
{
if( dg_debugfile.good ()&&dg_debugfile.is_open () ) { dg_debugfile.close (); }
dg_debugfile.setstate( std::ios::failbit ) ;
}
//DebugTrace dgDebugFLOW(std::cout);
//DebugTrace dgERRORFLOW(std::cerr);
/*
* Copyright 2015, 2019
* LAAS-CNRS
* Andrea Del Prete, François Bailly, Olivier Stasse
*
*/
#ifndef WIN32
#include <sys/time.h>
#else
#include <Windows.h>
#endif
#define ENABLE_RT_LOG
#include <dynamic-graph/logger.h>
#include <dynamic-graph/real-time-logger.h>
#include <stdio.h>
#include <iomanip> // std::setprecision
#include <iostream>
#include <sstream>
namespace dynamicgraph {
Logger::Logger(double timeSample, double streamPrintPeriod)
: m_timeSample(timeSample),
m_streamPrintPeriod(streamPrintPeriod),
m_printCountdown(0.0) {
m_lv = VERBOSITY_ERROR;
}
Logger::~Logger() {}
void Logger::setVerbosity(LoggerVerbosity lv) { m_lv = lv; }
LoggerVerbosity Logger::getVerbosity() { return m_lv; }
void Logger::countdown() {
if (m_printCountdown < 0.0) m_printCountdown = m_streamPrintPeriod;
m_printCountdown -= m_timeSample;
}
void Logger::sendMsg(std::string msg, MsgType type, const std::string &lineId) {
stream(type, lineId) << msg << '\n';
}
void Logger::sendMsg(std::string msg, MsgType type, const std::string &file,
int line) {
std::ostringstream oss;
oss << file << line;
stream(type, oss.str()) << msg << '\n';
}
bool Logger::setTimeSample(double t) {
if (t <= 0.0) return false;
m_timeSample = t;
return true;
}
bool Logger::setStreamPrintPeriod(double s) {
if (s <= 0.0) return false;
m_streamPrintPeriod = s;
return true;
}
double Logger::getTimeSample() { return m_timeSample; }
double Logger::getStreamPrintPeriod() { return m_streamPrintPeriod; }
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
/*
* Copyright 2018,
* Joseph Mirabel
*
* LAAS-CNRS
*
*/
#include <dynamic-graph/real-time-logger.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
namespace dynamicgraph {
RealTimeLogger::RealTimeLogger(const std::size_t &bufferSize)
: buffer_(bufferSize, NULL),
frontIdx_(0),
backIdx_(0),
oss_(NULL),
nbDiscarded_(0) {
for (std::size_t i = 0; i < buffer_.size(); ++i) buffer_[i] = new Data;
}
RealTimeLogger::~RealTimeLogger() {
// Check that we are not spinning...
for (std::size_t i = 0; i < buffer_.size(); ++i) delete buffer_[i];
}
bool RealTimeLogger::spinOnce() {
if (empty()) return false;
Data *data = buffer_[frontIdx_];
frontIdx_ = (frontIdx_ + 1) % buffer_.size();
std::string str = data->buf.str();
// It is important to pass str.c_str() and not str
// because the str object may contains a '\0' so
// str.size() may be different from strlen(str.c_str())
for (std::size_t i = 0; i < outputs_.size(); ++i)
outputs_[i]->write(str.c_str());
return true;
}
RTLoggerStream RealTimeLogger::front() {
// If no output or if buffer is full, discard message.
if (outputs_.empty() || full()) {
nbDiscarded_++;
return RTLoggerStream(NULL, oss_);
}
bool alone = wmutex.try_lock();
// If someone is writting, discard message.
if (!alone) {
nbDiscarded_++;
return RTLoggerStream(NULL, oss_);
}
Data *data = buffer_[backIdx_];
// backIdx_ = (backIdx_+1) % buffer_.size();
// Reset position of cursor
data->buf.pubseekpos(0);
oss_.rdbuf(&data->buf);
return RTLoggerStream(this, oss_);
}
struct RealTimeLogger::thread {
bool requestShutdown_;
int threadPolicy_;
int threadPriority_;
bool changedThreadParams;
boost::thread t_;
explicit thread(RealTimeLogger *logger)
: requestShutdown_(false),
threadPolicy_(SCHED_OTHER),
threadPriority_(0),
changedThreadParams(true),
t_(&thread::spin, this, logger) {}
// void setThreadPolicy(int policy) {
// threadPolicy_ = policy;
// changedThreadParams = true;
// }
// void setPriority(int priority) {
// threadPriority_ = priority;
// changedThreadParams = true;
// }
// int getThreadPolicy() { return threadPolicy_; }
// int getThreadPriority() { return threadPriority_; }
void changeThreadParams() {
int threadPolicy;
struct sched_param threadParam;
if (pthread_getschedparam(pthread_self(), &threadPolicy, &threadParam) ==
0) {
threadPolicy = threadPolicy_;
threadParam.sched_priority = threadPriority_;
if (threadParam.sched_priority < sched_get_priority_min(threadPolicy))
threadParam.sched_priority = sched_get_priority_min(threadPolicy);
pthread_setschedparam(pthread_self(), threadPolicy, &threadParam);
changedThreadParams = false;
}
}
void spin(RealTimeLogger *logger) {
// Change the thread's scheduler from real-time to normal
// and reduce its priority
while (!requestShutdown_ || !logger->empty()) {
// If the logger did not write anything, it means the buffer is empty.
// Do a pause
if (!logger->spinOnce())
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
if (changedThreadParams) changeThreadParams();
}
}
};
RealTimeLogger *RealTimeLogger::instance_ = NULL;
RealTimeLogger::thread *RealTimeLogger::thread_ = NULL;
RealTimeLogger &RealTimeLogger::instance() {
if (instance_ == NULL) {
instance_ = new RealTimeLogger(1000);
thread_ = new thread(instance_);
}
return *instance_;
}
void RealTimeLogger::destroy() {
if (instance_ == NULL) return;
thread_->requestShutdown_ = true;
thread_->t_.join();
delete instance_;
delete thread_;
}
} // namespace dynamicgraph
...@@ -5,70 +5,49 @@ ...@@ -5,70 +5,49 @@
* *
* CNRS/AIST * CNRS/AIST
* *
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/ */
/*! Local framework includes */ /*! Local framework includes */
#include <dynamic-graph/command.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/entity.h> #include <dynamic-graph/entity.h>
#include <dynamic-graph/pool.h> #include <dynamic-graph/pool.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/command.h>
/*! System includes */ /*! System includes */
#include <stdlib.h> #include <stdlib.h>
#include <sstream>
#include <sstream>
using namespace std; using namespace std;
using namespace dynamicgraph; using namespace dynamicgraph;
using dynamicgraph::command::Command; using dynamicgraph::command::Command;
void Entity:: void Entity::entityRegistration() {
entityRegistration () PoolStorage::getInstance()->registerEntity(name, this);
{
PoolStorage::getInstance()->registerEntity(name,this);
} }
void Entity:: void Entity::entityDeregistration() {
entityDeregistration ()
{
PoolStorage::getInstance()->deregisterEntity(name); PoolStorage::getInstance()->deregisterEntity(name);
} }
Entity:: Entity::Entity(const string &name__) : name(name__) {
Entity( const string& name__ ) dgDEBUG(15) << "New entity <" << name__ << ">" << endl;
: name(name__) if (name.length() == 0) {
{ stringstream oss;
dgDEBUG(15) << "New entity <"<<name__<<">"<<endl; oss << rand();
if( name.length ()==0 ) // name = this->getClassName();
{ // Cannot call a virtual function from the constructor
stringstream oss; oss << rand (); name += "::";
//name = this->getClassName(); Cannot call a virtual function from the constructor name += oss.str();
name+="::"; }
name+=oss.str ();
}
entityRegistration (); entityRegistration();
} }
Entity:: Entity::~Entity() {
~Entity ()
{
dgDEBUG(25) << "# In (" << name << " { " << endl; dgDEBUG(25) << "# In (" << name << " { " << endl;
for (std::map<const std::string, Command*>::iterator it = for (std::map<const std::string, Command *>::iterator it = commandMap.begin();
commandMap.begin(); it != commandMap.end(); it++) { it != commandMap.end(); ++it) {
delete it->second; delete it->second;
} }
dgDEBUGOUT(25); dgDEBUGOUT(25);
...@@ -77,243 +56,159 @@ Entity:: ...@@ -77,243 +56,159 @@ Entity::
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* --- SIGNALS -------------------------------------------------------------- */ /* --- SIGNALS -------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
void Entity:: void Entity::signalRegistration(const SignalArray<int> &signals) {
signalRegistration( const SignalArray<int>& signals ) for (unsigned int i = 0; i < signals.getSize(); ++i) {
{ SignalBase<int> &sig = signals[i];
for( unsigned int i=0;i<signals.getSize ();++i ) // const string& signame = sig.getName ();
{ istringstream iss(sig.getName());
SignalBase<int>& sig = signals[i]; const int SIZE = 128;
//const string& signame = sig.getName (); char buffer[SIZE];
istringstream iss( sig.getName () ); while (iss.good()) {
const int SIZE = 128; iss.getline(buffer, SIZE, ':');
char buffer[SIZE];
while( iss.good () )
{ iss.getline(buffer,SIZE,':'); }
const string& signame( buffer );
SignalMap::iterator sigkey = signalMap.find(signame);
if( sigkey != signalMap.end () ) // key does exist
{
dgERRORF( "Key %s already exist in the signalMap.",signame.c_str () );
if( sigkey->second!=&sig )
{
throw ExceptionFactory( ExceptionFactory::SIGNAL_CONFLICT,
"Another signal already defined with the same name. ",
"Signame is <%s>.",signame.c_str () );
}
}
else
{
dgDEBUG(10) << "Register signal <"<< signame << "> for entity <"
<< getName () << "> ."<<endl;
signalMap[signame] = &sig;
}
} }
} const string &signame(buffer);
SignalMap::iterator sigkey = signalMap.find(signame);
void Entity:: if (sigkey != signalMap.end()) // key does exist
signalDeregistration( const std::string& signame )
{
SignalMap::iterator sigkey = signalMap.find(signame);
if( sigkey == signalMap.end () ) // key does not exist
{
dgERRORF( "Key %s does not exist in the signalMap.",signame.c_str () );
throw ExceptionFactory( ExceptionFactory::UNREFERED_SIGNAL,
"No signal defined with the given name. ",
" (while erasing <%s>).",signame.c_str () );
}
else
{ {
dgDEBUG(10) << "Deregister signal <"<< signame << "> for entity <" dgERRORF("Key %s already exist in the signalMap.", signame.c_str());
<< getName () << "> ."<<endl; if (sigkey->second != &sig) {
signalMap.erase(signame); throw ExceptionFactory(
ExceptionFactory::SIGNAL_CONFLICT,
"Another signal already defined with the same name. ",
"Signame is <%s>.", signame.c_str());
}
} else {
dgDEBUG(10) << "Register signal <" << signame << "> for entity <"
<< getName() << "> ." << endl;
signalMap[signame] = &sig;
} }
}
} }
void Entity::signalDeregistration(const std::string &signame) {
SignalMap::iterator sigkey = signalMap.find(signame);
if (sigkey == signalMap.end()) // key does not exist
{
dgERRORF("Key %s does not exist in the signalMap.", signame.c_str());
throw ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL,
"No signal defined with the given name. ",
" (while erasing <%s>).", signame.c_str());
} else {
dgDEBUG(10) << "Deregister signal <" << signame << "> for entity <"
<< getName() << "> ." << endl;
signalMap.erase(signame);
}
}
std::string Entity::getDocString () const std::string Entity::getDocString() const {
{ std::string docString("No header documentation.");
std::string docString ("No header documentation.");
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",\ "The requested signal is not registered", ": %s", \
": %s",signame.c_str () );\ signame.c_str()); \
}\ } \
return *(sigkey ->second) ; return *(sigkey->second);
bool Entity:: bool Entity::hasSignal(const string &signame) const {
hasSignal( const string & signame ) const return (!(signalMap.find(signame) == signalMap.end()));
{
return (!(signalMap.find(signame) == signalMap.end ()));
} }
SignalBase<int>& Entity:: SignalBase<int> &Entity::getSignal(const string &signame) {
getSignal( const string & signame )
{
__DG_ENTITY_GET_SIGNAL__(iterator); __DG_ENTITY_GET_SIGNAL__(iterator);
} }
const SignalBase<int>& Entity:: const SignalBase<int> &Entity::getSignal(const string &signame) const {
getSignal( const string & signame ) const
{
__DG_ENTITY_GET_SIGNAL__(const_iterator); __DG_ENTITY_GET_SIGNAL__(const_iterator);
} }
std::ostream &Entity::displaySignalList(std::ostream &os) const {
std::ostream& Entity:: os << "--- <" << getName() << "> signal list: " << endl;
displaySignalList( std::ostream& os ) const const SignalMap::const_iterator iterend = signalMap.end();
{ for (SignalMap::const_iterator iter = signalMap.begin(); iterend != iter;
os << "--- <" << getName () << "> signal list: "<<endl; ++iter) {
const SignalMap::const_iterator iterend=signalMap.end (); os << " ";
for( SignalMap::const_iterator iter = signalMap.begin ();iterend!=iter;++iter ) if ((++iter)-- == iterend)
{ os << "`";
os << " "; if( (++iter)--==iterend ) os << "`"; else os <<"|"; else
os << "-- <" << *(iter->second) << endl; os << "|";
} os << "-- <" << *(iter->second) << endl;
}
return os; return os;
} }
std::ostream& Entity:: std::ostream &Entity::writeGraph(std::ostream &os) const {
writeGraph( std::ostream& os ) const const SignalMap::const_iterator iterend = signalMap.end();
{ for (SignalMap::const_iterator iter = signalMap.begin(); iterend != iter;
const SignalMap::const_iterator iterend=signalMap.end (); ++iter) {
for( SignalMap::const_iterator iter = signalMap.begin ();iterend!=iter;++iter ) (*(iter->second)).writeGraph(os);
{ }
(*(iter->second)).writeGraph(os);
}
return os; return os;
} }
std::ostream& Entity:: std::ostream &Entity::writeCompletionList(std::ostream &os) const {
writeCompletionList( std::ostream& os ) const const SignalMap::const_iterator iterend = signalMap.end();
{ for (SignalMap::const_iterator iter = signalMap.begin(); iterend != iter;
const SignalMap::const_iterator iterend=signalMap.end (); ++iter) {
for( SignalMap::const_iterator iter = signalMap.begin ();iterend!=iter;++iter ) os << getName() << "." << (*(iter->second)).shortName() << std::endl;
{ }
os << getName () << "." << (*(iter->second)).shortName () << std::endl;
}
os << getCommandList () << std::endl; os << getCommandList() << std::endl;
return os; return os;
} }
void Entity:: void Entity::display(std::ostream &os) const {
display( std::ostream& os ) const os << this->getClassName() << ": " << name;
{
os<<this->getClassName ()<<": "<<name;
} }
std::ostream& dynamicgraph::operator<< (std::ostream& os, const Entity& ent ) std::ostream &dynamicgraph::operator<<(std::ostream &os, const Entity &ent) {
{
ent.display(os); ent.display(os);
return os; return os;
} }
Entity::SignalMap Entity::getSignalMap() const Entity::SignalMap Entity::getSignalMap() const { return signalMap; }
{
return signalMap;
}
/* --- PARAMS --------------------------------------------------------------- */ /* --- PARAMS --------------------------------------------------------------- */
/* --- PARAMS --------------------------------------------------------------- */ /* --- PARAMS --------------------------------------------------------------- */
/* --- PARAMS --------------------------------------------------------------- */ /* --- PARAMS --------------------------------------------------------------- */
static std::string Entity_COMMAND_LIST = "print\nsignals\nsignalDep"; static std::string Entity_COMMAND_LIST = "print\nsignals\nsignalDep";
const std::string& Entity:: const std::string &Entity::getCommandList() const {
getCommandList () const
{
return Entity_COMMAND_LIST; return Entity_COMMAND_LIST;
} }
void Entity::
commandLine( const std::string& cmdLine,std::istringstream& cmdArgs,std::ostream& os )
{
if( cmdLine == "help" )
{
os << "Entity : " << std::endl
<< " - print\t\t\tWhat d'you think?"<<endl
<< " - signals\t\t\tDisplay the signals list."<<endl
<< " - signalDep <signame> \tDisplay the dependency graph for signal signame."<<endl;
}
else if( cmdLine == "print")
{
os << *this << std::endl;
}
else if( cmdLine == "signals")
{ displaySignalList(os); }
else if( cmdLine == "signalDep")
{
string sig; cmdArgs>>sig;
cmdArgs >> ws; int depth=-1;
if( cmdArgs.good () ) { cmdArgs >> depth; }
getSignal(sig) .displayDependencies( os,depth ); os<<endl;
}
else
{
try{
SignalBase<int> & sig = getSignal( cmdLine );
int time; cmdArgs>>ws;
if( cmdArgs.good () )
{cmdArgs >> time;} else {time=0;}
sig.recompute( time );
os << cmdLine << " = "; sig.get( os );
} catch( ExceptionFactory& e ) {
switch( e.getCode () )
{
case ExceptionFactory::UNREFERED_SIGNAL:
DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_FUNCTION,
"The requested function/signal :","<%s> is "
"not registered.",cmdLine.c_str () );
break;
default:
throw;
}
} catch( ... ) { throw; }
}
}
/// Add a command to Entity /// Add a command to Entity
void Entity:: void Entity::addCommand(const std::string &inName, Command *command) {
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);
} }
/// Return the list of command objects /// Return the list of command objects
std::map<const std::string, Command*> Entity:: std::map<const std::string, Command *> Entity::getNewStyleCommandMap() {
getNewStyleCommandMap()
{
return commandMap; return commandMap;
} }
Command* Entity:: Command *Entity::getNewStyleCommand(const std::string &commandName) {
getNewStyleCommand( const std::string& commandName ) if (commandMap.count(commandName) != 1) {
{ DG_THROW ExceptionFactory(
if (commandMap.count(commandName) != 1) ExceptionFactory::UNREFERED_FUNCTION,
{ "Command <" + commandName + "> is not registered in Entity.");
DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_FUNCTION, }
"Command <" + commandName +
"> is not registered in Entity.");
}
return commandMap[commandName]; return commandMap[commandName];
} }
void Entity::sendMsg(const std::string &msg, MsgType t,
const std::string &lineId) {
logger_.stream(t, lineId) << "[" << name << "]" << msg << '\n';
}
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse, // Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST. // JRL, CNRS/AIST.
// //
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or #include "dynamic-graph/factory.h"
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#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;
namespace dynamicgraph namespace dynamicgraph {
{ FactoryStorage *FactoryStorage::getInstance() {
FactoryStorage* FactoryStorage::getInstance () if (instance_ == 0) {
{ instance_ = new FactoryStorage;
if (instance_ == 0) {
instance_ = new FactoryStorage;
}
return instance_;
}
void FactoryStorage::destroy()
{
delete instance_;
instance_ = NULL;
}
FactoryStorage::FactoryStorage ()
: entityMap ()
{}
FactoryStorage::~FactoryStorage ()
{
instance_ = 0;
dgDEBUGINOUT (25);
}
void
FactoryStorage::registerEntity(const std::string& entname,
FactoryStorage::EntityConstructor_ptr ent)
{
dgDEBUGIN (25);
if (existEntity (entname))
{
DG_THROW ExceptionFactory
(ExceptionFactory::OBJECT_CONFLICT,
"Another entity class already defined with the same name. ",
"(while adding entity class <%s> inside the factory).",
entname.c_str ());
dgERRORF ("Another entity class already defined with the same name. "
"(while adding entity class <%s> inside the factory).",
entname.c_str ());
}
else
{
if (!ent)
{
//FIXME: we should have a better error code for that.
DG_THROW ExceptionFactory
(ExceptionFactory::OBJECT_CONFLICT,
"Bad entity constructor.");
}
dgDEBUG (30) << "Register entity <"<< entname
<< "> in the factory." <<std::endl;
entityMap[entname] = ent;
}
dgDEBUGOUT (25);
}
void
FactoryStorage::deregisterEntity (const std::string& entname)
{
dgDEBUGIN (25);
if (!existEntity(entname))
{
DG_THROW ExceptionFactory( ExceptionFactory::OBJECT_CONFLICT,
"Entity class not defined yet. ",
"(while removing entity class <%s>).",
entname.c_str () );
dgERRORF(ExceptionFactory::OBJECT_CONFLICT,
"Entity class not defined yet. "
"(while removing entity class <%s>).",
entname.c_str () );
}
else
{
dgDEBUG (30) << "Deregister entity <"<< entname
<< "> from the factory." <<std::endl;
entityMap.erase(entname);
}
dgDEBUGOUT (25);
}
Entity*
FactoryStorage::newEntity (const std::string& classname,
const std::string& objname) const
{
dgDEBUG (15) << "New <" << classname << ">Entity <"
<< objname << ">" << std::endl;
EntityMap::const_iterator entPtr = entityMap.find (classname);
if (entPtr == entityMap.end ())
{
DG_THROW ExceptionFactory
(ExceptionFactory::UNREFERED_OBJECT,
"Unknown entity.",
" (while calling new_entity <%s>)",
classname.c_str ());
}
return entPtr->second (objname);
} }
return instance_;
}
void FactoryStorage::destroy() {
delete instance_;
instance_ = NULL;
}
FactoryStorage::FactoryStorage() : entityMap() {}
FactoryStorage::~FactoryStorage() {
instance_ = 0;
dgDEBUGINOUT(25);
}
void FactoryStorage::registerEntity(const std::string &entname,
FactoryStorage::EntityConstructor_ptr ent) {
dgDEBUGIN(25);
if (existEntity(entname)) {
DG_THROW ExceptionFactory(
ExceptionFactory::OBJECT_CONFLICT,
"Another entity class already defined with the same name. ",
"(while adding entity class <%s> inside the factory).",
entname.c_str());
dgERRORF(
"Another entity class already defined with the same name. "
"(while adding entity class <%s> inside the factory).",
entname.c_str());
} else {
if (!ent) {
// FIXME: we should have a better error code for that.
DG_THROW ExceptionFactory(ExceptionFactory::OBJECT_CONFLICT,
"Bad entity constructor.");
}
dgDEBUG(30) << "Register entity <" << entname << "> in the factory."
// This checks efficiently if a key exists in an STL map using the << std::endl;
// approach suggested by Scott Meyer's Effective STL (item 24). entityMap[entname] = ent;
bool
FactoryStorage::existEntity (const std::string& name) const
{
EntityMap::const_iterator lb = entityMap.lower_bound (name);
return lb != entityMap.end ()
&& !(entityMap.key_comp () (name, lb->first));
} }
dgDEBUGOUT(25);
//FIXME: this should be removed at some point. }
void
FactoryStorage::listEntities (std::vector<std::string>& outList) const void FactoryStorage::deregisterEntity(const std::string &entname) {
{ dgDEBUGIN(25);
typedef std::pair<std::string, EntityConstructor_ptr> iter_t; if (!existEntity(entname)) {
BOOST_FOREACH (const iter_t& entity, entityMap) DG_THROW ExceptionFactory(
outList.push_back(entity.first); ExceptionFactory::OBJECT_CONFLICT, "Entity class not defined yet. ",
"(while removing entity class <%s>).", entname.c_str());
dgERRORF(ExceptionFactory::OBJECT_CONFLICT,
"Entity class not defined yet. "
"(while removing entity class <%s>).",
entname.c_str());
} else {
dgDEBUG(30) << "Deregister entity <" << entname << "> from the factory."
<< std::endl;
entityMap.erase(entname);
} }
dgDEBUGOUT(25);
void }
FactoryStorage::commandLine(const std::string& cmdLine,
std::istringstream& cmdArgs, Entity *FactoryStorage::newEntity(const std::string &classname,
std::ostream& os) const std::string &objname) const {
{ dgDEBUG(15) << "New <" << classname << ">Entity <" << objname << ">"
if (cmdLine == "help") << std::endl;
{
os << "factory "; EntityMap::const_iterator entPtr = entityMap.find(classname);
if (entPtr == entityMap.end()) {
std::string cmd2; DG_THROW ExceptionFactory(
cmdArgs >> cmd2; ExceptionFactory::UNREFERED_OBJECT, "Unknown entity.",
" (while calling new_entity <%s>)", classname.c_str());
if (!cmdArgs.good ())
os
<< " <arg>\t\t\t\taccess to the factory (help <arg> for more detail)"
<< std::endl;
else if (cmd2 == "list")
os << "list\t\t:List all available entities." << std::endl;
else if (cmd2 == "listEntities")
os <<"listEntities\t:List available entities." << std::endl;
}
else if (cmdLine == "list")
commandLine("listEntities",cmdArgs,os);
else if (cmdLine == "listEntities")
{
os <<" List of available entities:" << std::endl;
typedef std::pair<std::string, EntityConstructor_ptr> iter_t;
BOOST_FOREACH (const iter_t& entity, entityMap)
os << " - " << entity.first << std::endl;
}
return;
} }
return entPtr->second(objname);
}
// This checks efficiently if a key exists in an STL map using the
// approach suggested by Scott Meyer's Effective STL (item 24).
bool FactoryStorage::existEntity(const std::string &name) const {
EntityRegisterer::EntityRegisterer EntityMap::const_iterator lb = entityMap.lower_bound(name);
(const std::string& entityClassName, FactoryStorage::EntityConstructor_ptr maker) return lb != entityMap.end() && !(entityMap.key_comp()(name, lb->first));
: entityName (entityClassName) }
{
dgDEBUGIN (15); // FIXME: this should be removed at some point.
FactoryStorage::getInstance()->registerEntity (entityClassName, maker); void FactoryStorage::listEntities(std::vector<std::string> &outList) const {
dgDEBUGOUT (15); typedef std::pair<std::string, EntityConstructor_ptr> iter_t;
} BOOST_FOREACH (const iter_t &entity, entityMap)
outList.push_back(entity.first);
EntityRegisterer::~EntityRegisterer () }
{
dgDEBUGIN(15); EntityRegisterer::EntityRegisterer(const std::string &entityClassName,
FactoryStorage::getInstance()->deregisterEntity (entityName); FactoryStorage::EntityConstructor_ptr maker)
dgDEBUGOUT (15); : entityName(entityClassName) {
} dgDEBUGIN(15);
FactoryStorage::getInstance()->registerEntity(entityClassName, maker);
dgDEBUGOUT(15);
// The global factory. }
FactoryStorage* FactoryStorage::instance_ = NULL;
} // end of namespace dynamicgraph. EntityRegisterer::~EntityRegisterer() {
dgDEBUGIN(15);
FactoryStorage::getInstance()->deregisterEntity(entityName);
dgDEBUGOUT(15);
}
// The global factory.
FactoryStorage *FactoryStorage::instance_ = NULL;
} // end of namespace dynamicgraph.
...@@ -5,17 +5,6 @@ ...@@ -5,17 +5,6 @@
* *
* CNRS/AIST * CNRS/AIST
* *
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
...@@ -23,12 +12,13 @@ ...@@ -23,12 +12,13 @@
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --- DYNAMIC-GRAPH --- */ /* --- DYNAMIC-GRAPH --- */
#include "dynamic-graph/pool.h"
#include <list> #include <list>
#include <typeinfo>
#include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include "dynamic-graph/pool.h" #include <typeinfo>
#include "dynamic-graph/debug.h" #include "dynamic-graph/debug.h"
#include "dynamic-graph/entity.h" #include "dynamic-graph/entity.h"
...@@ -38,142 +28,112 @@ using namespace dynamicgraph; ...@@ -38,142 +28,112 @@ using namespace dynamicgraph;
/* --- CLASS ----------------------------------------------------------- */ /* --- CLASS ----------------------------------------------------------- */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
PoolStorage* PoolStorage:: PoolStorage *PoolStorage::getInstance() {
getInstance()
{
if (instance_ == 0) { if (instance_ == 0) {
instance_ = new PoolStorage; instance_ = new PoolStorage;
} }
return instance_; return instance_;
} }
void PoolStorage:: void PoolStorage::destroy() {
destroy()
{
delete instance_; delete instance_;
instance_ = NULL; instance_ = NULL;
} }
PoolStorage:: PoolStorage::~PoolStorage() {
~PoolStorage ()
{
dgDEBUGIN(15); dgDEBUGIN(15);
for( Entities::iterator iter=entityMap.begin (); iter!=entityMap.end (); for (Entities::iterator iter = entityMap.begin(); iter != entityMap.end();
iter=entityMap.begin ()) // Here, this is normal that the next iteration is at the beginning
{ // of the map as deregisterEntity remove the element iter from the map.
dgDEBUG(15) << "Delete \"" iter = entityMap.begin()) {
<< (iter->first) <<"\""<<std::endl; dgDEBUG(15) << "Delete \"" << (iter->first) << "\"" << std::endl;
Entity* entity = iter->second; Entity *entity = iter->second;
deregisterEntity(iter); deregisterEntity(iter);
delete (entity); delete (entity);
} }
instance_ = 0; instance_ = 0;
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
void PoolStorage:: void PoolStorage::registerEntity(const std::string &entname, Entity *ent) {
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( ExceptionFactory::OBJECT_CONFLICT, throw ExceptionFactory(
"Another entity already defined with the same name. ", ExceptionFactory::OBJECT_CONFLICT,
"Entity name is <%s>.",entname.c_str () ); "Another entity already defined with the same name. ",
} "Entity name is <%s>.", entname.c_str());
else } else {
{ dgDEBUG(10) << "Register entity <" << entname << "> in the pool."
dgDEBUG(10) << "Register entity <"<< entname << std::endl;
<< "> in the pool." <<std::endl; entityMap[entname] = ent;
entityMap[entname] = ent; }
}
} }
void PoolStorage:: void PoolStorage::deregisterEntity(const std::string &entname) {
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 not defined yet. ", "Entity name is <%s>.",
"Entity name is <%s>.",entname.c_str () ); entname.c_str());
} } else {
else dgDEBUG(10) << "Deregister entity <" << entname << "> from the pool."
{ << std::endl;
dgDEBUG(10) << "Deregister entity <"<< entname deregisterEntity(entkey);
<< "> from the pool." <<std::endl; }
deregisterEntity(entkey);
}
} }
void PoolStorage:: void PoolStorage::deregisterEntity(const Entities::iterator &entity) {
deregisterEntity( const Entities::iterator& entity ) entityMap.erase(entity);
{
entityMap.erase( entity );
} }
Entity& PoolStorage:: Entity &PoolStorage::getEntity(const std::string &name) {
getEntity( const std::string& name ) dgDEBUG(25) << "Get <" << name << ">" << std::endl;
{ Entities::iterator entPtr = entityMap.find(name);
dgDEBUG(25) << "Get <" << name << ">"<<std::endl; if (entPtr == entityMap.end()) {
Entities::iterator entPtr = entityMap.find( name ); DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_OBJECT,
if( entPtr == entityMap.end () ) "Unknown entity.", " (while calling <%s>)",
{ name.c_str());
DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_OBJECT, } else
"Unknown entity."," (while calling <%s>)", return *entPtr->second;
name.c_str () );
}
else return *entPtr->second;
} }
const PoolStorage::Entities& PoolStorage:: const PoolStorage::Entities &PoolStorage::getEntityMap() const {
getEntityMap () const
{
return entityMap; return entityMap;
} }
bool PoolStorage:: bool PoolStorage::existEntity(const std::string &name) {
existEntity (const std::string& name) return entityMap.find(name) != entityMap.end();
{
return entityMap.find( name ) != entityMap.end();
}
bool PoolStorage::
existEntity (const std::string& name, Entity*& ptr)
{
Entities::iterator entPtr = entityMap.find( name );
if( entPtr == entityMap.end () ) return false;
else
{
ptr = entPtr->second;
return true;
}
} }
bool PoolStorage::existEntity(const std::string &name, Entity *&ptr) {
Entities::iterator entPtr = entityMap.find(name);
if (entPtr == entityMap.end())
return false;
else {
ptr = entPtr->second;
return true;
}
}
void PoolStorage:: void PoolStorage::clearPlugin(const std::string &name) {
clearPlugin( const std::string& name )
{
dgDEBUGIN(5); dgDEBUGIN(5);
std::list<Entity*> toDelete; std::list<Entity *> toDelete;
for (Entities::iterator entPtr = entityMap.begin (); for (Entities::iterator entPtr = entityMap.begin(); entPtr != entityMap.end();
entPtr != entityMap.end (); ++entPtr) ++entPtr)
if (entPtr->second->getClassName () == name) if (entPtr->second->getClassName() == name)
toDelete.push_back (entPtr->second); toDelete.push_back(entPtr->second);
for (std::list< Entity* >::iterator iter = toDelete.begin (); for (std::list<Entity *>::iterator iter = toDelete.begin();
iter != toDelete.end (); ++iter) iter != toDelete.end(); ++iter)
delete (Entity*) *iter; delete (Entity *)*iter;
dgDEBUGOUT(5); dgDEBUGOUT(5);
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
#include <dynamic-graph/entity.h> #include <dynamic-graph/entity.h>
...@@ -182,15 +142,13 @@ clearPlugin( const std::string& name ) ...@@ -182,15 +142,13 @@ clearPlugin( const std::string& name )
#include <time.h> #include <time.h>
#endif /*WIN32*/ #endif /*WIN32*/
void PoolStorage:: void PoolStorage::writeGraph(const std::string &aFileName) {
writeGraph(const std::string &aFileName)
{
size_t IdxPointFound = aFileName.rfind("."); size_t IdxPointFound = aFileName.rfind(".");
std::string tmp1 = aFileName.substr(0,IdxPointFound); std::string tmp1 = aFileName.substr(0, IdxPointFound);
size_t IdxSeparatorFound = aFileName.rfind("/"); size_t IdxSeparatorFound = aFileName.rfind("/");
std::string GenericName; std::string GenericName;
if (IdxSeparatorFound!=std::string::npos) if (IdxSeparatorFound != std::string::npos)
GenericName = tmp1.substr(IdxSeparatorFound,tmp1.length ()); GenericName = tmp1.substr(IdxSeparatorFound, tmp1.length());
else else
GenericName = tmp1; GenericName = tmp1;
...@@ -199,129 +157,77 @@ writeGraph(const std::string &aFileName) ...@@ -199,129 +157,77 @@ writeGraph(const std::string &aFileName)
ltime = time(NULL); ltime = time(NULL);
struct tm ltimeformatted; struct tm ltimeformatted;
#ifdef WIN32 #ifdef WIN32
localtime_s(&ltimeformatted,&ltime); localtime_s(&ltimeformatted, &ltime);
#else #else
localtime_r(&ltime,&ltimeformatted); localtime_r(&ltime, &ltimeformatted);
#endif /*WIN32*/ #endif /*WIN32*/
/* Opening the file and writing the first comment. */ /* Opening the file and writing the first comment. */
std::ofstream GraphFile (aFileName.c_str (),std::ofstream::out); std::ofstream GraphFile(aFileName.c_str(), std::ofstream::out);
GraphFile << "/* This graph has been automatically generated. " << std::endl; GraphFile << "/* This graph has been automatically generated. " << std::endl;
GraphFile << " " << 1900+ltimeformatted.tm_year GraphFile << " " << 1900 + ltimeformatted.tm_year
<< " Month: " << 1+ltimeformatted.tm_mon << " Month: " << 1 + ltimeformatted.tm_mon
<< " Day: " << ltimeformatted.tm_mday << " Day: " << ltimeformatted.tm_mday
<< " Time: " << ltimeformatted.tm_hour << " Time: " << ltimeformatted.tm_hour << ":"
<< ":" << ltimeformatted.tm_min; << ltimeformatted.tm_min;
GraphFile << " */" << std::endl; GraphFile << " */" << std::endl;
GraphFile << "digraph \"" << GenericName << "\" { "; GraphFile << "digraph \"" << GenericName << "\" { ";
GraphFile << "\t graph [ label=\"" << GenericName << "\" bgcolor = white rankdir=LR ]" << std::endl GraphFile << "\t graph [ label=\"" << GenericName
<< "\t node [ fontcolor = black, color = black, fillcolor = gold1, style=filled, shape=box ] ; " << std::endl; << "\" bgcolor = white rankdir=LR ]" << std::endl
<< "\t node [ fontcolor = black, color = black,"
<< "fillcolor = gold1, style=filled, shape=box ] ; " << std::endl;
GraphFile << "\tsubgraph cluster_Entities { " << std::endl; GraphFile << "\tsubgraph cluster_Entities { " << std::endl;
GraphFile << "\t} " << std::endl; GraphFile << "\t} " << std::endl;
for( Entities::iterator iter=entityMap.begin (); for (Entities::iterator iter = entityMap.begin(); iter != entityMap.end();
iter!=entityMap.end (); ++iter) ++iter) {
{ Entity *ent = iter->second;
Entity* ent = iter->second; GraphFile << "\"" << ent->getName() << "\""
GraphFile << "\"" << ent->getName () << "\"" << " [ label = \"" << ent->getName() << "\" ," << std::endl
<<" [ label = \"" << ent->getName () << "\" ," << std::endl << " fontcolor = black, color = black, fillcolor=cyan,"
<<" fontcolor = black, color = black, fillcolor=cyan, style=filled, shape=box ]" << std::endl; << " style=filled, shape=box ]" << std::endl;
ent->writeGraph(GraphFile); ent->writeGraph(GraphFile);
} }
GraphFile << "}"<< std::endl;
GraphFile.close ();
}
void PoolStorage::
writeCompletionList(std::ostream& os)
{
for( Entities::iterator iter=entityMap.begin ();
iter!=entityMap.end (); ++iter)
{
Entity* ent = iter->second;
ent->writeCompletionList(os);
}
GraphFile << "}" << std::endl;
GraphFile.close();
} }
void PoolStorage::writeCompletionList(std::ostream &os) {
void PoolStorage:: for (Entities::iterator iter = entityMap.begin(); iter != entityMap.end();
commandLine( const std::string& objectName,const std::string& functionName, ++iter) {
std::istringstream& cmdArg, std::ostream& os ) Entity *ent = iter->second;
{ ent->writeCompletionList(os);
dgDEBUG(15) << "Object <" << objectName<< "> function <" }
<<functionName<<">"<<std::endl;
if( objectName=="pool" )
{
if( functionName=="help" )
{
os <<"Pool: " << std::endl
<<" - list" << std::endl
<< " - writegraph FileName" << std::endl;
}
else if( functionName=="list" )
{
for( Entities::iterator iter=entityMap.begin ();
iter!=entityMap.end (); ++iter)
{
Entity* ent = iter->second;
os << ent->getName ()
<<" (" << ent->getClassName () << ")" << std::endl;
}
}
else if (functionName=="writegraph")
{
std::string aFileName;
cmdArg >> aFileName;
writeGraph(aFileName);
}
}
else
{
Entity& ent = getEntity(objectName);
ent.commandLine(functionName,cmdArg,os);
}
} }
static bool static bool objectNameParser(std::istringstream &cmdparse, std::string &objName,
objectNameParser( std::istringstream& cmdparse, std::string &funName) {
std::string& objName, const int SIZE = 128;
std::string& funName )
{
const int SIZE=128;
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;
//cmdparse.getline( buffer,SIZE ); // cmdparse.getline( buffer,SIZE );
//funName = buffer; // funName = buffer;
cmdparse >> funName; cmdparse >> funName;
return true; return true;
} }
SignalBase<int>& SignalBase<int> &PoolStorage::getSignal(std::istringstream &sigpath) {
PoolStorage:: std::string objname, signame;
getSignal( std::istringstream& sigpath ) if (!objectNameParser(sigpath, objname, signame)) {
{ DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL,
std::string objname,signame; "Parse error in signal name");
if(! objectNameParser( sigpath,objname,signame ) ) }
{ DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_SIGNAL,
"Parse error in signal name" ); }
Entity& ent = getEntity( objname );
return ent.getSignal( signame );
}
PoolStorage* PoolStorage::instance_ = 0; Entity &ent = getEntity(objname);
return ent.getSignal(signame);
}
PoolStorage *PoolStorage::instance_ = 0;
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse, // Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST. // JRL, CNRS/AIST.
// //
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <cstring>
#include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-abstract.h>
namespace dynamicgraph { #include <cstring>
const std::string ExceptionAbstract::EXCEPTION_NAME = "Abstract";
ExceptionAbstract::ExceptionAbstract (const int& _code,
const std::string& _msg)
: code (_code),
message (_msg)
{}
const char*
ExceptionAbstract::getMessage () const
{
return (this->message) .c_str ();
}
const std::string&
ExceptionAbstract::getStringMessage () const
{
return this->message;
}
int
ExceptionAbstract::getCode () const
{
return this->code;
}
ExceptionAbstract::Param&
ExceptionAbstract::Param::initCopy (const Param& p)
{
if (&p == this)
return *this;
dgDEBUGIN(25);
if (p.pointersSet)
{
strncpy (function,p.functionPTR, BUFFER_SIZE);
strncpy (file,p.filePTR, BUFFER_SIZE);
line = p.line;
pointersSet = false;
set = true;
}
else
set = false;
dgDEBUGOUT(25);
return *this;
}
ExceptionAbstract::Param::Param (const int& _line,
const char* _function,
const char* _file)
: functionPTR (_function),
line (_line),
filePTR (_file),
pointersSet (true)
{
dgDEBUGINOUT(25);
}
std::ostream& namespace dynamicgraph {
operator << (std::ostream& os, const std::string ExceptionAbstract::EXCEPTION_NAME = "Abstract";
const ExceptionAbstract& error)
{ ExceptionAbstract::ExceptionAbstract(const int &_code, const std::string &_msg)
os << error.getExceptionName () : code(_code), message(_msg) {}
<< "Error [#" << error.code << "]: " << error.message << std::endl;
const char *ExceptionAbstract::getMessage() const {
return (this->message).c_str();
}
const std::string &ExceptionAbstract::getStringMessage() const {
return this->message;
}
int ExceptionAbstract::getCode() const { return this->code; }
ExceptionAbstract::Param &ExceptionAbstract::Param::initCopy(const Param &p) {
if (&p == this) return *this;
dgDEBUGIN(25);
if (p.pointersSet) {
strncpy(function, p.functionPTR, BUFFER_SIZE);
strncpy(file, p.filePTR, BUFFER_SIZE);
line = p.line;
pointersSet = false;
set = true;
} else
set = false;
dgDEBUGOUT(25);
return *this;
}
ExceptionAbstract::Param::Param(const int &_line, const char *_function,
const char *_file)
: functionPTR(_function), line(_line), filePTR(_file), pointersSet(true) {
dgDEBUGINOUT(25);
}
std::ostream &operator<<(std::ostream &os, const ExceptionAbstract &error) {
os << error.getExceptionName() << "Error [#" << error.code
<< "]: " << error.message << std::endl;
#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM #ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
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.
...@@ -5,22 +5,12 @@ ...@@ -5,22 +5,12 @@
* *
* CNRS/AIST * CNRS/AIST
* *
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-factory.h>
#include <stdarg.h> #include <stdarg.h>
#include <cstdio> #include <cstdio>
using namespace dynamicgraph; using namespace dynamicgraph;
...@@ -31,40 +21,36 @@ using namespace dynamicgraph; ...@@ -31,40 +21,36 @@ using namespace dynamicgraph;
const std::string ExceptionFactory::EXCEPTION_NAME = "Factory"; const std::string ExceptionFactory::EXCEPTION_NAME = "Factory";
ExceptionFactory:: ExceptionFactory::ExceptionFactory(
ExceptionFactory ( const ExceptionFactory::ErrorCodeEnum& errcode, const ExceptionFactory::ErrorCodeEnum &errcode, const std::string &msg)
const std::string & msg ) : ExceptionAbstract(errcode, msg) {
:ExceptionAbstract(errcode,msg) dgDEBUGF(15, "Created with message <%s>.", msg.c_str());
{ dgDEBUG(1) << "Created with message <%s>." << msg << std::endl;
dgDEBUGF( 15,"Created with message <%s>.",msg.c_str ());
dgDEBUG( 1) <<"Created with message <%s>."<<msg<<std::endl;
} }
ExceptionFactory:: ExceptionFactory::ExceptionFactory(
ExceptionFactory ( const ExceptionFactory::ErrorCodeEnum& errcode, const ExceptionFactory::ErrorCodeEnum &errcode, const std::string &msg,
const std::string & msg,const char* format, ... ) const char *format, ...)
:ExceptionAbstract(errcode,msg) : ExceptionAbstract(errcode, msg) {
{
va_list args; va_list args;
va_start(args,format); va_start(args, format);
const unsigned int SIZE = 256; const unsigned int SIZE = 256;
char buffer[SIZE]; char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args); vsnprintf(buffer, SIZE, format, args);
dgDEBUG(15) <<"Created "<<" with message <" dgDEBUG(15) << "Created "
<<msg<<"> and buffer <"<<buffer<<">. "<<std::endl; << " with message <" << msg << "> and buffer <" << buffer << ">. "
<< std::endl;
message += buffer; message += buffer;
va_end(args); va_end(args);
dgDEBUG(1) << "Throw exception " << EXCEPTION_NAME << "[#" << errcode<<"]: " dgDEBUG(1) << "Throw exception " << EXCEPTION_NAME << "[#" << errcode << "]: "
<<"<"<< message << ">."<<std::endl; << "<" << message << ">." << std::endl;
} }
/* /*
* Local variables: * Local variables:
* c-basic-offset: 2 * c-basic-offset: 2
......
...@@ -5,21 +5,11 @@ ...@@ -5,21 +5,11 @@
* *
* CNRS/AIST * CNRS/AIST
* *
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <dynamic-graph/exception-signal.h> #include <dynamic-graph/exception-signal.h>
#include <stdarg.h> #include <stdarg.h>
#include <cstdio> #include <cstdio>
using namespace dynamicgraph; using namespace dynamicgraph;
...@@ -30,32 +20,26 @@ using namespace dynamicgraph; ...@@ -30,32 +20,26 @@ using namespace dynamicgraph;
const std::string ExceptionSignal::EXCEPTION_NAME = "Signal"; const std::string ExceptionSignal::EXCEPTION_NAME = "Signal";
ExceptionSignal:: ExceptionSignal::ExceptionSignal(const ExceptionSignal::ErrorCodeEnum &errcode,
ExceptionSignal ( const ExceptionSignal::ErrorCodeEnum& errcode, const std::string &msg)
const std::string & msg ) : ExceptionAbstract(errcode, msg) {}
:ExceptionAbstract(errcode,msg)
{
}
ExceptionSignal:: ExceptionSignal::ExceptionSignal(const ExceptionSignal::ErrorCodeEnum &errcode,
ExceptionSignal ( const ExceptionSignal::ErrorCodeEnum& errcode, const std::string &msg, const char *format,
const std::string & msg,const char* format, ... ) ...)
:ExceptionAbstract(errcode,msg) : ExceptionAbstract(errcode, msg) {
{
va_list args; va_list args;
va_start(args,format); va_start(args, format);
const unsigned int SIZE = 256; const unsigned int SIZE = 256;
char buffer[SIZE]; char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args); vsnprintf(buffer, SIZE, format, args);
message += buffer; message += buffer;
va_end(args); va_end(args);
} }
/* /*
* Local variables: * Local variables:
* c-basic-offset: 2 * c-basic-offset: 2
......
...@@ -5,23 +5,12 @@ ...@@ -5,23 +5,12 @@
* *
* CNRS/AIST * CNRS/AIST
* *
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <dynamic-graph/exception-traces.h> #include <dynamic-graph/exception-traces.h>
#include <stdarg.h> #include <stdarg.h>
#include <cstdio>
#include <cstdio>
using namespace dynamicgraph; using namespace dynamicgraph;
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
...@@ -30,32 +19,26 @@ using namespace dynamicgraph; ...@@ -30,32 +19,26 @@ using namespace dynamicgraph;
const std::string ExceptionTraces::EXCEPTION_NAME = "Traces"; const std::string ExceptionTraces::EXCEPTION_NAME = "Traces";
ExceptionTraces:: ExceptionTraces::ExceptionTraces(const ExceptionTraces::ErrorCodeEnum &errcode,
ExceptionTraces ( const ExceptionTraces::ErrorCodeEnum& errcode, const std::string &msg)
const std::string & msg ) : ExceptionAbstract(errcode, msg) {}
:ExceptionAbstract(errcode,msg)
{
}
ExceptionTraces:: ExceptionTraces::ExceptionTraces(const ExceptionTraces::ErrorCodeEnum &errcode,
ExceptionTraces ( const ExceptionTraces::ErrorCodeEnum& errcode, const std::string &msg, const char *format,
const std::string & msg,const char* format, ... ) ...)
:ExceptionAbstract(errcode,msg) : ExceptionAbstract(errcode, msg) {
{
va_list args; va_list args;
va_start(args,format); va_start(args, format);
const unsigned int SIZE = 256; const unsigned int SIZE = 256;
char buffer[SIZE]; char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args); vsnprintf(buffer, SIZE, format, args);
message += buffer; message += buffer;
va_end(args); va_end(args);
} }
/* /*
* Local variables: * Local variables:
* c-basic-offset: 2 * c-basic-offset: 2
......
/* Copyright LAAS, CNRS
* Author: O. Stasse, 2019
* See LICENSE file in the root directory of this repository.
*/
#include <dynamic-graph/process-list.hh>
#include <fstream>
#include <sstream>
#include <string>
using namespace dynamicgraph::CPU;
CPUData::CPUData()
: user_mode_time_(0),
nice_time_(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) {
unsigned long long int luser_mode_time = 0, lnice_time = 0, lsystem_time = 0,
lidle_time = 0, liowait_time = 0, lirq_time = 0,
lsoftirq_time = 0, lsteal_time = 0, lguest_time = 0,
lguest_nice_time;
aCPULine >> luser_mode_time;
aCPULine >> lnice_time;
aCPULine >> lsystem_time;
aCPULine >> lidle_time;
aCPULine >> liowait_time;
aCPULine >> lirq_time;
aCPULine >> lsoftirq_time;
aCPULine >> lsteal_time;
aCPULine >> lguest_time;
aCPULine >> lguest_nice_time;
// Remove guest time already in user_time:
luser_mode_time -= lguest_time;
lnice_time -= lguest_nice_time;
// Compute cumulative time
unsigned long long int lidle_all_time = 0, lsystem_all_time = 0,
lguest_all_time = 0, ltotal_time = 0;
lidle_all_time = lidle_time + liowait_time;
lsystem_all_time = lsystem_time + lirq_time + lsoftirq_time;
lguest_all_time = lguest_time + lguest_nice_time;
ltotal_time = luser_mode_time + lnice_time + lsystem_all_time +
lidle_all_time + lsteal_time + lguest_all_time;
// Update periodic computation.
user_mode_period_ = computePeriod(luser_mode_time, user_mode_time_);
nice_period_ = computePeriod(lnice_time, nice_time_);
system_period_ = computePeriod(lsystem_time, system_time_);
system_all_period_ = computePeriod(lsystem_all_time, system_all_time_);
idle_period_ = computePeriod(lidle_time, idle_time_);
idle_all_period_ = computePeriod(lidle_all_time, idle_all_time_);
iowait_period_ = computePeriod(liowait_time, idle_time_);
irq_period_ = computePeriod(lirq_time, irq_time_);
softirq_period_ = computePeriod(lsoftirq_time, softirq_time_);
steal_period_ = computePeriod(lsteal_time, steal_time_);
guest_period_ = computePeriod(lguest_all_time, guest_time_);
total_period_ = computePeriod(ltotal_time, total_time_);
/// Update time.
user_mode_time_ = luser_mode_time;
nice_time_ = lnice_time;
system_time_ = lsystem_time;
system_all_time_ = lsystem_all_time;
idle_time_ = lidle_time;
idle_all_time_ = lidle_all_time;
iowait_time_ = liowait_time;
irq_time_ = lirq_time;
softirq_time_ = lsoftirq_time;
steal_time_ = lsteal_time;
guest_time_ = lguest_all_time;
total_time_ = ltotal_time;
if (total_period_ != 0) {
percent_ = (double)(user_mode_period_) / (double)(total_period_)*100.0;
percent_ += (double)(nice_period_) / (double)(total_period_)*100.0;
percent_ += (double)(system_period_) / (double)(total_period_)*100.0;
percent_ += (double)(irq_period_) / (double)(total_period_)*100.0;
percent_ += (double)(softirq_period_) / (double)(total_period_)*100.0;
percent_ += (double)(steal_period_) / (double)(total_period_)*100.0;
percent_ += (double)(iowait_period_) / (double)(total_period_)*100.0;
}
}
System::System() {
vCPUData_.clear();
init();
}
void System::init() {
init_ = false;
readProcStat();
init_ = true;
}
void System::ProcessCPULine(unsigned int cpunb, std::istringstream &aCPULine) {
vCPUData_[cpunb].ProcessLine(aCPULine);
}
void System::readProcStat() {
std::ifstream aif;
cpuNb_ = 1;
aif.open("/proc/stat", std::ifstream::in);
std::string aline;
aline.clear();
while (std::getline(aif, aline)) {
// Read on line of the file
std::istringstream anISSLine(aline);
std::string line_hdr;
anISSLine >> line_hdr;
// Check if the line start with cpu
std::size_t pos = line_hdr.find("cpu");
std::string str_cpunbr = line_hdr.substr(pos + 3);
// Check if this is the first line
if (pos == 0 and str_cpunbr.empty()) {
gCPUData_.ProcessLine(anISSLine);
gCPUData_.cpu_id_ = -1;
} else {
// If not then check if there is a CPU number
if (pos == 0) {
std::istringstream iss(str_cpunbr);
unsigned int lcpunb;
iss >> lcpunb;
// If we did not initialize
if (!init_) {
// Count the number of CPU.
if (lcpunb > cpuNb_) cpuNb_ = lcpunb;
} else
// Otherwise process the line.
ProcessCPULine(lcpunb, anISSLine);
}
}
}
if (!init_) {
/// The number of CPU has been detected by going through /proc/stat.
vCPUData_.resize(cpuNb_ + 1);
for (unsigned long i = 0; i < (unsigned long)cpuNb_; i++)
vCPUData_[i].cpu_id_ = (int)i;
}
aif.close();
}
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <dynamic-graph/interpreter.h>
#include <dynamic-graph/functions.h>
#include <dynamic-graph/plugin-loader.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/exception-signal.h>
#ifdef WIN32
#include <Windows.h>
#endif
#include <fstream>
using namespace std;
using namespace dynamicgraph;
extern "C" {
ShellFunctionRegisterer regFun1
( "try",boost::bind(ShellFunctions::cmdTry,_1,_2,_3) );
ShellFunctionRegisterer regFun2
( "loadPlugins",boost::bind(ShellFunctions::cmdLoadPlugins,_1,_2,_3) );
ShellFunctionRegisterer regFun3
( "displayPlugins",boost::bind(ShellFunctions::cmdDisplayPlugins,_1,_2,_3) );
ShellFunctionRegisterer regFun4
( "factory",boost::bind(ShellFunctions::cmdDisplayFactory,_1,_2,_3) );
ShellFunctionRegisterer regFun5
( "#",boost::bind(ShellFunctions::cmdCommentary,_1,_2,_3) );
ShellFunctionRegisterer regFun7
( "unplug",boost::bind(ShellFunctions::cmdUnplug,_1,_2,_3) );
ShellFunctionRegisterer regFun8
( "clearPlugin",boost::bind(ShellFunctions::cmdClearPlugin,_1,_2,_3) );
ShellFunctionRegisterer regFun9
( "signalTime",boost::bind(ShellFunctions::cmdSignalTime,_1,_2,_3) );
ShellFunctionRegisterer regFun10
( "synchro",boost::bind(ShellFunctions::cmdSynchroSignal,_1,_2,_3) );
ShellFunctionRegisterer regFun11
( "echo",boost::bind(ShellFunctions::cmdEcho,_1,_2,_3) );
ShellFunctionRegisterer regFun12
( "copy",boost::bind(ShellFunctions::cmdCopy,_1,_2,_3) );
ShellFunctionRegisterer regFun13
( "freeze",boost::bind(ShellFunctions::cmdFreeze,_1,_2,_3) );
ShellFunctionRegisterer regFun13b
( "squeeze",boost::bind(ShellFunctions::cmdSqueeze,_1,_2,_3) );
ShellFunctionRegisterer regFun14
( "debugtrace",boost::bind(ShellFunctions::cmdEnableTrace,_1,_2,_3) );
ShellFunctionRegisterer regFun15
( "prompt",boost::bind(ShellFunctions::cmdSetPrompt,_1,_2,_3) );
ShellFunctionRegisterer regFun16
( "sleep",boost::bind(ShellFunctions::cmdSleep,_1,_2,_3) );
ShellFunctionRegisterer regFun17
( "beep",boost::bind(ShellFunctions::cmdBeep,_1,_2,_3) );
ShellFunctionRegisterer regFun19
( "completion",boost::bind(ShellFunctions::cmdCompletionList,_1,_2,_3) );
}
/*
* Copyright 2010,
* François Bleibel,
* Olivier Stasse,
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/shell-procedure.h>
#include <dynamic-graph/plugin-loader.h>
#include <dynamic-graph/factory.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/entity.h>
#include <fstream>
using namespace std;
using namespace dynamicgraph;
void ShellProcedure::
cmdStartProcedure( const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - proc <name>"
<< "\t\t\t\tProcedure header." <<endl;
return;
}
args>>procName;
dgDEBUG(5)<<"Proc <" <<procName<<">"<<endl;
currentProc.clear ();
args >> ws;
while( args.good () )
{
std::string next;
args>>next>>ws;
currentProc.params.push_back(next);
}
}
void ShellProcedure::
cmdContinueProcedure( const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - -> cmd args..."
<< "\t\t\t\tProcedure body." <<endl;
return;
}
std::string cmd2;
args>>ws>>cmd2;
dgDEBUG(5)<<"Proc <" <<procName<<">: "<<cmd2<<endl;
Instruction ins; ins.cmd=cmd2;
args >> ws;
while( args.good () )
{
std::string next;
int param = -1;
args >> next >> ws;
for (unsigned int i = 0; i < currentProc.params.size (); ++i)
{
if (next == currentProc.params[i])
{
param = (int) i;
break;
}
}
ins.args.push_back (next);
ins.params.push_back (param);
}
currentProc.instructions.push_back( ins );
}
void ShellProcedure::
cmdEndProcedure( const std::string& cmdLine,std::istringstream&, std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - endproc..."
<< "\t\t\t\tProcedure end." <<endl;
return;
}
dgDEBUG(5)<<"Proc <" <<procName<<">: endproc"<<endl;
procedureList[ procName ] = currentProc;
currentProc.clear ();
if( g_shell.deregisterFunction( procName ))
{ os<< "Redefining proc <"<<procName<<">: procedure already defined. "
<< "Overwrite it."<<endl; }
ShellFunctionRegisterer registration
( procName.c_str (),boost::bind(&ShellProcedure::cmdProcedure,
this,procName,_1,_2,_3) );
}
void ShellProcedure::
cmdProcedure( const std::string& procname,
const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os<<" - "<<procname<<"\t\t\t\t\tUser-defined procedure"<<endl;
args >> ws;
if( args.good () )
{
std::string argname;
const std::streamoff gc = args.tellg ();
args >> argname;
args.seekg(gc); args.clear ();
if( procname==argname )
{
/* if cmdline = "Help <procname>", then display
* the proc instruction. */
ProcedureList::iterator pair = procedureList.find( argname );
if( pair==procedureList.end () )
{
DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_FUNCTION,
"Undefined procedure",
": procedure <%s> not defined.",
argname.c_str () );
}
Procedure & proc = pair->second;
unsigned int cmdnum=1;
for( std::list<Instruction>::iterator ins=proc.instructions.begin ();
ins!=proc.instructions.end (); ++ins )
{
os<<"\t#" <<cmdnum++<<" "<<ins->cmd; // <<" "<<ins->args <<endl;
for( unsigned int i=0;i<ins->args.size ();++i )
{ os << " " << ins->args[i]; }
os << endl;
}
}
}
return;
}
dgDEBUG(15) << " Calling procedure <" <<cmdLine<<"> " <<endl;
ProcedureList::iterator pair = procedureList.find( cmdLine );
if( pair==procedureList.end () )
{
DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_FUNCTION,
"Undefined procedure",
": procedure <%s> not defined.",cmdLine.c_str () );
}
/* You need a copy here, in case the proc is removed from the
* list by itself:
* % proc next
* % -> proc next
* % -> -> echo TOTO
* % -> endproc
* % endproc
*/
Procedure proc = pair->second;
std::vector< std::string > paramValue;
for( unsigned int i=0;i<proc.params.size ();++i )
{
args>>ws;
if( args.good () )
{
std::string next; args>>next>>ws;
paramValue.push_back( next );
dgDEBUG(25) << "Args : <" << next << ">"<<endl;
}
else { paramValue.push_back(""); }
}
istringstream iss; ostringstream oss;
for( std::list<Instruction>::iterator ins=proc.instructions.begin ();
ins!=proc.instructions.end (); ++ins )
{
dgDEBUG(15) << "Proc <" << cmdLine << "> : " << ins->cmd << endl;
oss.clear (); oss.str("");
for( unsigned int i=0;i<ins->params.size ();++i )
{
int paramArg = ins->params[i];
if( paramArg==-1 ) oss << ins->args[i] << " ";
else oss << paramValue[(size_t) paramArg] << " ";
}
dgDEBUG(15) << " Args = " << oss.str () << endl;
iss.str(oss.str ()); iss.clear ();
g_shell.cmd(ins->cmd,iss,os);
}
}
void ShellProcedure::
cmdFor( const std::string& cmdLine,std::istringstream& args,std::ostream& os )
{
if( cmdLine == "help" )
{
os << " - for 1 5 instruction "<<endl;
return;
}
std::string cmd2,idx;
int istart,iend;
{
stringstream oss;
args >> cmd2; oss.str( cmd2 );
const unsigned int SIZE = 32; char b1[SIZE],b2[SIZE],b3[SIZE];
oss.getline( b1,SIZE,'=' );
oss.getline( b2,SIZE,':' );
oss.getline( b3,SIZE );
dgDEBUG(15) << b1 << "/" << b2 << "/" << b3 << endl;
idx = b1; istart = atoi(b2); iend = atoi(b3);
args >> cmd2;
dgDEBUG(15) << "FOR <" << idx << "> = " << istart << " TO " << iend
<< " DO " << cmd2 <<endl;
}
string argsstr;
{
const unsigned int SIZE = 1024; char buffer[SIZE];
args.getline( buffer,SIZE );
argsstr = buffer;
}
for( int i=istart;i<=iend;++i )
{
istringstream iss; stringstream oss;
std::string insp;
istringstream issargs( argsstr );
while( issargs.good () )
{
issargs >> insp;
if( insp == idx ) { oss << i << " "; } else { oss<<insp<< " "; }
}
iss.str( oss.str () );
g_shell.cmd(cmd2,iss,os);
}
}
ShellProcedure sotShellProceduror;
extern "C" {
ShellFunctionRegisterer regFun1
( "proc",boost::bind(&ShellProcedure::cmdStartProcedure,
&sotShellProceduror,_1,_2,_3) );
ShellFunctionRegisterer regFun2
( "->",boost::bind(&ShellProcedure::cmdContinueProcedure,
&sotShellProceduror,_1,_2,_3) );
ShellFunctionRegisterer regFun3
( "endproc",boost::bind(&ShellProcedure::cmdEndProcedure,
&sotShellProceduror,_1,_2,_3) );
ShellFunctionRegisterer regFun4
( "for",boost::bind(&ShellProcedure::cmdFor,
_1,_2,_3) );
}
...@@ -5,21 +5,10 @@ ...@@ -5,21 +5,10 @@
* *
* CNRS/AIST * CNRS/AIST
* *
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <dynamic-graph/signal-array.h> #include <dynamic-graph/signal-array.h>
namespace dynamicgraph { namespace dynamicgraph {
SignalArray<int> sotNOSIGNAL(0); SignalArray<int> sotNOSIGNAL(0);
} }
// -*- c++-mode -*-
// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse, Nicolas Mansard
//
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License
// along with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <boost/date_time/posix_time/posix_time.hpp>
#include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/signal-cast-helper.h>
#include <dynamic-graph/dynamic-graph-api.h>
#include <exception>
#include <boost/lambda/bind.hpp>
#include <string>
#include <sstream>
#include <algorithm>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/linear-algebra.h>
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
//
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License
// along with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/dynamic-graph-api.h>
#include <exception>
#include <boost/lambda/bind.hpp>
#include <string>
#include <sstream>
#include <algorithm>
#include <dynamic-graph/exception-signal.h>
#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
...@@ -5,17 +5,6 @@ ...@@ -5,17 +5,6 @@
* *
* CNRS/AIST * CNRS/AIST
* *
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
...@@ -23,116 +12,98 @@ ...@@ -23,116 +12,98 @@
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* DG */ /* DG */
#include <iomanip> #include <dynamic-graph/all-commands.h>
#include <boost/bind.hpp>
#include <dynamic-graph/tracer-real-time.h>
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/factory.h> #include <dynamic-graph/factory.h>
#include <dynamic-graph/all-commands.h> #include <dynamic-graph/pool.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;
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(TracerRealTime,"TracerRealTime"); DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(TracerRealTime, "TracerRealTime");
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --- DGOUTSTRINGSTREAM ---------------------------------------------- */ /* --- DGOUTSTRINGSTREAM ---------------------------------------------- */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
OutStringStream:: OutStringStream::OutStringStream()
OutStringStream () : std::ostringstream(), buffer(0), index(0), bufferSize(0), full(false) {
: std::ostringstream ()
,buffer( 0 ),index(0),bufferSize(0),full(false)
{
dgDEBUGINOUT(15); dgDEBUGINOUT(15);
} }
OutStringStream:: OutStringStream::~OutStringStream() {
~OutStringStream ()
{
dgDEBUGIN(15); dgDEBUGIN(15);
delete[] buffer; delete[] buffer;
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
void OutStringStream:: void OutStringStream::resize(const std::streamsize &size) {
resize (const std::streamsize& size)
{
dgDEBUGIN(15); dgDEBUGIN(15);
index=0; index = 0;
bufferSize = size; bufferSize = size;
full=false; full = false;
delete[] buffer; delete[] buffer;
buffer = new char[static_cast<size_t> (size)]; buffer = new char[static_cast<size_t>(size)];
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
bool OutStringStream:: bool OutStringStream::addData(const char *data, const std::streamoff &size) {
addData (const char * data, const std::streamoff& size)
{
dgDEBUGIN(15); dgDEBUGIN(15);
std::streamsize towrite = static_cast<std::streamsize> (size); std::streamsize towrite = static_cast<std::streamsize>(size);
if (index + towrite > bufferSize) if (index + towrite > bufferSize) {
{ dgDEBUGOUT(15);
dgDEBUGOUT(15); full = true;
full = true; return false;
return false; }
} memcpy(buffer + index, data, static_cast<size_t>(towrite));
memcpy (buffer + index, data, static_cast<size_t> (towrite));
index += towrite; index += towrite;
dgDEBUGOUT(15); dgDEBUGOUT(15);
return true; return true;
} }
void OutStringStream:: void OutStringStream::dump(std::ostream &os) {
dump( std::ostream& os )
{
dgDEBUGIN(15); dgDEBUGIN(15);
os.write( buffer,index ); os.write(buffer, index);
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
void OutStringStream:: void OutStringStream::empty() {
empty ()
{
dgDEBUGIN(15); dgDEBUGIN(15);
index=0; full=false; index = 0;
full = false;
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
TracerRealTime::TracerRealTime(const std::string &n)
TracerRealTime::TracerRealTime( const std::string & n ) : Tracer(n), bufferSize(BUFFER_SIZE_DEFAULT) {
:Tracer(n)
,bufferSize( BUFFER_SIZE_DEFAULT )
{
dgDEBUGINOUT(15); dgDEBUGINOUT(15);
/* --- Commands --- */ /* --- Commands --- */
{ {
using namespace dynamicgraph::command; using namespace dynamicgraph::command;
std::string doc std::string doc = docCommandVoid0(
= docCommandVoid0("Trash the current content of the buffers, without saving it."); "Trash the current content of the buffers, without saving it.");
addCommand("empty", addCommand("empty",
makeCommandVoid0(*this,&TracerRealTime::emptyBuffers,doc )); makeCommandVoid0(*this, &TracerRealTime::emptyBuffers, doc));
addCommand("getBufferSize", addCommand("getBufferSize",
makeDirectGetter(*this,&bufferSize, makeDirectGetter(*this, &bufferSize,
docDirectGetter("bufferSize","int"))); docDirectGetter("bufferSize", "int")));
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);
} }
...@@ -141,264 +112,194 @@ TracerRealTime::TracerRealTime( const std::string & n ) ...@@ -141,264 +112,194 @@ TracerRealTime::TracerRealTime( const std::string & n )
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
void TracerRealTime::openFile(const SignalBase<int> &sig,
void TracerRealTime:: const std::string &givenname) {
openFile( const SignalBase<int> & sig,
const std::string& givenname )
{
dgDEBUGIN(15); dgDEBUGIN(15);
string signame; string signame;
if( givenname.length () ) if (givenname.length()) {
{ signame = givenname; } else { signame = sig.shortName (); } signame = givenname;
} else {
signame = sig.shortName();
}
string filename = rootdir + basename + signame + suffix; string filename = rootdir + basename + signame + suffix;
dgDEBUG(5) << "Sig <"<<sig.getName () dgDEBUG(5) << "Sig <" << sig.getName() << ">: new file " << filename << endl;
<< ">: 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()) {
dgDEBUG(5) << "Newfile:" << (void*) newfile << endl; delete newfile;
hardFiles.push_back( newfile ); DG_THROW ExceptionTraces(
ExceptionTraces::NOT_OPEN,
"Could not open file " + filename + " for signal " + signame, "");
}
dgDEBUG(5) << "Newfile:" << (void *)newfile << endl;
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);
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
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();
while( files.end ()!=iter ) while (files.end() != iter) {
{ dgDEBUG(25) << "Close the files." << endl;
dgDEBUG(25) << "Close the files." << endl;
std::stringstream * file = dynamic_cast< stringstream* >(*iter); std::stringstream *file = dynamic_cast<stringstream *>(*iter);
std::ofstream * hardFile = *hardIter; std::ofstream *hardFile = *hardIter;
(*hardFile) <<flush; hardFile->close (); (*hardFile) << flush;
delete file; hardFile->close();
delete hardFile; delete file;
delete hardFile;
++iter; ++hardIter; ++iter;
} ++hardIter;
}
dgDEBUG(25) << "Clear the lists." << endl; dgDEBUG(25) << "Clear the lists." << endl;
files.clear (); files.clear();
hardFiles.clear (); hardFiles.clear();
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
void TracerRealTime:: void TracerRealTime::trace() {
trace ()
{
dgDEBUGIN(15); dgDEBUGIN(15);
FileList::iterator iter = files.begin (); FileList::iterator iter = files.begin();
HardFileList::iterator hardIter = hardFiles.begin (); HardFileList::iterator hardIter = hardFiles.begin();
while( files.end ()!=iter ) while (files.end() != iter) {
{ dgDEBUG(35) << "Next" << endl;
dgDEBUG(35) << "Next" << endl; std::ostream *os = *iter;
std::ostream * os = *iter; if (NULL == os) {
if( NULL==os ) DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "The buffer is null",
{ DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN, "");
"The buffer is null",""); } }
//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", "");
}
std::ofstream & hardFile = **hardIter;
if(! hardFile.good () ) std::ofstream &hardFile = **hardIter;
{ DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN, if (!hardFile.good()) {
"The file is not open",""); } DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
"The file is not open", "");
if( (hardFile.good ())&&(NULL!=file) ) }
{
if ((hardFile.good()) && (NULL != file)) {
// const unsigned int SIZE = 1024*8; file->dump(hardFile);
// char buffer[SIZE]; file->empty();
// streambuf * pbuf = file.rdbuf (); hardFile.flush();
// 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->empty ();
hardFile.flush ();
//file.str("");
}
++iter; ++hardIter;
} }
++iter;
++hardIter;
}
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
void TracerRealTime:: void TracerRealTime::emptyBuffers() {
emptyBuffers ()
{
dgDEBUGIN(15); dgDEBUGIN(15);
for( FileList::iterator iter = files.begin ();files.end ()!=iter;++iter ) for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) {
{ // std::stringstream & file = * dynamic_cast< stringstream* >(*iter);
//std::stringstream & file = * dynamic_cast< stringstream* >(*iter); try {
try { OutStringStream &file = *dynamic_cast<OutStringStream *>(*iter);
OutStringStream & file = * dynamic_cast< OutStringStream* >(*iter); file.empty();
file.empty (); // file.str("");
//file.str(""); } catch (...) {
} DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
catch( ... ) { DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN, "The buffer is not open", "");
"The buffer is not open",""); }
} }
}
dgDEBUGOUT(15); dgDEBUGOUT(15);
} }
void TracerRealTime::recordSignal(std::ostream &os,
// void TracerRealTime:: const SignalBase<int> &sig) {
// emptyBuffer( std::stringstream & file )
// {
// streambuf * pbuf = file.rdbuf ();
// pbuf->file.rdbuf () ->pubsetbuf( fileBuffer,10 );
// }
void TracerRealTime::
recordSignal( std::ostream& os,
const SignalBase<int>& sig )
{
dgDEBUGIN(15); dgDEBUGIN(15);
try { try {
OutStringStream &file = dynamic_cast<OutStringStream &>(os);
OutStringStream & file = dynamic_cast< OutStringStream& >(os);
file.str(""); file.str("");
dgDEBUG(45) << "Empty file [" << file.tellp () dgDEBUG(45) << "Empty file [" << file.tellp() << "] <" << file.str().c_str()
<< "] <" << file.str ().c_str () <<"> " <<endl; << "> " << endl;
Tracer::recordSignal( file,sig ); Tracer::recordSignal(file, sig);
file.addData( file.str ().c_str (),file.tellp () ); file.addData(file.str().c_str(), file.tellp());
dgDEBUG(35) << "Write data [" << file.tellp () dgDEBUG(35) << "Write data [" << file.tellp() << "] <" << file.str().c_str()
<< "] <" << file.str ().c_str () <<"> " <<endl; << "> " << endl;
} catch( ExceptionAbstract & exc ) { throw exc; } } catch (ExceptionAbstract &exc) {
catch( ... ) { throw;
DG_THROW ExceptionTraces( ExceptionTraces::NOT_OPEN, } catch (...) {
"The buffer is not open",""); DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
"The buffer is not open", "");
} }
dgDEBUGOUT(15); dgDEBUGOUT(15);
return ; return;
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
void TracerRealTime:: void TracerRealTime::display(std::ostream &os) const {
display( std::ostream& os ) const os << CLASS_NAME << " " << name << " [mode=" << (play ? "play" : "pause")
{ << "] : " << endl
os << CLASS_NAME << " " << name << " [mode=" << (play?"play":"pause") << " - Dep list: " << endl;
<< "] : "<< endl
<< " - Dep list: "<<endl; FileList::const_iterator iterFile = files.begin();
for (SignalList::const_iterator iter = toTraceSignals.begin();
FileList::const_iterator iterFile = files.begin (); toTraceSignals.end() != iter; ++iter) {
for( SignalList::const_iterator iter = toTraceSignals.begin (); dgDEBUG(35) << "Next" << endl;
toTraceSignals.end ()!=iter;++iter ) const OutStringStream *file = dynamic_cast<OutStringStream *>(*iterFile);
{ os << " -> " << (*iter)->getName();
dgDEBUG(35) << "Next" << endl; if (file->givenname.length()) os << " (in " << file->givenname << ")";
const OutStringStream * file = dynamic_cast< OutStringStream* >(*iterFile); os << "\t";
os << " -> "<<(*iter)->getName (); if (file) {
if( file->givenname.length () ) os << " (in " << file->givenname << ")" ; const std::streamsize PRECISION = os.precision();
os << "\t"; const std::streamsize SIZE = file->index;
if( file ) const std::streamsize MSIZE = file->bufferSize;
{ unsigned int dec = 0;
const std::streamsize PRECISION = os.precision (); std::string unit = "";
const std::streamsize SIZE = file->index; if ((SIZE >> 30) || (MSIZE >> 30)) {
const std::streamsize MSIZE = file->bufferSize; dec = 30;
unsigned int dec=0; std::string unit =""; unit = "Go";
if( (SIZE>>30)||(MSIZE>>30) ) { dec = 30; unit="Go"; } } else if ((SIZE >> 20) || (MSIZE >> 20)) {
else if( (SIZE>>20)||(MSIZE>>20) ) { dec = 20; unit="Mo"; } dec = 20;
else if( (SIZE>>10)||(MSIZE>>10) ) { dec = 10; unit="Ko"; } unit = "Mo";
os << "[" << std::setw(1)<<std::setprecision(1) } else if ((SIZE >> 10) || (MSIZE >> 10)) {
<< (((double)SIZE+0.0)/(1<<dec)) << unit << "/" dec = 10;
<< std::setprecision(2)<<(((double)MSIZE+0.0)/(1<<dec)) unit = "Ko";
<< unit << "]\t"; }
if( file->full ) os << "(FULL)"; os << "[" << std::setw(1) << std::setprecision(1)
os.precision(PRECISION); << (((double)SIZE + 0.0) / (1 << dec)) << unit << "/"
} << std::setprecision(2) << (((double)MSIZE + 0.0) / (1 << dec)) << unit
os<<endl; << "]\t";
iterFile++; if (file->full) os << "(FULL)";
os.precision(PRECISION);
} }
os << endl;
++iterFile;
}
} }
std::ostream &operator<<(std::ostream &os, const TracerRealTime &t) {
std::ostream& operator<< ( std::ostream& os,const TracerRealTime& t )
{
t.display(os); t.display(os);
return os; return os;
} }
void TracerRealTime::
commandLine( const std::string& cmdLine
,std::istringstream& cmdArgs
,std::ostream& os )
{
if( cmdLine=="help" )
{
os << "TracerRealTime: "<<endl
<< " - empty: trash the buffers." <<endl
<< " - bufferSize [<size>]: get/set the buffer size." <<endl;
Tracer::commandLine( cmdLine,cmdArgs,os );
}
else if( cmdLine=="empty" )
{
emptyBuffers ();
}
else if( cmdLine=="bufferSize" )
{
cmdArgs>>ws;
if( cmdArgs.good () )
{
int s; cmdArgs>>s;
setBufferSize( s );
}
else os << getBufferSize () << endl;
}
else
Tracer::commandLine( cmdLine,cmdArgs,os );
}