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 1482 additions and 1602 deletions
...@@ -4,99 +4,102 @@ ...@@ -4,99 +4,102 @@
// //
#ifndef DYNAMIC_GRAPH_TRACER_H #ifndef DYNAMIC_GRAPH_TRACER_H
# define DYNAMIC_GRAPH_TRACER_H #define DYNAMIC_GRAPH_TRACER_H
# include <string> #include <dynamic-graph/entity.h>
# include <list> #include <dynamic-graph/exception-traces.h>
# include <boost/function.hpp> #include <dynamic-graph/signal-base.h>
#include <dynamic-graph/signal-time-dependent.h>
# include <dynamic-graph/signal-base.h> #include <dynamic-graph/time-dependency.h>
# include <dynamic-graph/signal-time-dependent.h>
# include <dynamic-graph/time-dependency.h> #include <boost/function.hpp>
# include <dynamic-graph/entity.h> #include <dynamic-graph/config-tracer.hh>
# include <dynamic-graph/exception-traces.h> #include <list>
#include <mutex>
# include <dynamic-graph/config-tracer.hh> #include <string>
namespace dynamicgraph namespace dynamicgraph {
{ /// \ingroup plugin
/// \ingroup plugin ///
/// /// \brief Tracer plug-in main class.
/// \brief Tracer plug-in main class. class DG_TRACER_DLLAPI Tracer : public Entity {
class DG_TRACER_DLLAPI Tracer : public Entity DYNAMIC_GRAPH_ENTITY_DECL();
{
DYNAMIC_GRAPH_ENTITY_DECL (); protected:
protected: typedef std::list<const SignalBase<int> *> SignalList;
typedef std::list< const SignalBase<int>* > SignalList; SignalList toTraceSignals;
SignalList toTraceSignals; std::mutex files_mtx;
public:
enum TraceStyle public:
{ enum TraceStyle {
WHEN_SAID /// Record, then trace to file only when said to. WHEN_SAID
,EACH_TIME /// Record and trace to file immediately. /// Record, then trace to file only when said to.
,FREQUENTLY /// Record X time then trace (X is tuned by setFrenquence () ). ,
}; EACH_TIME
TraceStyle traceStyle; /// Record and trace to file immediately.
static const TraceStyle TRACE_STYLE_DEFAULT = EACH_TIME; ,
double frequency; FREQUENTLY
/// Record X time then trace (X is tuned by setFrenquence () ).
std::string basename;
std::string suffix;
std::string rootdir;
bool namesSet;
typedef std::list< std::ostream* > FileList;
FileList files;
typedef std::list< std::string > NameList;
NameList names;
bool play;
int timeStart;
public:
Tracer( const std::string n );
virtual ~Tracer (){ closeFiles (); }
void addSignalToTrace( const SignalBase<int>& sig,
const std::string& filename="" );
void addSignalToTraceByName( const std::string& signame,
const std::string& filename="" );
void clearSignalToTrace ();
//void parasite( SignalBase<int>& sig );
void openFiles( const std::string& rootdir, const std::string& basename,
const std::string& suffix );
virtual void closeFiles ();
protected:
virtual void openFile( const SignalBase<int> & sig,
const std::string& filename );
public:
void setTraceStyle( const TraceStyle& style ){ traceStyle = style; }
TraceStyle getTraceStyle (){ return traceStyle; }
void setFrenquency( const double& frqu ){ frequency = frqu; }
double getFrequency (){ return frequency; }
void record ();
virtual void recordSignal( std::ostream& os,
const SignalBase<int>& sig );
int& recordTrigger( int& dummy, const int& time );
virtual void trace ();
void start() { play = true ; }
void stop() { play = false; }
public:
//SignalTrigerer<int> triger;
SignalTimeDependent<int,int> triger;
/* --- DISPLAY ------------------------------------------------------------ */
DG_TRACER_DLLAPI friend std::ostream& operator<<
(std::ostream& os,const Tracer& t);
/* --- PARAMS --- */
void display( std::ostream& os ) const;
}; };
TraceStyle traceStyle;
} // end of namespace dynamicgraph static const TraceStyle TRACE_STYLE_DEFAULT = EACH_TIME;
double frequency;
#endif //! DYNAMIC_GRAPH_TRACER_H
std::string basename;
std::string suffix;
std::string rootdir;
bool namesSet;
typedef std::list<std::ostream *> FileList;
FileList files;
typedef std::list<std::string> NameList;
NameList names;
bool play;
int timeStart;
public:
Tracer(const std::string n);
virtual ~Tracer() { closeFiles(); }
void addSignalToTrace(const SignalBase<int> &sig,
const std::string &filename = "");
void addSignalToTraceByName(const std::string &signame,
const std::string &filename = "");
void clearSignalToTrace();
// void parasite( SignalBase<int>& sig );
void openFiles(const std::string &rootdir, const std::string &basename,
const std::string &suffix);
virtual void closeFiles();
protected:
virtual void openFile(const SignalBase<int> &sig,
const std::string &filename);
public:
void setTraceStyle(const TraceStyle &style) { traceStyle = style; }
TraceStyle getTraceStyle() { return traceStyle; }
void setFrenquency(const double &frqu) { frequency = frqu; }
double getFrequency() { return frequency; }
void record();
virtual void recordSignal(std::ostream &os, const SignalBase<int> &sig);
int &recordTrigger(int &dummy, const int &time);
virtual void trace();
void start() { play = true; }
void stop() { play = false; }
public:
// SignalTrigerer<int> triger;
SignalTimeDependent<int, int> triger;
/* --- DISPLAY --------------------------------------------------------- */
DG_TRACER_DLLAPI friend std::ostream &operator<<(std::ostream &os,
const Tracer &t);
/* --- PARAMS --- */
void display(std::ostream &os) const;
};
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_TRACER_H
...@@ -7,109 +7,136 @@ ...@@ -7,109 +7,136 @@
#ifndef DYNAMIC_GRAPH_VALUE_H #ifndef DYNAMIC_GRAPH_VALUE_H
#define DYNAMIC_GRAPH_VALUE_H #define DYNAMIC_GRAPH_VALUE_H
#include <string> #include <dynamic-graph/linear-algebra.h>
#include <cassert> #include <cassert>
#include <string>
#include <typeinfo> #include <typeinfo>
#include <vector>
#include "dynamic-graph/dynamic-graph-api.h" #include "dynamic-graph/dynamic-graph-api.h"
#include <dynamic-graph/linear-algebra.h>
namespace dynamicgraph { namespace dynamicgraph {
namespace command { namespace command {
class Value; class Value;
class DYNAMIC_GRAPH_DLLAPI EitherType { typedef std::vector<Value> Values;
public:
EitherType(const Value& value); class DYNAMIC_GRAPH_DLLAPI EitherType {
~EitherType(); public:
operator bool () const; EitherType(const Value &value);
operator unsigned () const; ~EitherType();
operator int () const; operator bool() const;
operator float () const; operator unsigned() const;
operator double () const; operator unsigned long int() const;
operator std::string () const; operator int() const;
operator Vector () const; operator long int() const;
operator Eigen::MatrixXd () const; operator float() const;
operator Eigen::Matrix4d () const; operator double() const;
private: operator std::string() const;
const Value* value_; operator Vector() const;
}; operator Eigen::MatrixXd() const;
operator Eigen::Matrix4d() const;
operator Values() const;
private:
const Value *value_;
};
/** \ingroup dgraph
\brief This class implements a variant design pattern to handle basic types
in Command.
*/
class DYNAMIC_GRAPH_DLLAPI Value {
public:
enum Type {
NONE,
BOOL,
UNSIGNED,
UNSIGNEDLONGINT,
INT,
LONGINT,
FLOAT,
DOUBLE,
STRING,
VECTOR,
MATRIX,
MATRIX4D,
VALUES,
NB_TYPES
};
~Value();
void deleteValue();
explicit Value(const bool &value);
explicit Value(const unsigned &value);
explicit Value(const unsigned long int &value);
explicit Value(const int &value);
explicit Value(const long int &value);
explicit Value(const float &value);
explicit Value(const double &value);
explicit Value(const std::string &value);
explicit Value(const Vector &value);
explicit Value(const Eigen::MatrixXd &value);
explicit Value(const Eigen::Matrix4d &value);
explicit Value(const Values &value);
/// Copy constructor
Value(const Value &value);
// Construct an empty value (None)
explicit Value();
// operator assignement
Value operator=(const Value &value);
// Equality operator
bool operator==(const Value &other) const;
/// Return the type of the value
Type type() const;
class DYNAMIC_GRAPH_DLLAPI Value { /// Return the value as a castable value into the approriate type
public: ///
enum Type { /// For instance,
NONE, /// \code
BOOL, /// Value v1(5.0); // v1 is of type double
UNSIGNED, /// Value v2(3); // v2 is of type int
INT, /// double x1 = v1.value();
FLOAT, /// double x2 = v2.value();
DOUBLE, /// \endcode
STRING, /// The first assignment will succeed, while the second one will throw
VECTOR, /// an exception.
MATRIX, const EitherType value() const;
MATRIX4D, /// Return the name of the type
NB_TYPES static std::string typeName(Type type);
};
~Value();
void deleteValue ();
explicit Value(const bool& value);
explicit Value(const unsigned& value);
explicit Value(const int& value);
explicit Value(const float& value);
explicit Value(const double& value);
explicit Value(const std::string& value);
explicit Value(const Vector& value);
explicit Value(const Eigen::MatrixXd& value);
explicit Value(const Eigen::Matrix4d& value);
/// Copy constructor
Value(const Value& value);
// Construct an empty value (None)
explicit Value();
// operator assignement
Value operator=(const Value& value);
/// Return the type of the value
Type type() const;
/// Return the value as a castable value into the approriate type /// Output in a stream
/// DYNAMIC_GRAPH_DLLAPI friend std::ostream &operator<<(std::ostream &os,
/// For instance, const Value &value);
/// \code
/// Value v1(5.0); // v1 is of type double
/// Value v2(3); // v2 is of type int
/// double x1 = v1.value();
/// double x2 = v2.value();
/// \endcode
/// The first assignment will succeed, while the second one will throw
/// an exception.
const EitherType value () const;
/// Return the name of the type
static std::string typeName(Type type);
/// Output in a stream public:
DYNAMIC_GRAPH_DLLAPI friend std::ostream& operator<<(std::ostream& os, const Value& value); friend class EitherType;
public: bool boolValue() const;
friend class EitherType; unsigned unsignedValue() const;
bool boolValue() const; unsigned long int unsignedlongintValue() const;
unsigned unsignedValue() const; int intValue() const;
int intValue() const; long int longintValue() const;
float floatValue() const; float floatValue() const;
double doubleValue() const; double doubleValue() const;
std::string stringValue() const; std::string stringValue() const;
Vector vectorValue() const; Vector vectorValue() const;
Eigen::MatrixXd matrixXdValue() const; Eigen::MatrixXd matrixXdValue() const;
Eigen::Matrix4d matrix4dValue() const; Eigen::Matrix4d matrix4dValue() const;
Type type_; Values valuesValue() const;
const void* const value_; const Values &constValuesValue() const;
}; Type type_;
const void *const value_;
};
/* ---- HELPER ---------------------------------------------------------- */ /* ---- HELPER ---------------------------------------------------------- */
// Note: to ensure the WIN32 compatibility, it is necessary to export // Note: to ensure the WIN32 compatibility, it is necessary to export
// the template specialization. Also, it is forbidden to do the template // the template specialization. Also, it is forbidden to do the template
// specialization declaration in the header file, for the same reason. // specialization declaration in the header file, for the same reason.
template< typename T > template <typename T>
struct DYNAMIC_GRAPH_DLLAPI ValueHelper struct DYNAMIC_GRAPH_DLLAPI ValueHelper {
{ static const Value::Type TypeID;
static const Value::Type TypeID; };
}; } // namespace command
} // namespace command } // namespace dynamicgraph
} //namespace dynamicgraph
#endif //DYNAMIC_GRAPH_VALUE_H #endif // DYNAMIC_GRAPH_VALUE_H
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<script> <script>
function renderDOTFile() { function renderDOTFile() {
var fileInputElement = document.getElementById("fileInputElement"); var fileInputElement = document.getElementById("fileInputElement");
var reader = new FileReader(); var reader = new FileReader();
var graphtextres = "" var graphtextres = ""
reader.onloadend = function(e) { reader.onloadend = function(e) {
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
.catch(error => { .catch(error => {
// Create a new Viz instance (@see Caveats page for more info) // Create a new Viz instance (@see Caveats page for more info)
viz = new Viz(); viz = new Viz();
// Possibly display the error // Possibly display the error
console.error(error); console.error(error);
}); });
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
</script> </script>
<input type="file" id="fileInputElement"> <input type="file" id="fileInputElement">
<input id="Rendering" type="button" value="Rendering" onclick="renderDOTFile();" /> <input id="Rendering" type="button" value="Rendering" onclick="renderDOTFile();" />
<script> <script>
var el = document.getElementById("Rendering"); var el = document.getElementById("Rendering");
...@@ -49,4 +49,3 @@ ...@@ -49,4 +49,3 @@
</body> </body>
</html> </html>
<?xml version="1.0"?>
<package format="3">
<name>dynamic-graph</name>
<version>4.4.3</version>
<description>
Dynamic graph library
</description>
<maintainer email="guilhem.saurel@laas.fr">Guilhem saurel</maintainer>
<license>BSD</license>
<url>http://github.com/stack-of-tasks/dynamic-graph</url>
<author>Nicolas Mansard</author>
<author>Olivier Stasse</author>
<build_depend>git</build_depend>
<build_depend>doxygen</build_depend>
<!-- The following tags are recommended by REP-136 -->
<exec_depend condition="$ROS_VERSION == 1">catkin</exec_depend>
<exec_depend condition="$ROS_VERSION == 2">ament_cmake</exec_depend>
<depend>eigen</depend>
<depend>boost</depend>
<depend>graphviz</depend>
<buildtool_depend>cmake</buildtool_depend>
<export>
<build_type>cmake</build_type>
</export>
</package>
# Copyright 2010, Olivier Stasse, JRL, CNRS/AIST set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
#
#################################### set(plugins traces/tracer traces/tracer-real-time)
### Main Library
####################################
SET(LIBRARY_NAME ${PROJECT_NAME})
# Verbosity level set(tracer-real-time_deps tracer)
IF (NOT (\"${CMAKE_VERBOSITY_LEVEL}\" STREQUAL \"\"))
ADD_DEFINITIONS(-DVP_DEBUG_MODE=${CMAKE_VERBOSITY_LEVEL} -DVP_DEBUG)
ENDIF (NOT (\"${CMAKE_VERBOSITY_LEVEL}\" STREQUAL \"\"))
# Declare boost include directories foreach(plugin ${plugins})
include_directories(${Boost_INCLUDE_DIRS}) get_filename_component(LIBRARY_NAME ${plugin} NAME)
link_directories(${Boost_LIBRARY_DIRS}) add_library(${LIBRARY_NAME} SHARED "${plugin}.cpp")
ADD_LIBRARY(${LIBRARY_NAME} if(SUFFIX_SO_VERSION)
SHARED set_target_properties(${LIBRARY_NAME} PROPERTIES SOVERSION
debug/debug.cpp ${PROJECT_VERSION})
debug/real-time-logger.cpp endif(SUFFIX_SO_VERSION)
debug/logger.cpp set_target_properties(${LIBRARY_NAME} PROPERTIES INSTALL_RPATH $ORIGIN)
dgraph/entity.cpp target_link_libraries(${LIBRARY_NAME} PUBLIC ${PROJECT_NAME}
dgraph/factory.cpp ${${LIBRARY_NAME}_deps})
dgraph/pool.cpp
exception/exception-abstract.cpp install(
exception/exception-factory.cpp TARGETS ${LIBRARY_NAME}
exception/exception-signal.cpp EXPORT ${TARGETS_EXPORT_NAME}
exception/exception-traces.cpp DESTINATION ${DYNAMIC_GRAPH_PLUGINDIR})
endforeach(plugin)
signal/signal-array.cpp
signal/signal-caster.cpp
signal/signal-cast-helper.cpp
command/value.cpp
command/command.cpp
)
SET_TARGET_PROPERTIES(${LIBRARY_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION})
IF (UNIX)
TARGET_LINK_LIBRARIES(${LIBRARY_NAME} ${CMAKE_DL_LIBS} pthread)
ENDIF (UNIX)
TARGET_LINK_LIBRARIES(${LIBRARY_NAME} ${Boost_LIBRARIES})
#IF (UNIX AND NOT APPLE)
# TARGET_LINK_LIBRARIES(${LIBRARY_NAME} ${JRL_MAL_LDFLAGS_OTHER})
#ENDIF (UNIX AND NOT APPLE)
INSTALL(TARGETS ${LIBRARY_NAME}
DESTINATION ${CMAKE_INSTALL_LIBDIR})
####################################
### Plugins
####################################
SET(plugins_list
traces/tracer
traces/tracer-real-time
)
SET(tracer-real-time_dependency tracer)
FOREACH(plugin_file ${plugins_list})
GET_FILENAME_COMPONENT(plugin ${plugin_file} NAME)
ADD_LIBRARY(${plugin} SHARED "${plugin_file}.cpp")
TARGET_LINK_LIBRARIES(${plugin}
${PROJECT_NAME} ${${plugin}_dependency}
${Boost_LIBRARIES})
SET_TARGET_PROPERTIES(${plugin}
PROPERTIES
PREFIX ""
)
INSTALL(TARGETS ${plugin} DESTINATION ${PLUGINDIR})
ENDFOREACH(plugin_file)
...@@ -4,68 +4,54 @@ ...@@ -4,68 +4,54 @@
// Author: Florent Lamiraux // Author: Florent Lamiraux
// //
#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
...@@ -4,359 +4,379 @@ ...@@ -4,359 +4,379 @@
// Author: Florent Lamiraux // Author: Florent Lamiraux
// //
#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();
break; }
case Value::BOOL: return copy;
copy = new bool(value.boolValue()); }
break;
case Value::UNSIGNED: Value::Value() : type_(NONE), value_(NULL) {}
copy = new unsigned(value.unsignedValue());
break; Value Value::operator=(const Value &value) {
case Value::INT: if (&value != this) {
copy = new int(value.intValue()); if (value_ != 0x0) deleteValue();
break; type_ = value.type_;
case Value::FLOAT: void **ptValue = const_cast<void **>(&value_);
copy = new float(value.floatValue()); *ptValue = copyValue(value);
break; }
case Value::DOUBLE: return *this;
copy = new double(value.doubleValue()); }
break;
case Value::STRING: bool Value::operator==(const Value &other) const {
copy = new std::string(value.stringValue()); if (type_ != other.type_) return false;
break; switch (type_) {
case Value::VECTOR: case Value::BOOL:
copy = new Vector(value.vectorValue()); return boolValue() == other.boolValue();
break; case Value::UNSIGNED:
case Value::MATRIX: return unsignedValue() == other.unsignedValue();
copy = new Eigen::MatrixXd(value.matrixXdValue()); case Value::UNSIGNEDLONGINT:
break; return unsignedlongintValue() == other.unsignedlongintValue();
case Value::MATRIX4D: case Value::INT:
copy = new Eigen::Matrix4d(value.matrix4dValue()); return intValue() == other.intValue();
break; case Value::DOUBLE:
default: return doubleValue() == other.doubleValue();
abort(); case Value::FLOAT:
} return floatValue() == other.floatValue();
return copy; case Value::STRING:
} return stringValue() == other.stringValue();
case Value::VECTOR:
Value::Value() : type_(NONE), value_(NULL) return vectorValue() == other.vectorValue();
{ case Value::MATRIX:
} return matrixXdValue() == other.matrixXdValue();
case Value::MATRIX4D:
Value Value::operator=(const Value& value) return matrix4dValue() == other.matrix4dValue();
{ case Value::VALUES:
if (&value != this) { return constValuesValue() == other.constValuesValue();
if(value_ != 0x0) case Value::NONE:
deleteValue (); break;
type_ = value.type_; default:
void** ptValue = const_cast<void**>(&value_); break;
*ptValue = copyValue(value); }
} return false;
return *this; }
}
const EitherType Value::value() const { return EitherType(*this); }
const EitherType Value::value() const
{ Value::Type Value::type() const { return type_; }
return EitherType(*this);
} bool Value::boolValue() const {
if (type_ == BOOL) return *((const bool *)value_);
Value::Type Value::type() const throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an bool");
{ }
return type_;
} unsigned Value::unsignedValue() const {
if (type_ == UNSIGNED) return *((const unsigned *)value_);
bool Value::boolValue() const throw ExceptionAbstract(ExceptionAbstract::TOOLS,
{ "value is not an unsigned int");
if(type_ == BOOL) }
return *((const bool*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, unsigned long int Value::unsignedlongintValue() const {
"value is not an bool"); if (type_ == UNSIGNEDLONGINT) return *((const unsigned long int *)value_);
} throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an unsigned long int");
unsigned Value::unsignedValue() const }
{
if(type_ == UNSIGNED) long int Value::longintValue() const {
return *((const unsigned*)value_); if (type_ == LONGINT) return *((const long int *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an long int");
"value is not an unsigned int"); }
}
int Value::intValue() const {
int Value::intValue() const if (type_ == INT) return *((const int *)value_);
{ throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an int");
if(type_ == INT) }
return *((const int*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, float Value::floatValue() const {
"value is not an int int"); float result;
} if (FLOAT != type_)
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a float");
float Value::floatValue() const result = *((const float *)value_);
{ return result;
float result; }
if(FLOAT != type_)
throw ExceptionAbstract(ExceptionAbstract::TOOLS, double Value::doubleValue() const {
"value is not a float"); double result;
result = *((const float*)value_); if (DOUBLE != type_)
return result; throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a double");
} result = *((const double *)value_);
return result;
double Value::doubleValue() const }
{
double result; std::string Value::stringValue() const {
if(DOUBLE != type_) if (type_ == STRING) return *((const std::string *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an string");
"value is not a double"); }
result = *((const double*)value_);
return result; Vector Value::vectorValue() const {
} if (type_ == VECTOR) return *((const Vector *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an vector");
std::string Value::stringValue() const }
{
if(type_ == STRING) Eigen::MatrixXd Value::matrixXdValue() const {
return *((const std::string*)value_); if (type_ == MATRIX) return *((const Eigen::MatrixXd *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an string"); "value is not a Eigen matrixXd");
} }
Vector Value::vectorValue() const Eigen::Matrix4d Value::matrix4dValue() const {
{ if (type_ == MATRIX4D) return *((const Eigen::Matrix4d *)value_);
if(type_ == VECTOR) throw ExceptionAbstract(ExceptionAbstract::TOOLS,
return *((const Vector*)value_); "value is not a Eigen matrix4d");
throw ExceptionAbstract(ExceptionAbstract::TOOLS, }
"value is not an vector");
} Values Value::valuesValue() const {
if (type_ == VALUES) return *((const Values *)value_);
Eigen::MatrixXd Value::matrixXdValue() const throw ExceptionAbstract(ExceptionAbstract::TOOLS,
{ "value is not a vector of Value");
if(type_ == MATRIX) }
return *((const Eigen::MatrixXd*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, const Values &Value::constValuesValue() const {
"value is not a Eigen matrixXd"); if (type_ == VALUES) return *((const Values *)value_);
} throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a vector of Value");
Eigen::Matrix4d Value::matrix4dValue() const }
{
if(type_ == MATRIX4D) std::string Value::typeName(Type type) {
return *((const Eigen::Matrix4d*)value_); switch (type) {
throw ExceptionAbstract(ExceptionAbstract::TOOLS, case BOOL:
"value is not a Eigen matrix4d"); return std::string("bool");
} case UNSIGNED:
return std::string("unsigned int");
std::string Value::typeName(Type type) case UNSIGNEDLONGINT:
{ return std::string("unsigned long int");
switch(type) { case INT:
case BOOL: return std::string("int");
return std::string("bool"); case FLOAT:
case UNSIGNED: return std::string("float");
return std::string("unsigned int"); case DOUBLE:
case INT: return std::string("double");
return std::string("int"); case STRING:
case FLOAT: return std::string("string");
return std::string("float"); case VECTOR:
case DOUBLE: return std::string("vector");
return std::string("double"); case MATRIX:
case STRING: return std::string("matrixXd");
return std::string("string"); case MATRIX4D:
case VECTOR: return std::string("matrix4d");
return std::string("vector"); case VALUES:
case MATRIX: return std::string("values");
return std::string("matrixXd"); default:
case MATRIX4D: return std::string("unknown");
return std::string("matrix4d"); }
default: }
return std::string("unknown");
} std::ostream &operator<<(std::ostream &os, const Value &value) {
} os << "Type=" << Value::typeName(value.type_) << ", value=";
switch (value.type_) {
std::ostream& operator<<(std::ostream& os, const Value& value) case Value::BOOL:
{ os << value.boolValue();
os << "Type=" << Value::typeName(value.type_) break;
<< ", value="; case Value::UNSIGNED:
switch(value.type_) { os << value.unsignedValue();
case Value::BOOL: break;
os << value.boolValue(); case Value::UNSIGNEDLONGINT:
break; os << value.unsignedlongintValue();
case Value::UNSIGNED: break;
os << value.unsignedValue(); case Value::INT:
break; os << value.intValue();
case Value::INT: break;
os << value.intValue(); case Value::DOUBLE:
break; os << value.doubleValue();
case Value::DOUBLE: break;
os << value.doubleValue(); case Value::FLOAT:
break; os << value.floatValue();
case Value::FLOAT: break;
os << value.floatValue(); case Value::STRING:
break; os << value.stringValue();
case Value::STRING: break;
os << value.stringValue(); case Value::VECTOR:
break; os << value.vectorValue();
case Value::VECTOR: break;
os << value.vectorValue(); case Value::MATRIX:
break; os << value.matrixXdValue();
case Value::MATRIX: break;
os << value.matrixXdValue(); case Value::MATRIX4D:
break; os << value.matrix4dValue();
case Value::MATRIX4D: break;
os << value.matrix4dValue(); case Value::VALUES: {
break; const std::vector<Value> &vals = value.constValuesValue();
default: os << "[ ";
return 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
...@@ -8,56 +8,52 @@ ...@@ -8,56 +8,52 @@
*/ */
#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);
...@@ -12,103 +12,74 @@ ...@@ -12,103 +12,74 @@
#endif #endif
#define ENABLE_RT_LOG #define ENABLE_RT_LOG
#include <stdio.h>
#include <iostream>
#include <iomanip> // std::setprecision
#include <dynamic-graph/logger.h> #include <dynamic-graph/logger.h>
#include <dynamic-graph/real-time-logger.h> #include <dynamic-graph/real-time-logger.h>
#include <stdio.h>
namespace dynamicgraph #include <iomanip> // std::setprecision
{ #include <iostream>
#include <sstream>
using namespace std; namespace dynamicgraph {
Logger::Logger(double timeSample, double streamPrintPeriod) Logger::Logger(double timeSample, double streamPrintPeriod)
: m_timeSample(timeSample), : m_timeSample(timeSample),
m_streamPrintPeriod(streamPrintPeriod), m_streamPrintPeriod(streamPrintPeriod),
m_printCountdown(0.0) m_printCountdown(0.0) {
{ m_lv = VERBOSITY_ERROR;
m_lv = VERBOSITY_ERROR; }
}
Logger::~Logger() {}
Logger::~Logger()
{ void Logger::setVerbosity(LoggerVerbosity lv) { m_lv = lv; }
}
LoggerVerbosity Logger::getVerbosity() { return m_lv; }
void Logger::setVerbosity(LoggerVerbosity lv) void Logger::countdown() {
{ if (m_printCountdown < 0.0) m_printCountdown = m_streamPrintPeriod;
m_lv=lv; m_printCountdown -= m_timeSample;
} }
LoggerVerbosity Logger::getVerbosity() void Logger::sendMsg(std::string msg, MsgType type, const std::string &lineId) {
{ stream(type, lineId) << msg << '\n';
return m_lv; }
} void Logger::sendMsg(std::string msg, MsgType type, const std::string &file,
void Logger::countdown() int line) {
{ std::ostringstream oss;
if(m_printCountdown<0.0) oss << file << line;
m_printCountdown = m_streamPrintPeriod; stream(type, oss.str()) << msg << '\n';
m_printCountdown -= m_timeSample; }
}
bool Logger::setTimeSample(double t) {
void Logger::sendMsg(string msg, MsgType type, const char* file, int line) if (t <= 0.0) return false;
{ m_timeSample = t;
if(m_lv==VERBOSITY_NONE || return true;
(m_lv==VERBOSITY_ERROR && !isErrorMsg(type)) || }
(m_lv==VERBOSITY_WARNING_ERROR && !(isWarningMsg(type) || isErrorMsg(type))) ||
(m_lv==VERBOSITY_INFO_WARNING_ERROR && isDebugMsg(type))) bool Logger::setStreamPrintPeriod(double s) {
return; if (s <= 0.0) return false;
m_streamPrintPeriod = s;
// if print is allowed by current verbosity level return true;
if( isStreamMsg(type)) }
{
// check whether counter already exists double Logger::getTimeSample() { return m_timeSample; }
string id = file+toString(line);
map<string,double>::iterator it = m_stream_msg_counters.find(id); double Logger::getStreamPrintPeriod() { return m_streamPrintPeriod; }
if(it == m_stream_msg_counters.end())
{ bool Logger::checkStreamPeriod(const std::string &lineId) {
// if counter doesn't exist then add one // insert element with value 0 if it does not exist.
m_stream_msg_counters.insert(make_pair(id, 0.0)); // otherwise, return a counter to the existing one.
it = m_stream_msg_counters.find(id); 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 // if counter is greater than 0 then decrement it and do not print
if(it->second>0.0) double &counter = result.first->second;
{ counter -= m_timeSample;
it->second -= m_timeSample; if (counter > 0.0) {
return; return false;
} } else // otherwise reset counter and print
else // otherwise reset counter and print counter = m_streamPrintPeriod;
it->second = m_streamPrintPeriod; return true;
} }
dgRTLOG() << msg.c_str() << "\n";
} } // namespace dynamicgraph
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;
}
} // namespace dynamicgraph
...@@ -8,122 +8,129 @@ ...@@ -8,122 +8,129 @@
#include <dynamic-graph/real-time-logger.h> #include <dynamic-graph/real-time-logger.h>
#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
namespace dynamicgraph namespace dynamicgraph {
{ RealTimeLogger::RealTimeLogger(const std::size_t &bufferSize)
RealTimeLogger::RealTimeLogger (const std::size_t& bufferSize) : buffer_(bufferSize, NULL),
: buffer_(bufferSize, NULL) frontIdx_(0),
, frontIdx_ (0) backIdx_(0),
, backIdx_ (0) oss_(NULL),
, oss_ (NULL) nbDiscarded_(0) {
, nbDiscarded_ (0) for (std::size_t i = 0; i < buffer_.size(); ++i) buffer_[i] = new Data;
{ }
for (std::size_t i = 0; i < buffer_.size(); ++i)
buffer_[i] = new Data;
}
RealTimeLogger::~RealTimeLogger () RealTimeLogger::~RealTimeLogger() {
{ // Check that we are not spinning...
// Check that we are not spinning... for (std::size_t i = 0; i < buffer_.size(); ++i) delete buffer_[i];
for (std::size_t i = 0; i < buffer_.size(); ++i) delete buffer_[i]; }
}
bool RealTimeLogger::spinOnce () bool RealTimeLogger::spinOnce() {
{ if (empty()) return false;
if (empty()) return false; Data *data = buffer_[frontIdx_];
Data* data = buffer_[frontIdx_]; frontIdx_ = (frontIdx_ + 1) % buffer_.size();
frontIdx_ = (frontIdx_ + 1) % buffer_.size(); std::string str = data->buf.str();
std::string str = data->buf.str(); // It is important to pass str.c_str() and not str
// It is important to pass str.c_str() and not str // because the str object may contains a '\0' so
// because the str object may contains a '\0' so // str.size() may be different from strlen(str.c_str())
// str.size() may be different from strlen(str.c_str()) for (std::size_t i = 0; i < outputs_.size(); ++i)
for (std::size_t i = 0; i < outputs_.size(); ++i) outputs_[i]->write(str.c_str());
outputs_[i]->write (str.c_str()); return true;
return true; }
}
RTLoggerStream RealTimeLogger::front () RTLoggerStream RealTimeLogger::front() {
{ // If no output or if buffer is full, discard message.
// If no output or if buffer is full, discard message. if (outputs_.empty() || full()) {
if (outputs_.empty() || full()) { nbDiscarded_++;
nbDiscarded_++; return RTLoggerStream(NULL, oss_);
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_);
} }
bool alone = wmutex.try_lock();
RTLoggerStream::~RTLoggerStream() // If someone is writting, discard message.
{ if (!alone) {
os_ << std::ends; nbDiscarded_++;
if (logger_ != NULL) logger_->frontReady(); 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_; }
struct RealTimeLogger::thread void changeThreadParams() {
{ int threadPolicy;
bool requestShutdown_; struct sched_param threadParam;
boost::thread t_; if (pthread_getschedparam(pthread_self(), &threadPolicy, &threadParam) ==
0) {
thread (RealTimeLogger* logger) threadPolicy = threadPolicy_;
: requestShutdown_ (false) threadParam.sched_priority = threadPriority_;
, t_ (&thread::spin, this, logger) if (threadParam.sched_priority < sched_get_priority_min(threadPolicy))
{} threadParam.sched_priority = sched_get_priority_min(threadPolicy);
void spin (RealTimeLogger* logger) pthread_setschedparam(pthread_self(), threadPolicy, &threadParam);
{ changedThreadParams = false;
// Change the thread's scheduler from real-time to normal and reduce its priority
int threadPolicy;
struct sched_param threadParam;
if (pthread_getschedparam (pthread_self(), &threadPolicy, &threadParam) == 0)
{
threadPolicy = SCHED_OTHER;
threadParam.sched_priority -= 5;
if (threadParam.sched_priority < sched_get_priority_min (threadPolicy))
threadParam.sched_priority = sched_get_priority_min (threadPolicy);
pthread_setschedparam (pthread_self(), threadPolicy, &threadParam);
}
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(100));
}
} }
}; }
RealTimeLogger* RealTimeLogger::instance_ = NULL; void spin(RealTimeLogger *logger) {
RealTimeLogger::thread* RealTimeLogger::thread_ = NULL; // Change the thread's scheduler from real-time to normal
// and reduce its priority
RealTimeLogger& RealTimeLogger::instance() while (!requestShutdown_ || !logger->empty()) {
{ // If the logger did not write anything, it means the buffer is empty.
if (instance_ == NULL) { // Do a pause
instance_ = new RealTimeLogger (1000); if (!logger->spinOnce())
thread_ = new thread (instance_); boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
if (changedThreadParams) changeThreadParams();
} }
return *instance_;
} }
};
RealTimeLogger *RealTimeLogger::instance_ = NULL;
RealTimeLogger::thread *RealTimeLogger::thread_ = NULL;
void RealTimeLogger::destroy () RealTimeLogger &RealTimeLogger::instance() {
{ if (instance_ == NULL) {
if (instance_ == NULL) return; instance_ = new RealTimeLogger(1000);
thread_->requestShutdown_ = true; thread_ = new thread(instance_);
thread_->t_.join();
delete instance_;
delete thread_;
} }
return *instance_;
}
void RealTimeLogger::destroy() {
if (instance_ == NULL) return;
thread_->requestShutdown_ = true;
thread_->t_.join();
delete instance_;
delete thread_;
} }
} // namespace dynamicgraph
...@@ -8,56 +8,46 @@ ...@@ -8,56 +8,46 @@
*/ */
/*! 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);
...@@ -66,201 +56,159 @@ Entity:: ...@@ -66,201 +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);
void Entity:: SignalMap::iterator sigkey = signalMap.find(signame);
signalDeregistration( const std::string& signame ) if (sigkey != signalMap.end()) // key does exist
{
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;
} }
/// 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:: void Entity::sendMsg(const std::string &msg, MsgType t,
sendMsg(const std::string &msg, const std::string &lineId) {
MsgType t, logger_.stream(t, lineId) << "[" << name << "]" << msg << '\n';
const char *file,
int line)
{
logger_.sendMsg("["+name+"]"+msg,t,file,line);
} }
...@@ -2,153 +2,122 @@ ...@@ -2,153 +2,122 @@
// JRL, CNRS/AIST. // JRL, CNRS/AIST.
// //
#include "dynamic-graph/factory.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include "dynamic-graph/debug.h" #include "dynamic-graph/debug.h"
#include "dynamic-graph/factory.h"
using namespace std; using namespace std;
using namespace dynamicgraph; using namespace dynamicgraph;
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);
}
// 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
{
EntityMap::const_iterator lb = entityMap.lower_bound (name);
return lb != entityMap.end ()
&& !(entityMap.key_comp () (name, lb->first));
} }
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.");
}
//FIXME: this should be removed at some point. dgDEBUG(30) << "Register entity <" << entname << "> in the factory."
void << std::endl;
FactoryStorage::listEntities (std::vector<std::string>& outList) const entityMap[entname] = ent;
{
typedef std::pair<std::string, EntityConstructor_ptr> iter_t;
BOOST_FOREACH (const iter_t& entity, entityMap)
outList.push_back(entity.first);
} }
dgDEBUGOUT(25);
EntityRegisterer::EntityRegisterer }
(const std::string& entityClassName, FactoryStorage::EntityConstructor_ptr maker)
: entityName (entityClassName) void FactoryStorage::deregisterEntity(const std::string &entname) {
{ dgDEBUGIN(25);
dgDEBUGIN (15); if (!existEntity(entname)) {
FactoryStorage::getInstance()->registerEntity (entityClassName, maker); DG_THROW ExceptionFactory(
dgDEBUGOUT (15); 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);
EntityRegisterer::~EntityRegisterer () }
{
dgDEBUGIN(15); Entity *FactoryStorage::newEntity(const std::string &classname,
FactoryStorage::getInstance()->deregisterEntity (entityName); const std::string &objname) const {
dgDEBUGOUT (15); 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);
}
// The global factory.
FactoryStorage* FactoryStorage::instance_ = NULL; // This checks efficiently if a key exists in an STL map using the
} // end of namespace dynamicgraph. // approach suggested by Scott Meyer's Effective STL (item 24).
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));
}
// FIXME: this should be removed at some point.
void FactoryStorage::listEntities(std::vector<std::string> &outList) const {
typedef std::pair<std::string, EntityConstructor_ptr> iter_t;
BOOST_FOREACH (const iter_t &entity, entityMap)
outList.push_back(entity.first);
}
EntityRegisterer::EntityRegisterer(const std::string &entityClassName,
FactoryStorage::EntityConstructor_ptr maker)
: entityName(entityClassName) {
dgDEBUGIN(15);
FactoryStorage::getInstance()->registerEntity(entityClassName, maker);
dgDEBUGOUT(15);
}
EntityRegisterer::~EntityRegisterer() {
dgDEBUGIN(15);
FactoryStorage::getInstance()->deregisterEntity(entityName);
dgDEBUGOUT(15);
}
// The global factory.
FactoryStorage *FactoryStorage::instance_ = NULL;
} // end of namespace dynamicgraph.
...@@ -12,11 +12,13 @@ ...@@ -12,11 +12,13 @@
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* --- DYNAMIC-GRAPH --- */ /* --- DYNAMIC-GRAPH --- */
#include "dynamic-graph/pool.h"
#include <list> #include <list>
#include <typeinfo>
#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"
...@@ -26,144 +28,112 @@ using namespace dynamicgraph; ...@@ -26,144 +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();
// Here, this is normal that the next iteration is at the beginning // Here, this is normal that the next iteration is at the beginning
// of the map as deregisterEntity remove the element iter from the map. // of the map as deregisterEntity remove the element iter from the map.
iter=entityMap.begin()) iter = entityMap.begin()) {
{ dgDEBUG(15) << "Delete \"" << (iter->first) << "\"" << std::endl;
dgDEBUG(15) << "Delete \"" Entity *entity = iter->second;
<< (iter->first) <<"\""<<std::endl; deregisterEntity(iter);
Entity* entity = iter->second; delete (entity);
deregisterEntity(iter); }
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>
...@@ -172,15 +142,13 @@ clearPlugin( const std::string& name ) ...@@ -172,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;
...@@ -189,86 +157,77 @@ writeGraph(const std::string &aFileName) ...@@ -189,86 +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 << "}" << std::endl;
GraphFile.close (); GraphFile.close();
} }
void PoolStorage:: void PoolStorage::writeCompletionList(std::ostream &os) {
writeCompletionList(std::ostream& os) for (Entities::iterator iter = entityMap.begin(); iter != entityMap.end();
{ ++iter) {
for( Entities::iterator iter=entityMap.begin (); Entity *ent = iter->second;
iter!=entityMap.end (); ++iter) ent->writeCompletionList(os);
{ }
Entity* ent = iter->second;
ent->writeCompletionList(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);
Entity& ent = getEntity( objname );
return ent.getSignal( signame );
} }
PoolStorage* PoolStorage::instance_ = 0; PoolStorage *PoolStorage::instance_ = 0;
...@@ -2,84 +2,60 @@ ...@@ -2,84 +2,60 @@
// JRL, CNRS/AIST. // JRL, CNRS/AIST.
// //
#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.
...@@ -7,9 +7,10 @@ ...@@ -7,9 +7,10 @@
* *
*/ */
#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;
...@@ -20,40 +21,36 @@ using namespace dynamicgraph; ...@@ -20,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
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#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;
...@@ -19,32 +20,26 @@ using namespace dynamicgraph; ...@@ -19,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
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
#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;
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
...@@ -19,32 +19,26 @@ using namespace dynamicgraph; ...@@ -19,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();
}
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
* *
* CNRS/AIST * CNRS/AIST
* *
*/ */
#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
//
#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