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 1531 additions and 1916 deletions
......@@ -2,113 +2,104 @@
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#ifndef DYNAMIC_GRAPH_TRACER_H
# define DYNAMIC_GRAPH_TRACER_H
# include <string>
# include <list>
# include <boost/function.hpp>
# include <dynamic-graph/signal-base.h>
# include <dynamic-graph/signal-time-dependent.h>
# include <dynamic-graph/time-dependency.h>
# include <dynamic-graph/entity.h>
# include <dynamic-graph/exception-traces.h>
# include <dynamic-graph/config-tracer.hh>
namespace dynamicgraph
{
/// \ingroup plugin
///
/// \brief Tracer plug-in main class.
class DG_TRACER_DLLAPI Tracer : public Entity
{
DYNAMIC_GRAPH_ENTITY_DECL ();
protected:
typedef std::list< const SignalBase<int>* > SignalList;
SignalList toTraceSignals;
public:
enum TraceStyle
{
WHEN_SAID /// Record, then trace to file only when said to.
,EACH_TIME /// Record and trace to file immediately.
,FREQUENTLY /// Record X time then trace (X is tuned by setFrenquence () ).
};
TraceStyle traceStyle;
static const TraceStyle TRACE_STYLE_DEFAULT = EACH_TIME;
double frequency;
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;
#define DYNAMIC_GRAPH_TRACER_H
#include <dynamic-graph/entity.h>
#include <dynamic-graph/exception-traces.h>
#include <dynamic-graph/signal-base.h>
#include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/time-dependency.h>
#include <boost/function.hpp>
#include <dynamic-graph/config-tracer.hh>
#include <list>
#include <mutex>
#include <string>
namespace dynamicgraph {
/// \ingroup plugin
///
/// \brief Tracer plug-in main class.
class DG_TRACER_DLLAPI Tracer : public Entity {
DYNAMIC_GRAPH_ENTITY_DECL();
protected:
typedef std::list<const SignalBase<int> *> SignalList;
SignalList toTraceSignals;
std::mutex files_mtx;
public:
enum TraceStyle {
WHEN_SAID
/// Record, then trace to file only when said to.
,
EACH_TIME
/// Record and trace to file immediately.
,
FREQUENTLY
/// Record X time then trace (X is tuned by setFrenquence () ).
};
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_TRACER_H
TraceStyle traceStyle;
static const TraceStyle TRACE_STYLE_DEFAULT = EACH_TIME;
double frequency;
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
......@@ -3,124 +3,140 @@
//
// Author: Florent Lamiraux
//
// This file is part of dynamic-graph.
// dynamic-graph is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
// dynamic-graph is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details. You should
// have received a copy of the GNU Lesser General Public License along
// with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#ifndef DYNAMIC_GRAPH_VALUE_H
#define DYNAMIC_GRAPH_VALUE_H
#include <string>
#include <dynamic-graph/linear-algebra.h>
#include <cassert>
#include <string>
#include <typeinfo>
#include <vector>
#include "dynamic-graph/dynamic-graph-api.h"
#include <dynamic-graph/linear-algebra.h>
namespace dynamicgraph {
namespace command {
class Value;
class DYNAMIC_GRAPH_DLLAPI EitherType {
public:
EitherType(const Value& value);
~EitherType();
operator bool () const;
operator unsigned () const;
operator int () const;
operator float () const;
operator double () const;
operator std::string () const;
operator Vector () const;
operator Eigen::MatrixXd () const;
operator Eigen::Matrix4d () const;
private:
const Value* value_;
};
namespace command {
class Value;
typedef std::vector<Value> Values;
class DYNAMIC_GRAPH_DLLAPI EitherType {
public:
EitherType(const Value &value);
~EitherType();
operator bool() const;
operator unsigned() const;
operator unsigned long int() const;
operator int() const;
operator long int() const;
operator float() const;
operator double() const;
operator std::string() const;
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 {
public:
enum Type {
NONE,
BOOL,
UNSIGNED,
INT,
FLOAT,
DOUBLE,
STRING,
VECTOR,
MATRIX,
MATRIX4D,
NB_TYPES
};
~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
///
/// For instance,
/// \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);
/// Return the value as a castable value into the approriate type
///
/// For instance,
/// \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
DYNAMIC_GRAPH_DLLAPI friend std::ostream &operator<<(std::ostream &os,
const Value &value);
/// Output in a stream
DYNAMIC_GRAPH_DLLAPI friend std::ostream& operator<<(std::ostream& os, const Value& value);
public:
friend class EitherType;
bool boolValue() const;
unsigned unsignedValue() const;
int intValue() const;
float floatValue() const;
double doubleValue() const;
std::string stringValue() const;
Vector vectorValue() const;
Eigen::MatrixXd matrixXdValue() const;
Eigen::Matrix4d matrix4dValue() const;
Type type_;
const void* const value_;
};
public:
friend class EitherType;
bool boolValue() const;
unsigned unsignedValue() const;
unsigned long int unsignedlongintValue() const;
int intValue() const;
long int longintValue() const;
float floatValue() const;
double doubleValue() const;
std::string stringValue() const;
Vector vectorValue() const;
Eigen::MatrixXd matrixXdValue() const;
Eigen::Matrix4d matrix4dValue() const;
Values valuesValue() const;
const Values &constValuesValue() const;
Type type_;
const void *const value_;
};
/* ---- HELPER ---------------------------------------------------------- */
// Note: to ensure the WIN32 compatibility, it is necessary to export
// the template specialization. Also, it is forbidden to do the template
// specialization declaration in the header file, for the same reason.
template< typename T >
struct DYNAMIC_GRAPH_DLLAPI ValueHelper
{
static const Value::Type TypeID;
};
} // namespace command
} //namespace dynamicgraph
/* ---- HELPER ---------------------------------------------------------- */
// Note: to ensure the WIN32 compatibility, it is necessary to export
// the template specialization. Also, it is forbidden to do the template
// specialization declaration in the header file, for the same reason.
template <typename T>
struct DYNAMIC_GRAPH_DLLAPI ValueHelper {
static const Value::Type TypeID;
};
} // namespace command
} // namespace dynamicgraph
#endif //DYNAMIC_GRAPH_VALUE_H
#endif // DYNAMIC_GRAPH_VALUE_H
<html>
<body>
<script src="https://github.com/mdaines/viz.js/releases/download/v2.1.2/viz.js"></script>
<script src="https://github.com/mdaines/viz.js/releases/download/v2.1.2/full.render.js"></script>
<script>
function renderDOTFile() {
var fileInputElement = document.getElementById("fileInputElement");
var reader = new FileReader();
var graphtextres = ""
reader.onloadend = function(e) {
graphtextres = e.target.result
var viz = new Viz();
viz.renderSVGElement(graphtextres)
.then(function(element) {
elementToRemove=document.getElementById("displaysvgzone")
if (elementToRemove != null)
{
document.body.removeChild(elementToRemove)
}
document.body.appendChild(element)
element.id="displaysvgzone"
})
.catch(error => {
// Create a new Viz instance (@see Caveats page for more info)
viz = new Viz();
// Possibly display the error
console.error(error);
});
}
reader.readAsText(fileInputElement.files[0]);
};
</script>
<input type="file" id="fileInputElement">
<input id="Rendering" type="button" value="Rendering" onclick="renderDOTFile();" />
<script>
var el = document.getElementById("Rendering");
if (el.addEventListener)
el.addEventListener("click", renderDOTFile, false);
else if (el.attachEvent)
el.attachEvent('onclick', renderDOTFile);
</script>
</body>
</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
#
# This file is part of dynamic-graph.
# dynamic-graph is free software:
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
####################################
### Main Library
####################################
SET(LIBRARY_NAME ${PROJECT_NAME})
set(plugins traces/tracer traces/tracer-real-time)
# Verbosity level
IF (NOT (\"${CMAKE_VERBOSITY_LEVEL}\" STREQUAL \"\"))
ADD_DEFINITIONS(-DVP_DEBUG_MODE=${CMAKE_VERBOSITY_LEVEL} -DVP_DEBUG)
ENDIF (NOT (\"${CMAKE_VERBOSITY_LEVEL}\" STREQUAL \"\"))
set(tracer-real-time_deps tracer)
# Declare boost include directories
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
foreach(plugin ${plugins})
get_filename_component(LIBRARY_NAME ${plugin} NAME)
add_library(${LIBRARY_NAME} SHARED "${plugin}.cpp")
ADD_LIBRARY(${LIBRARY_NAME}
SHARED
debug/debug.cpp
debug/real-time-logger.cpp
debug/logger.cpp
if(SUFFIX_SO_VERSION)
set_target_properties(${LIBRARY_NAME} PROPERTIES SOVERSION
${PROJECT_VERSION})
endif(SUFFIX_SO_VERSION)
set_target_properties(${LIBRARY_NAME} PROPERTIES INSTALL_RPATH $ORIGIN)
dgraph/entity.cpp
dgraph/factory.cpp
dgraph/pool.cpp
target_link_libraries(${LIBRARY_NAME} PUBLIC ${PROJECT_NAME}
${${LIBRARY_NAME}_deps})
exception/exception-abstract.cpp
exception/exception-factory.cpp
exception/exception-signal.cpp
exception/exception-traces.cpp
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)
install(
TARGETS ${LIBRARY_NAME}
EXPORT ${TARGETS_EXPORT_NAME}
DESTINATION ${DYNAMIC_GRAPH_PLUGINDIR})
endforeach(plugin)
......@@ -3,91 +3,55 @@
//
// Author: Florent Lamiraux
//
// This file is part of dynamic-graph.
// dynamic-graph is free software:
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#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>();
Command::~Command() {}
Command::Command(Entity& entity,
const std::vector<Value::Type>& valueTypes,
const std::string& docstring) :
owner_(entity), valueTypeVector_(valueTypes), docstring_(docstring)
{
}
#include <sstream>
const std::vector<Value::Type>& Command::valueTypes() const
{
return valueTypeVector_;
}
#include "dynamic-graph/exception-abstract.h"
void Command::setParameterValues(const std::vector<Value>& values)
{
const std::vector<Value::Type>& paramTypes = valueTypes();
// Check that number of parameters is correct
if (values.size() != paramTypes.size()) {
throw ExceptionAbstract(ExceptionAbstract::ABSTRACT,
"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;
namespace dynamicgraph {
namespace command {
const std::vector<Value::Type> Command::EMPTY_ARG = std::vector<Value::Type>();
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 {
return valueTypeVector_;
}
void Command::setParameterValues(const std::vector<Value> &values) {
const std::vector<Value::Type> &paramTypes = valueTypes();
// Check that number of parameters is correct
if (values.size() != paramTypes.size()) {
throw ExceptionAbstract(ExceptionAbstract::ABSTRACT,
"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
{
return valueVector_;
}
const std::vector<Value> &Command::getParameterValues() const {
return valueVector_;
}
Value Command::execute()
{
return doExecute();
}
Value Command::execute() { return doExecute(); }
Entity& Command::owner()
{
return owner_;
}
std::string Command::getDocstring() const
{
return docstring_;
}
} // namespace command
} //namespace dynamicgraph
Entity &Command::owner() { return owner_; }
std::string Command::getDocstring() const { return docstring_; }
} // namespace command
} // namespace dynamicgraph
......@@ -3,382 +3,380 @@
//
// Author: Florent Lamiraux
//
// This file is part of dynamic-graph.
// dynamic-graph is free software:
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "dynamic-graph/value.h"
#include "dynamic-graph/exception-abstract.h"
namespace dynamicgraph {
namespace command {
static void* copyValue(const Value& value);
EitherType::EitherType(const Value& value) : value_(new Value(value))
{
}
EitherType::~EitherType()
{
delete value_;
value_ = NULL;
}
EitherType::operator bool() const
{
return value_->boolValue();
}
EitherType::operator unsigned() const
{
return value_->unsignedValue();
}
EitherType::operator int() const
{
return value_->intValue();
}
EitherType::operator float() const
{
return value_->floatValue();
}
EitherType::operator double() const
{
return value_->doubleValue();
}
EitherType::operator std::string() const
{
return value_->stringValue();
}
EitherType::operator Vector() const
{
return value_->vectorValue();
}
EitherType::operator Eigen::MatrixXd() const
{
return value_->matrixXdValue();
}
EitherType::operator Eigen::Matrix4d() const
{
return value_->matrix4dValue();
}
void Value::deleteValue ()
{
switch(type_) {
case BOOL:
delete(const bool*)value_;
break;
case UNSIGNED:
delete(const unsigned*)value_;
break;
case INT:
delete(const int*)value_;
break;
case FLOAT:
delete(const float*)value_;
break;
case DOUBLE:
delete(const double*)value_;
break;
case STRING:
delete(const std::string*)value_;
break;
case VECTOR:
delete(const Vector*)value_;
break;
case MATRIX:
delete(const Eigen::MatrixXd*)value_;
break;
case MATRIX4D:
delete(const Eigen::Matrix4d*)value_;
break;
default:;
}
}
Value::~Value()
{
deleteValue ();
}
Value::Value(const bool& value) : type_(BOOL), value_(new bool(value))
{
}
Value::Value(const unsigned& value) : type_(UNSIGNED),
value_(new unsigned(value))
{
}
Value::Value(const int& value) : type_(INT),
value_(new int(value))
{
}
Value::Value(const float& value) : type_(FLOAT),
value_(new float(value))
{
}
Value::Value(const 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(const Eigen::MatrixXd& value) : type_(MATRIX),
value_(new Eigen::MatrixXd(value))
{
}
Value::Value(const Eigen::Matrix4d& value) : type_(MATRIX4D),
value_(new Eigen::Matrix4d(value))
{
}
Value::Value(const Value& value) : type_(value.type_),
value_(copyValue(value))
{
}
void* copyValue(const Value& value)
{
void* copy;
switch(value.type()) {
case Value::NONE:
copy = NULL;
break;
case Value::BOOL:
copy = new bool(value.boolValue());
break;
case Value::UNSIGNED:
copy = new unsigned(value.unsignedValue());
break;
case Value::INT:
copy = new int(value.intValue());
break;
case Value::FLOAT:
copy = new float(value.floatValue());
break;
case Value::DOUBLE:
copy = new double(value.doubleValue());
break;
case Value::STRING:
copy = new std::string(value.stringValue());
break;
case Value::VECTOR:
copy = new Vector(value.vectorValue());
break;
case Value::MATRIX:
copy = new Eigen::MatrixXd(value.matrixXdValue());
break;
case Value::MATRIX4D:
copy = new Eigen::Matrix4d(value.matrix4dValue());
break;
default:
abort();
}
return copy;
}
Value::Value() : type_(NONE), value_(NULL)
{
}
Value Value::operator=(const Value& value)
{
if (&value != this) {
if(value_ != 0x0)
deleteValue ();
type_ = value.type_;
void** ptValue = const_cast<void**>(&value_);
*ptValue = copyValue(value);
}
return *this;
}
const EitherType Value::value() const
{
return EitherType(*this);
}
Value::Type Value::type() const
{
return type_;
}
bool Value::boolValue() const
{
if(type_ == BOOL)
return *((const bool*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an bool");
}
unsigned Value::unsignedValue() const
{
if(type_ == UNSIGNED)
return *((const unsigned*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an unsigned int");
}
int Value::intValue() const
{
if(type_ == INT)
return *((const int*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an int int");
}
float Value::floatValue() const
{
float result;
if(FLOAT != type_)
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a float");
result = *((const float*)value_);
return result;
}
double Value::doubleValue() const
{
double result;
if(DOUBLE != type_)
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a double");
result = *((const double*)value_);
return result;
}
std::string Value::stringValue() const
{
if(type_ == STRING)
return *((const std::string*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an string");
}
Vector Value::vectorValue() const
{
if(type_ == VECTOR)
return *((const Vector*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an vector");
}
Eigen::MatrixXd Value::matrixXdValue() const
{
if(type_ == MATRIX)
return *((const Eigen::MatrixXd*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a Eigen matrixXd");
}
Eigen::Matrix4d Value::matrix4dValue() const
{
if(type_ == MATRIX4D)
return *((const Eigen::Matrix4d*)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a Eigen matrix4d");
}
std::string Value::typeName(Type type)
{
switch(type) {
case BOOL:
return std::string("bool");
case UNSIGNED:
return std::string("unsigned int");
case INT:
return std::string("int");
case FLOAT:
return std::string("float");
case DOUBLE:
return std::string("double");
case STRING:
return std::string("string");
case VECTOR:
return std::string("vector");
case MATRIX:
return std::string("matrixXd");
case MATRIX4D:
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_) {
case Value::BOOL:
os << value.boolValue();
break;
case Value::UNSIGNED:
os << value.unsignedValue();
break;
case Value::INT:
os << value.intValue();
break;
case Value::DOUBLE:
os << value.doubleValue();
break;
case Value::FLOAT:
os << value.floatValue();
break;
case Value::STRING:
os << value.stringValue();
break;
case Value::VECTOR:
os << value.vectorValue();
break;
case Value::MATRIX:
os << value.matrixXdValue();
break;
case Value::MATRIX4D:
os << value.matrix4dValue();
break;
default:
return os;
}
namespace command {
static void *copyValue(const Value &value);
EitherType::EitherType(const Value &value) : value_(new Value(value)) {}
EitherType::~EitherType() {
delete value_;
value_ = NULL;
}
EitherType::operator bool() const { return value_->boolValue(); }
EitherType::operator unsigned() const { return value_->unsignedValue(); }
EitherType::operator unsigned long int() const {
return value_->unsignedlongintValue();
}
EitherType::operator int() const { return value_->intValue(); }
EitherType::operator long int() const { return value_->longintValue(); }
EitherType::operator float() const { return value_->floatValue(); }
EitherType::operator double() const { return value_->doubleValue(); }
EitherType::operator std::string() const { return value_->stringValue(); }
EitherType::operator Vector() const { return value_->vectorValue(); }
EitherType::operator Eigen::MatrixXd() const { return value_->matrixXdValue(); }
EitherType::operator Eigen::Matrix4d() const { return value_->matrix4dValue(); }
EitherType::operator Values() const { return value_->valuesValue(); }
void Value::deleteValue() {
switch (type_) {
case BOOL:
delete (const bool *)value_;
break;
case UNSIGNED:
delete (const unsigned *)value_;
break;
case UNSIGNEDLONGINT:
delete (const unsigned long int *)value_;
break;
case INT:
delete (const int *)value_;
break;
case LONGINT:
delete (const long int *)value_;
break;
case FLOAT:
delete (const float *)value_;
break;
case DOUBLE:
delete (const double *)value_;
break;
case STRING:
delete (const std::string *)value_;
break;
case VECTOR:
delete (const Vector *)value_;
break;
case MATRIX:
delete (const Eigen::MatrixXd *)value_;
break;
case MATRIX4D:
delete (const Eigen::Matrix4d *)value_;
break;
case VALUES:
delete (const Values *)value_;
break;
case NONE: /* Equivalent to void */
break;
default:
throw "Value::deleteValue : Undefined type";
;
}
}
Value::~Value() { deleteValue(); }
Value::Value(const bool &value) : type_(BOOL), value_(new bool(value)) {}
Value::Value(const unsigned &value)
: type_(UNSIGNED), value_(new unsigned(value)) {}
Value::Value(const unsigned long int &value)
: type_(UNSIGNEDLONGINT), value_(new unsigned long int(value)) {}
Value::Value(const int &value) : type_(INT), value_(new int(value)) {}
Value::Value(const float &value) : type_(FLOAT), value_(new float(value)) {}
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(const Eigen::MatrixXd &value)
: type_(MATRIX), value_(new Eigen::MatrixXd(value)) {}
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 Value &value)
: type_(value.type_), value_(copyValue(value)) {}
void *copyValue(const Value &value) {
void *copy;
switch (value.type()) {
case Value::NONE:
copy = NULL;
break;
case Value::BOOL:
copy = new bool(value.boolValue());
break;
case Value::UNSIGNED:
copy = new unsigned(value.unsignedValue());
break;
case Value::UNSIGNEDLONGINT:
copy = new unsigned long int(value.unsignedlongintValue());
break;
case Value::INT:
copy = new int(value.intValue());
break;
case Value::LONGINT:
copy = new long int(value.longintValue());
break;
case Value::FLOAT:
copy = new float(value.floatValue());
break;
case Value::DOUBLE:
copy = new double(value.doubleValue());
break;
case Value::STRING:
copy = new std::string(value.stringValue());
break;
case Value::VECTOR:
copy = new Vector(value.vectorValue());
break;
case Value::MATRIX:
copy = new Eigen::MatrixXd(value.matrixXdValue());
break;
case Value::MATRIX4D:
copy = new Eigen::Matrix4d(value.matrix4dValue());
break;
case Value::VALUES:
copy = new Values(value.valuesValue());
break;
default:
abort();
}
return copy;
}
Value::Value() : type_(NONE), value_(NULL) {}
Value Value::operator=(const Value &value) {
if (&value != this) {
if (value_ != 0x0) deleteValue();
type_ = value.type_;
void **ptValue = const_cast<void **>(&value_);
*ptValue = copyValue(value);
}
return *this;
}
bool Value::operator==(const Value &other) const {
if (type_ != other.type_) return false;
switch (type_) {
case Value::BOOL:
return boolValue() == other.boolValue();
case Value::UNSIGNED:
return unsignedValue() == other.unsignedValue();
case Value::UNSIGNEDLONGINT:
return unsignedlongintValue() == other.unsignedlongintValue();
case Value::INT:
return intValue() == other.intValue();
case Value::DOUBLE:
return doubleValue() == other.doubleValue();
case Value::FLOAT:
return floatValue() == other.floatValue();
case Value::STRING:
return stringValue() == other.stringValue();
case Value::VECTOR:
return vectorValue() == other.vectorValue();
case Value::MATRIX:
return matrixXdValue() == other.matrixXdValue();
case Value::MATRIX4D:
return matrix4dValue() == other.matrix4dValue();
case Value::VALUES:
return constValuesValue() == other.constValuesValue();
case Value::NONE:
break;
default:
break;
}
return false;
}
const EitherType Value::value() const { return EitherType(*this); }
Value::Type Value::type() const { return type_; }
bool Value::boolValue() const {
if (type_ == BOOL) return *((const bool *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an bool");
}
unsigned Value::unsignedValue() const {
if (type_ == UNSIGNED) return *((const unsigned *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an unsigned int");
}
unsigned long int Value::unsignedlongintValue() const {
if (type_ == UNSIGNEDLONGINT) return *((const unsigned long int *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not an unsigned long int");
}
long int Value::longintValue() const {
if (type_ == LONGINT) return *((const long int *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an long int");
}
int Value::intValue() const {
if (type_ == INT) return *((const int *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an int");
}
float Value::floatValue() const {
float result;
if (FLOAT != type_)
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a float");
result = *((const float *)value_);
return result;
}
double Value::doubleValue() const {
double result;
if (DOUBLE != type_)
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a double");
result = *((const double *)value_);
return result;
}
std::string Value::stringValue() const {
if (type_ == STRING) return *((const std::string *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an string");
}
Vector Value::vectorValue() const {
if (type_ == VECTOR) return *((const Vector *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an vector");
}
Eigen::MatrixXd Value::matrixXdValue() const {
if (type_ == MATRIX) return *((const Eigen::MatrixXd *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a Eigen matrixXd");
}
Eigen::Matrix4d Value::matrix4dValue() const {
if (type_ == MATRIX4D) return *((const Eigen::Matrix4d *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a Eigen matrix4d");
}
Values Value::valuesValue() const {
if (type_ == VALUES) return *((const Values *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a vector of Value");
}
const Values &Value::constValuesValue() const {
if (type_ == VALUES) return *((const Values *)value_);
throw ExceptionAbstract(ExceptionAbstract::TOOLS,
"value is not a vector of Value");
}
std::string Value::typeName(Type type) {
switch (type) {
case BOOL:
return std::string("bool");
case UNSIGNED:
return std::string("unsigned int");
case UNSIGNEDLONGINT:
return std::string("unsigned long int");
case INT:
return std::string("int");
case FLOAT:
return std::string("float");
case DOUBLE:
return std::string("double");
case STRING:
return std::string("string");
case VECTOR:
return std::string("vector");
case MATRIX:
return std::string("matrixXd");
case MATRIX4D:
return std::string("matrix4d");
case VALUES:
return std::string("values");
default:
return std::string("unknown");
}
}
std::ostream &operator<<(std::ostream &os, const Value &value) {
os << "Type=" << Value::typeName(value.type_) << ", value=";
switch (value.type_) {
case Value::BOOL:
os << value.boolValue();
break;
case Value::UNSIGNED:
os << value.unsignedValue();
break;
case Value::UNSIGNEDLONGINT:
os << value.unsignedlongintValue();
break;
case Value::INT:
os << value.intValue();
break;
case Value::DOUBLE:
os << value.doubleValue();
break;
case Value::FLOAT:
os << value.floatValue();
break;
case Value::STRING:
os << value.stringValue();
break;
case Value::VECTOR:
os << value.vectorValue();
break;
case Value::MATRIX:
os << value.matrixXdValue();
break;
case Value::MATRIX4D:
os << value.matrix4dValue();
break;
case Value::VALUES: {
const std::vector<Value> &vals = value.constValuesValue();
os << "[ ";
for (std::size_t i = 0; i < vals.size(); ++i)
os << "Value(" << vals[i] << "), ";
os << "]";
} break;
default:
return os;
}
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<> 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;
} // namespace command
} //namespace dynamicgraph
}
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<unsigned long int>::TypeID =
Value::UNSIGNEDLONGINT;
template <>
const Value::Type ValueHelper<int>::TypeID = Value::INT;
template <>
const Value::Type ValueHelper<float>::TypeID = Value::FLOAT;
template <>
const Value::Type ValueHelper<double>::TypeID = Value::DOUBLE;
template <>
const Value::Type ValueHelper<std::string>::TypeID = Value::STRING;
template <>
const Value::Type ValueHelper<Vector>::TypeID = Value::VECTOR;
template <>
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
......@@ -5,82 +5,55 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <dynamic-graph/debug.h>
#include <fstream>
#include <ios>
using namespace dynamicgraph;
#ifdef WIN32
const char * DebugTrace::DEBUG_FILENAME_DEFAULT = "c:/tmp/dynamic-graph-traces.txt";
#else /*WIN32*/
const char * DebugTrace::DEBUG_FILENAME_DEFAULT = "/tmp/dynamic-graph-traces.txt";
#endif /*WIN32*/
const char *DebugTrace::DEBUG_FILENAME_DEFAULT =
"c:/tmp/dynamic-graph-traces.txt";
#else /*WIN32*/
const char *DebugTrace::DEBUG_FILENAME_DEFAULT =
"/tmp/dynamic-graph-traces.txt";
#endif /*WIN32*/
#ifdef VP_DEBUG
#ifdef WIN32
std::ofstream dg_debugfile( "C:/tmp/dynamic-graph-traces.txt", std::ios::trunc&std::ios::out );
#else /*WIN32*/
std::ofstream dg_debugfile( "/tmp/dynamic-graph-traces.txt", std::ios::trunc&std::ios::out );
#endif /*WIN32*/
#ifdef WIN32
std::ofstream dg_debugfile("C:/tmp/dynamic-graph-traces.txt",
std::ios::trunc &std::ios::out);
#else /*WIN32*/
std::ofstream dg_debugfile("/tmp/dynamic-graph-traces.txt",
std::ios::trunc &std::ios::out);
#endif /*WIN32*/
#else
std::ofstream dg_debugfile; //( "/dev/null", std::ios::trunc&std::ios::out );
class dgDebug_init
{
std::ofstream dg_debugfile;
class dgDebug_init {
public:
dgDebug_init ()
{ dg_debugfile.setstate( std::ios::failbit ) ; /* dg_debugfile.close (); */ }
};
dgDebug_init dgDebug_initialisator;
dgDebug_init() { dg_debugfile.setstate(std::ios::failbit); }
};
dgDebug_init dgDebug_initialisator;
#endif
namespace dynamicgraph {
DebugTrace dgDEBUGFLOW(dg_debugfile);
DebugTrace dgERRORFLOW(dg_debugfile);
}
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 );
//std::cout << filename << dg_debugfile.good () << dg_debugfile.is_open () << std::endl;
DebugTrace dgDEBUGFLOW(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::closeFile(const char *)
{
if( dg_debugfile.good ()&&dg_debugfile.is_open () ) { dg_debugfile.close (); }
dg_debugfile.setstate( std::ios::failbit ) ;
void DebugTrace::closeFile(const char *) {
if (dg_debugfile.good() && dg_debugfile.is_open()) {
dg_debugfile.close();
}
dg_debugfile.setstate(std::ios::failbit);
}
//DebugTrace dgDebugFLOW(std::cout);
//DebugTrace dgERRORFLOW(std::cerr);
/*
* Copyright 2015, 2019
* Copyright 2015, 2019
* LAAS-CNRS
* Andrea Del Prete, François Bailly, Olivier Stasse
*
* This file is part of dynamic-graph.
* See license file.
*
*/
#ifndef WIN32
......@@ -14,94 +12,74 @@
#endif
#define ENABLE_RT_LOG
#include <stdio.h>
#include <iostream>
#include <iomanip> // std::setprecision
#include <dynamic-graph/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_streamPrintPeriod(streamPrintPeriod),
m_printCountdown(0.0)
{
m_lv = VERBOSITY_ERROR;
}
Logger::~Logger()
{
}
void Logger::setVerbosity(LoggerVerbosity lv)
{
m_lv=lv;
}
LoggerVerbosity Logger::getVerbosity()
{
return m_lv;
}
void Logger::countdown()
{
if(m_printCountdown<0.0)
m_printCountdown = m_streamPrintPeriod;
m_printCountdown -= m_timeSample;
}
void Logger::sendMsg(string msg, MsgType type, const char* file, int line)
{
if(m_lv==VERBOSITY_NONE ||
(m_lv==VERBOSITY_ERROR && !isErrorMsg(type)) ||
(m_lv==VERBOSITY_WARNING_ERROR && !(isWarningMsg(type) || isErrorMsg(type))) ||
(m_lv==VERBOSITY_INFO_WARNING_ERROR && isDebugMsg(type)))
return;
// if print is allowed by current verbosity level
if(isStreamMsg(type))
{
// check whether counter already exists
string id = file+toString(line);
map<string,double>::iterator it = m_stream_msg_counters.find(id);
if(it == m_stream_msg_counters.end())
{
// if counter doesn't exist then add one
m_stream_msg_counters.insert(make_pair(id, 0.0));
it = m_stream_msg_counters.find(id);
}
// if counter is greater than 0 then decrement it and do not print
if(it->second>0.0)
{
it->second -= m_timeSample;
return;
}
else // otherwise reset counter and print
it->second = m_streamPrintPeriod;
}
dgRTLOG() << msg.c_str() << "\n";
}
bool Logger::setTimeSample(double t)
{
if(t<=0.0)
return false;
m_timeSample = t;
return true;
}
bool Logger::setStreamPrintPeriod(double s)
{
if(s<=0.0)
return false;
m_streamPrintPeriod = s;
return true;
}
} // namespace dynamicgraph
m_printCountdown(0.0) {
m_lv = VERBOSITY_ERROR;
}
Logger::~Logger() {}
void Logger::setVerbosity(LoggerVerbosity lv) { m_lv = lv; }
LoggerVerbosity Logger::getVerbosity() { return m_lv; }
void Logger::countdown() {
if (m_printCountdown < 0.0) m_printCountdown = m_streamPrintPeriod;
m_printCountdown -= m_timeSample;
}
void Logger::sendMsg(std::string msg, MsgType type, const std::string &lineId) {
stream(type, lineId) << msg << '\n';
}
void Logger::sendMsg(std::string msg, MsgType type, const std::string &file,
int line) {
std::ostringstream oss;
oss << file << line;
stream(type, oss.str()) << msg << '\n';
}
bool Logger::setTimeSample(double t) {
if (t <= 0.0) return false;
m_timeSample = t;
return true;
}
bool Logger::setStreamPrintPeriod(double s) {
if (s <= 0.0) return false;
m_streamPrintPeriod = s;
return true;
}
double Logger::getTimeSample() { return m_timeSample; }
double Logger::getStreamPrintPeriod() { return m_streamPrintPeriod; }
bool Logger::checkStreamPeriod(const std::string &lineId) {
// insert element with value 0 if it does not exist.
// otherwise, return a counter to the existing one.
std::pair<StreamCounterMap_t::iterator, bool> result =
m_stream_msg_counters.insert(std::make_pair(lineId, 0.));
// if counter is greater than 0 then decrement it and do not print
double &counter = result.first->second;
counter -= m_timeSample;
if (counter > 0.0) {
return false;
} else // otherwise reset counter and print
counter = m_streamPrintPeriod;
return true;
}
} // namespace dynamicgraph
......@@ -4,137 +4,133 @@
*
* LAAS-CNRS
*
* This file is part of dynamic-graph.
* dynamic-graph is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* dynamic-graph is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dynamic-graph/real-time-logger.h>
#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
namespace dynamicgraph
{
RealTimeLogger::RealTimeLogger (const std::size_t& bufferSize)
: buffer_(bufferSize, NULL)
, frontIdx_ (0)
, backIdx_ (0)
, oss_ (NULL)
, nbDiscarded_ (0)
{
for (std::size_t i = 0; i < buffer_.size(); ++i)
buffer_[i] = new Data;
}
namespace dynamicgraph {
RealTimeLogger::RealTimeLogger(const std::size_t &bufferSize)
: buffer_(bufferSize, NULL),
frontIdx_(0),
backIdx_(0),
oss_(NULL),
nbDiscarded_(0) {
for (std::size_t i = 0; i < buffer_.size(); ++i) buffer_[i] = new Data;
}
RealTimeLogger::~RealTimeLogger ()
{
// Check that we are not spinning...
for (std::size_t i = 0; i < buffer_.size(); ++i) delete buffer_[i];
}
RealTimeLogger::~RealTimeLogger() {
// Check that we are not spinning...
for (std::size_t i = 0; i < buffer_.size(); ++i) delete buffer_[i];
}
bool RealTimeLogger::spinOnce ()
{
if (empty()) return false;
Data* data = buffer_[frontIdx_];
frontIdx_ = (frontIdx_ + 1) % buffer_.size();
std::string str = data->buf.str();
// It is important to pass str.c_str() and not str
// because the str object may contains a '\0' so
// str.size() may be different from strlen(str.c_str())
for (std::size_t i = 0; i < outputs_.size(); ++i)
outputs_[i]->write (str.c_str());
return true;
}
bool RealTimeLogger::spinOnce() {
if (empty()) return false;
Data *data = buffer_[frontIdx_];
frontIdx_ = (frontIdx_ + 1) % buffer_.size();
std::string str = data->buf.str();
// It is important to pass str.c_str() and not str
// because the str object may contains a '\0' so
// str.size() may be different from strlen(str.c_str())
for (std::size_t i = 0; i < outputs_.size(); ++i)
outputs_[i]->write(str.c_str());
return true;
}
RTLoggerStream RealTimeLogger::front ()
{
// If no output or if buffer is full, discard message.
if (outputs_.empty() || full()) {
nbDiscarded_++;
return RTLoggerStream (NULL, oss_);
}
bool alone = wmutex.try_lock();
// If someone is writting, discard message.
if (!alone) {
nbDiscarded_++;
return RTLoggerStream (NULL, oss_);
}
Data* data = buffer_[backIdx_];
//backIdx_ = (backIdx_+1) % buffer_.size();
// Reset position of cursor
data->buf.pubseekpos(0);
oss_.rdbuf(&data->buf);
return RTLoggerStream (this, oss_);
RTLoggerStream RealTimeLogger::front() {
// If no output or if buffer is full, discard message.
if (outputs_.empty() || full()) {
nbDiscarded_++;
return RTLoggerStream(NULL, oss_);
}
RTLoggerStream::~RTLoggerStream()
{
os_ << std::ends;
if (logger_ != NULL) logger_->frontReady();
bool alone = wmutex.try_lock();
// If someone is writting, discard message.
if (!alone) {
nbDiscarded_++;
return RTLoggerStream(NULL, oss_);
}
Data *data = buffer_[backIdx_];
// backIdx_ = (backIdx_+1) % buffer_.size();
// Reset position of cursor
data->buf.pubseekpos(0);
oss_.rdbuf(&data->buf);
return RTLoggerStream(this, oss_);
}
struct RealTimeLogger::thread {
bool requestShutdown_;
int threadPolicy_;
int threadPriority_;
bool changedThreadParams;
boost::thread t_;
explicit thread(RealTimeLogger *logger)
: requestShutdown_(false),
threadPolicy_(SCHED_OTHER),
threadPriority_(0),
changedThreadParams(true),
t_(&thread::spin, this, logger) {}
// void setThreadPolicy(int policy) {
// threadPolicy_ = policy;
// changedThreadParams = true;
// }
// void setPriority(int priority) {
// threadPriority_ = priority;
// changedThreadParams = true;
// }
// int getThreadPolicy() { return threadPolicy_; }
// int getThreadPriority() { return threadPriority_; }
struct RealTimeLogger::thread
{
bool requestShutdown_;
boost::thread t_;
thread (RealTimeLogger* logger)
: requestShutdown_ (false)
, t_ (&thread::spin, this, logger)
{}
void spin (RealTimeLogger* logger)
{
// 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));
}
void changeThreadParams() {
int threadPolicy;
struct sched_param threadParam;
if (pthread_getschedparam(pthread_self(), &threadPolicy, &threadParam) ==
0) {
threadPolicy = threadPolicy_;
threadParam.sched_priority = threadPriority_;
if (threadParam.sched_priority < sched_get_priority_min(threadPolicy))
threadParam.sched_priority = sched_get_priority_min(threadPolicy);
pthread_setschedparam(pthread_self(), threadPolicy, &threadParam);
changedThreadParams = false;
}
};
}
RealTimeLogger* RealTimeLogger::instance_ = NULL;
RealTimeLogger::thread* RealTimeLogger::thread_ = NULL;
void spin(RealTimeLogger *logger) {
// Change the thread's scheduler from real-time to normal
// and reduce its priority
RealTimeLogger& RealTimeLogger::instance()
{
if (instance_ == NULL) {
instance_ = new RealTimeLogger (1000);
thread_ = new thread (instance_);
while (!requestShutdown_ || !logger->empty()) {
// If the logger did not write anything, it means the buffer is empty.
// Do a pause
if (!logger->spinOnce())
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
if (changedThreadParams) changeThreadParams();
}
return *instance_;
}
};
RealTimeLogger *RealTimeLogger::instance_ = NULL;
RealTimeLogger::thread *RealTimeLogger::thread_ = NULL;
void RealTimeLogger::destroy ()
{
if (instance_ == NULL) return;
thread_->requestShutdown_ = true;
thread_->t_.join();
delete instance_;
delete thread_;
RealTimeLogger &RealTimeLogger::instance() {
if (instance_ == NULL) {
instance_ = new RealTimeLogger(1000);
thread_ = new thread(instance_);
}
return *instance_;
}
void RealTimeLogger::destroy() {
if (instance_ == NULL) return;
thread_->requestShutdown_ = true;
thread_->t_.join();
delete instance_;
delete thread_;
}
} // namespace dynamicgraph
......@@ -5,81 +5,49 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*! Local framework includes */
#include <dynamic-graph/command.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/entity.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/command.h>
/*! System includes */
#include <stdlib.h>
#include <sstream>
#include <sstream>
using namespace std;
using namespace dynamicgraph;
using dynamicgraph::command::Command;
void Entity::
entityRegistration ()
{
PoolStorage::getInstance()->registerEntity(name,this);
void Entity::entityRegistration() {
PoolStorage::getInstance()->registerEntity(name, this);
}
void Entity::
entityDeregistration ()
{
void Entity::entityDeregistration() {
PoolStorage::getInstance()->deregisterEntity(name);
}
Entity::
Entity( const string& name__ )
: name(name__)
{
dgDEBUG(15) << "New entity <"<<name__<<">"<<endl;
if( name.length ()==0 )
{
stringstream oss; oss << rand ();
//name = this->getClassName(); Cannot call a virtual function from the constructor
name+="::";
name+=oss.str ();
}
Entity::Entity(const string &name__) : name(name__) {
dgDEBUG(15) << "New entity <" << name__ << ">" << endl;
if (name.length() == 0) {
stringstream oss;
oss << rand();
// name = this->getClassName();
// Cannot call a virtual function from the constructor
name += "::";
name += oss.str();
}
entityRegistration ();
entityRegistration();
}
Entity::
~Entity ()
{
Entity::~Entity() {
dgDEBUG(25) << "# In (" << name << " { " << endl;
for (std::map<const std::string, Command*>::iterator it =
commandMap.begin(); it != commandMap.end(); it++) {
for (std::map<const std::string, Command *>::iterator it = commandMap.begin();
it != commandMap.end(); ++it) {
delete it->second;
}
dgDEBUGOUT(25);
......@@ -88,202 +56,159 @@ Entity::
/* -------------------------------------------------------------------------- */
/* --- SIGNALS -------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Entity::
signalRegistration( const SignalArray<int>& signals )
{
for( unsigned int i=0;i<signals.getSize ();++i )
{
SignalBase<int>& sig = signals[i];
//const string& signame = sig.getName ();
istringstream iss( sig.getName () );
const int SIZE = 128;
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;
}
void Entity::signalRegistration(const SignalArray<int> &signals) {
for (unsigned int i = 0; i < signals.getSize(); ++i) {
SignalBase<int> &sig = signals[i];
// const string& signame = sig.getName ();
istringstream iss(sig.getName());
const int SIZE = 128;
char buffer[SIZE];
while (iss.good()) {
iss.getline(buffer, SIZE, ':');
}
}
const string &signame(buffer);
void Entity::
signalDeregistration( const std::string& signame )
{
SignalMap::iterator sigkey = signalMap.find(signame);
if( sigkey == signalMap.end () ) // key does not exist
SignalMap::iterator sigkey = signalMap.find(signame);
if (sigkey != signalMap.end()) // key does 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);
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;
}
}
}
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 docString ("No header documentation.");
std::string Entity::getDocString() const {
std::string docString("No header documentation.");
return docString;
}
#define __DG_ENTITY_GET_SIGNAL__(ITER_TYPE) \
SignalMap::ITER_TYPE sigkey = signalMap.find(signame); \
if( sigkey == signalMap.end () ) /* key does NOT exist */ \
{ \
throw ExceptionFactory( ExceptionFactory::UNREFERED_SIGNAL,\
"The requested signal is not registered",\
": %s",signame.c_str () );\
}\
return *(sigkey ->second) ;
#define __DG_ENTITY_GET_SIGNAL__(ITER_TYPE) \
SignalMap::ITER_TYPE sigkey = signalMap.find(signame); \
if (sigkey == signalMap.end()) /* key does NOT exist */ \
{ \
throw ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL, \
"The requested signal is not registered", ": %s", \
signame.c_str()); \
} \
return *(sigkey->second);
bool Entity::
hasSignal( const string & signame ) const
{
return (!(signalMap.find(signame) == signalMap.end ()));
bool Entity::hasSignal(const string &signame) const {
return (!(signalMap.find(signame) == signalMap.end()));
}
SignalBase<int>& Entity::
getSignal( const string & signame )
{
SignalBase<int> &Entity::getSignal(const string &signame) {
__DG_ENTITY_GET_SIGNAL__(iterator);
}
const SignalBase<int>& Entity::
getSignal( const string & signame ) const
{
const SignalBase<int> &Entity::getSignal(const string &signame) const {
__DG_ENTITY_GET_SIGNAL__(const_iterator);
}
std::ostream& Entity::
displaySignalList( std::ostream& os ) const
{
os << "--- <" << getName () << "> signal list: "<<endl;
const SignalMap::const_iterator iterend=signalMap.end ();
for( SignalMap::const_iterator iter = signalMap.begin ();iterend!=iter;++iter )
{
os << " "; if( (++iter)--==iterend ) os << "`"; else os <<"|";
os << "-- <" << *(iter->second) << endl;
}
std::ostream &Entity::displaySignalList(std::ostream &os) const {
os << "--- <" << getName() << "> signal list: " << endl;
const SignalMap::const_iterator iterend = signalMap.end();
for (SignalMap::const_iterator iter = signalMap.begin(); iterend != iter;
++iter) {
os << " ";
if ((++iter)-- == iterend)
os << "`";
else
os << "|";
os << "-- <" << *(iter->second) << endl;
}
return os;
}
std::ostream& Entity::
writeGraph( std::ostream& os ) const
{
const SignalMap::const_iterator iterend=signalMap.end ();
for( SignalMap::const_iterator iter = signalMap.begin ();iterend!=iter;++iter )
{
(*(iter->second)).writeGraph(os);
}
std::ostream &Entity::writeGraph(std::ostream &os) const {
const SignalMap::const_iterator iterend = signalMap.end();
for (SignalMap::const_iterator iter = signalMap.begin(); iterend != iter;
++iter) {
(*(iter->second)).writeGraph(os);
}
return os;
}
std::ostream& Entity::
writeCompletionList( std::ostream& os ) const
{
const SignalMap::const_iterator iterend=signalMap.end ();
for( SignalMap::const_iterator iter = signalMap.begin ();iterend!=iter;++iter )
{
os << getName () << "." << (*(iter->second)).shortName () << std::endl;
}
std::ostream &Entity::writeCompletionList(std::ostream &os) const {
const SignalMap::const_iterator iterend = signalMap.end();
for (SignalMap::const_iterator iter = signalMap.begin(); iterend != iter;
++iter) {
os << getName() << "." << (*(iter->second)).shortName() << std::endl;
}
os << getCommandList () << std::endl;
os << getCommandList() << std::endl;
return os;
}
void Entity::
display( std::ostream& os ) const
{
os<<this->getClassName ()<<": "<<name;
void Entity::display(std::ostream &os) const {
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);
return os;
}
Entity::SignalMap Entity::getSignalMap() const
{
return signalMap;
}
Entity::SignalMap Entity::getSignalMap() const { return signalMap; }
/* --- PARAMS --------------------------------------------------------------- */
/* --- PARAMS --------------------------------------------------------------- */
/* --- PARAMS --------------------------------------------------------------- */
static std::string Entity_COMMAND_LIST = "print\nsignals\nsignalDep";
const std::string& Entity::
getCommandList () const
{
const std::string &Entity::getCommandList() const {
return Entity_COMMAND_LIST;
}
/// Add a command to Entity
void Entity::
addCommand(const std::string& inName, Command* command)
{
void Entity::addCommand(const std::string &inName, Command *command) {
if (commandMap.count(inName) != 0) {
DG_THROW ExceptionFactory(ExceptionFactory::OBJECT_CONFLICT,
"Command " + inName +
" already registered in Entity.");
DG_THROW ExceptionFactory(
ExceptionFactory::OBJECT_CONFLICT,
"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);
}
/// Return the list of command objects
std::map<const std::string, Command*> Entity::
getNewStyleCommandMap()
{
std::map<const std::string, Command *> Entity::getNewStyleCommandMap() {
return commandMap;
}
Command* Entity::
getNewStyleCommand( const std::string& commandName )
{
if (commandMap.count(commandName) != 1)
{
DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_FUNCTION,
"Command <" + commandName +
"> is not registered in Entity.");
}
Command *Entity::getNewStyleCommand(const std::string &commandName) {
if (commandMap.count(commandName) != 1) {
DG_THROW ExceptionFactory(
ExceptionFactory::UNREFERED_FUNCTION,
"Command <" + commandName + "> is not registered in Entity.");
}
return commandMap[commandName];
}
void Entity::
sendMsg(const std::string &msg,
MsgType t,
const char *file,
int line)
{
logger_.sendMsg("["+name+"]"+msg,t,file,line);
void Entity::sendMsg(const std::string &msg, MsgType t,
const std::string &lineId) {
logger_.stream(t, lineId) << "[" << name << "]" << msg << '\n';
}
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
// This file is part of dynamic-graph.
// dynamic-graph is free software:
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "dynamic-graph/factory.h"
#include <boost/foreach.hpp>
#include "dynamic-graph/debug.h"
#include "dynamic-graph/factory.h"
using namespace std;
using namespace dynamicgraph;
namespace dynamicgraph
{
FactoryStorage* FactoryStorage::getInstance ()
{
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));
namespace dynamicgraph {
FactoryStorage *FactoryStorage::getInstance() {
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.");
}
//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);
dgDEBUG(30) << "Register entity <" << entname << "> in the factory."
<< std::endl;
entityMap[entname] = ent;
}
EntityRegisterer::EntityRegisterer
(const std::string& entityClassName, FactoryStorage::EntityConstructor_ptr maker)
: entityName (entityClassName)
{
dgDEBUGIN (15);
FactoryStorage::getInstance()->registerEntity (entityClassName, maker);
dgDEBUGOUT (15);
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);
}
EntityRegisterer::~EntityRegisterer ()
{
dgDEBUGIN(15);
FactoryStorage::getInstance()->deregisterEntity (entityName);
dgDEBUGOUT (15);
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());
}
// The global factory.
FactoryStorage* FactoryStorage::instance_ = NULL;
} // end of namespace dynamicgraph.
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));
}
// 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.
......@@ -5,29 +5,6 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software:
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided that the following
* conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* --------------------------------------------------------------------- */
......@@ -35,11 +12,13 @@
/* --------------------------------------------------------------------- */
/* --- DYNAMIC-GRAPH --- */
#include "dynamic-graph/pool.h"
#include <list>
#include <typeinfo>
#include <sstream>
#include <string>
#include "dynamic-graph/pool.h"
#include <typeinfo>
#include "dynamic-graph/debug.h"
#include "dynamic-graph/entity.h"
......@@ -49,144 +28,112 @@ using namespace dynamicgraph;
/* --- CLASS ----------------------------------------------------------- */
/* --------------------------------------------------------------------- */
PoolStorage* PoolStorage::
getInstance()
{
PoolStorage *PoolStorage::getInstance() {
if (instance_ == 0) {
instance_ = new PoolStorage;
}
return instance_;
}
void PoolStorage::
destroy()
{
void PoolStorage::destroy() {
delete instance_;
instance_ = NULL;
}
PoolStorage::
~PoolStorage ()
{
PoolStorage::~PoolStorage() {
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
// of the map as deregisterEntity remove the element iter from the map.
iter=entityMap.begin())
{
dgDEBUG(15) << "Delete \""
<< (iter->first) <<"\""<<std::endl;
Entity* entity = iter->second;
deregisterEntity(iter);
delete (entity);
}
iter = entityMap.begin()) {
dgDEBUG(15) << "Delete \"" << (iter->first) << "\"" << std::endl;
Entity *entity = iter->second;
deregisterEntity(iter);
delete (entity);
}
instance_ = 0;
dgDEBUGOUT(15);
}
/* --------------------------------------------------------------------- */
void PoolStorage::
registerEntity( const std::string& entname,Entity* ent )
{
void PoolStorage::registerEntity(const std::string &entname, Entity *ent) {
Entities::iterator entkey = entityMap.find(entname);
if( entkey != entityMap.end () ) // key does exist
{
throw ExceptionFactory( ExceptionFactory::OBJECT_CONFLICT,
"Another entity already defined with the same name. ",
"Entity name is <%s>.",entname.c_str () );
}
else
{
dgDEBUG(10) << "Register entity <"<< entname
<< "> in the pool." <<std::endl;
entityMap[entname] = ent;
}
if (entkey != entityMap.end()) // key does exist
{
throw ExceptionFactory(
ExceptionFactory::OBJECT_CONFLICT,
"Another entity already defined with the same name. ",
"Entity name is <%s>.", entname.c_str());
} else {
dgDEBUG(10) << "Register entity <" << entname << "> in the pool."
<< std::endl;
entityMap[entname] = ent;
}
}
void PoolStorage::
deregisterEntity( const std::string& entname )
{
void PoolStorage::deregisterEntity(const std::string &entname) {
Entities::iterator entkey = entityMap.find(entname);
if( entkey == entityMap.end () ) // key doesnot exist
{
throw ExceptionFactory( ExceptionFactory::OBJECT_CONFLICT,
"Entity not defined yet. ",
"Entity name is <%s>.",entname.c_str () );
}
else
{
dgDEBUG(10) << "Deregister entity <"<< entname
<< "> from the pool." <<std::endl;
deregisterEntity(entkey);
}
if (entkey == entityMap.end()) // key doesnot exist
{
throw ExceptionFactory(ExceptionFactory::OBJECT_CONFLICT,
"Entity not defined yet. ", "Entity name is <%s>.",
entname.c_str());
} else {
dgDEBUG(10) << "Deregister entity <" << entname << "> from the pool."
<< std::endl;
deregisterEntity(entkey);
}
}
void PoolStorage::
deregisterEntity( const Entities::iterator& entity )
{
entityMap.erase( entity );
void PoolStorage::deregisterEntity(const Entities::iterator &entity) {
entityMap.erase(entity);
}
Entity& PoolStorage::
getEntity( const std::string& name )
{
dgDEBUG(25) << "Get <" << name << ">"<<std::endl;
Entities::iterator entPtr = entityMap.find( name );
if( entPtr == entityMap.end () )
{
DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_OBJECT,
"Unknown entity."," (while calling <%s>)",
name.c_str () );
}
else return *entPtr->second;
Entity &PoolStorage::getEntity(const std::string &name) {
dgDEBUG(25) << "Get <" << name << ">" << std::endl;
Entities::iterator entPtr = entityMap.find(name);
if (entPtr == entityMap.end()) {
DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_OBJECT,
"Unknown entity.", " (while calling <%s>)",
name.c_str());
} else
return *entPtr->second;
}
const PoolStorage::Entities& PoolStorage::
getEntityMap () const
{
const PoolStorage::Entities &PoolStorage::getEntityMap() const {
return entityMap;
}
bool PoolStorage::
existEntity (const std::string& name)
{
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) {
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;
}
}
void PoolStorage::
clearPlugin( const std::string& name )
{
void PoolStorage::clearPlugin(const std::string &name) {
dgDEBUGIN(5);
std::list<Entity*> toDelete;
std::list<Entity *> toDelete;
for (Entities::iterator entPtr = entityMap.begin ();
entPtr != entityMap.end (); ++entPtr)
if (entPtr->second->getClassName () == name)
toDelete.push_back (entPtr->second);
for (Entities::iterator entPtr = entityMap.begin(); entPtr != entityMap.end();
++entPtr)
if (entPtr->second->getClassName() == name)
toDelete.push_back(entPtr->second);
for (std::list< Entity* >::iterator iter = toDelete.begin ();
iter != toDelete.end (); ++iter)
delete (Entity*) *iter;
for (std::list<Entity *>::iterator iter = toDelete.begin();
iter != toDelete.end(); ++iter)
delete (Entity *)*iter;
dgDEBUGOUT(5);
}
/* --------------------------------------------------------------------- */
#include <dynamic-graph/entity.h>
......@@ -195,15 +142,13 @@ clearPlugin( const std::string& name )
#include <time.h>
#endif /*WIN32*/
void PoolStorage::
writeGraph(const std::string &aFileName)
{
void PoolStorage::writeGraph(const std::string &aFileName) {
size_t IdxPointFound = aFileName.rfind(".");
std::string tmp1 = aFileName.substr(0,IdxPointFound);
std::string tmp1 = aFileName.substr(0, IdxPointFound);
size_t IdxSeparatorFound = aFileName.rfind("/");
std::string GenericName;
if (IdxSeparatorFound!=std::string::npos)
GenericName = tmp1.substr(IdxSeparatorFound,tmp1.length ());
if (IdxSeparatorFound != std::string::npos)
GenericName = tmp1.substr(IdxSeparatorFound, tmp1.length());
else
GenericName = tmp1;
......@@ -212,87 +157,77 @@ writeGraph(const std::string &aFileName)
ltime = time(NULL);
struct tm ltimeformatted;
#ifdef WIN32
localtime_s(&ltimeformatted,&ltime);
localtime_s(&ltimeformatted, &ltime);
#else
localtime_r(&ltime,&ltimeformatted);
localtime_r(&ltime, &ltimeformatted);
#endif /*WIN32*/
/* 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 << " " << 1900+ltimeformatted.tm_year
<< " Month: " << 1+ltimeformatted.tm_mon
<< " Day: " << ltimeformatted.tm_mday
<< " Time: " << ltimeformatted.tm_hour
<< ":" << ltimeformatted.tm_min;
GraphFile << " " << 1900 + ltimeformatted.tm_year
<< " Month: " << 1 + ltimeformatted.tm_mon
<< " Day: " << ltimeformatted.tm_mday
<< " Time: " << ltimeformatted.tm_hour << ":"
<< ltimeformatted.tm_min;
GraphFile << " */" << std::endl;
GraphFile << "digraph \"" << GenericName << "\" { ";
GraphFile << "\t graph [ label=\"" << GenericName << "\" bgcolor = white rankdir=LR ]" << std::endl
<< "\t node [ fontcolor = black, color = black, fillcolor = gold1, style=filled, shape=box ] ; " << std::endl;
GraphFile << "\t graph [ label=\"" << GenericName
<< "\" 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 << "\t} " << std::endl;
for( Entities::iterator iter=entityMap.begin ();
iter!=entityMap.end (); ++iter)
{
Entity* ent = iter->second;
GraphFile << "\"" << ent->getName () << "\""
<<" [ label = \"" << ent->getName () << "\" ," << std::endl
<<" fontcolor = black, color = black, fillcolor=cyan, style=filled, shape=box ]" << std::endl;
ent->writeGraph(GraphFile);
}
for (Entities::iterator iter = entityMap.begin(); iter != entityMap.end();
++iter) {
Entity *ent = iter->second;
GraphFile << "\"" << ent->getName() << "\""
<< " [ label = \"" << ent->getName() << "\" ," << std::endl
<< " fontcolor = black, color = black, fillcolor=cyan,"
<< " style=filled, shape=box ]" << std::endl;
ent->writeGraph(GraphFile);
}
GraphFile << "}"<< std::endl;
GraphFile << "}" << std::endl;
GraphFile.close ();
GraphFile.close();
}
void PoolStorage::
writeCompletionList(std::ostream& os)
{
for( Entities::iterator iter=entityMap.begin ();
iter!=entityMap.end (); ++iter)
{
Entity* ent = iter->second;
ent->writeCompletionList(os);
}
void PoolStorage::writeCompletionList(std::ostream &os) {
for (Entities::iterator iter = entityMap.begin(); iter != entityMap.end();
++iter) {
Entity *ent = iter->second;
ent->writeCompletionList(os);
}
}
static bool
objectNameParser( std::istringstream& cmdparse,
std::string& objName,
std::string& funName )
{
const int SIZE=128;
static bool objectNameParser(std::istringstream &cmdparse, std::string &objName,
std::string &funName) {
const int SIZE = 128;
char buffer[SIZE];
cmdparse >> std::ws;
cmdparse.getline( buffer,SIZE,'.' );
if(! cmdparse.good () ) // The callback is not an object method
cmdparse.getline(buffer, SIZE, '.');
if (!cmdparse.good()) // The callback is not an object method
return false;
objName = buffer;
//cmdparse.getline( buffer,SIZE );
//funName = buffer;
// cmdparse.getline( buffer,SIZE );
// funName = buffer;
cmdparse >> funName;
return true;
}
SignalBase<int>&
PoolStorage::
getSignal( std::istringstream& sigpath )
{
std::string objname,signame;
if(! objectNameParser( sigpath,objname,signame ) )
{ DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_SIGNAL,
"Parse error in signal name" ); }
Entity& ent = getEntity( objname );
return ent.getSignal( signame );
}
SignalBase<int> &PoolStorage::getSignal(std::istringstream &sigpath) {
std::string objname, signame;
if (!objectNameParser(sigpath, objname, signame)) {
DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL,
"Parse error in signal name");
}
PoolStorage* PoolStorage::instance_ = 0;
Entity &ent = getEntity(objname);
return ent.getSignal(signame);
}
PoolStorage *PoolStorage::instance_ = 0;
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
// This file is part of dynamic-graph.
// dynamic-graph is free software:
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstring>
#include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-abstract.h>
namespace dynamicgraph {
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);
}
#include <cstring>
std::ostream&
operator << (std::ostream& os,
const ExceptionAbstract& error)
{
os << error.getExceptionName ()
<< "Error [#" << error.code << "]: " << error.message << std::endl;
namespace dynamicgraph {
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 &operator<<(std::ostream &os, const ExceptionAbstract &error) {
os << error.getExceptionName() << "Error [#" << error.code
<< "]: " << error.message << std::endl;
#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
if (error.p.set)
os << "Thrown from " << error.p.file << ": " << error.p.function
<<" (#" << error.p.line << ")"<< std::endl;
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
if (error.p.set)
os << "Thrown from " << error.p.file << ": " << error.p.function << " (#"
<< error.p.line << ")" << std::endl;
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
return os;
}
return os;
}
} // end of namespace dynamicgraph.
} // end of namespace dynamicgraph.
......@@ -5,33 +5,12 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-factory.h>
#include <stdarg.h>
#include <cstdio>
using namespace dynamicgraph;
......@@ -42,40 +21,36 @@ using namespace dynamicgraph;
const std::string ExceptionFactory::EXCEPTION_NAME = "Factory";
ExceptionFactory::
ExceptionFactory ( const ExceptionFactory::ErrorCodeEnum& errcode,
const std::string & msg )
:ExceptionAbstract(errcode,msg)
{
dgDEBUGF( 15,"Created with message <%s>.",msg.c_str ());
dgDEBUG( 1) <<"Created with message <%s>."<<msg<<std::endl;
ExceptionFactory::ExceptionFactory(
const ExceptionFactory::ErrorCodeEnum &errcode, const std::string &msg)
: ExceptionAbstract(errcode, msg) {
dgDEBUGF(15, "Created with message <%s>.", msg.c_str());
dgDEBUG(1) << "Created with message <%s>." << msg << std::endl;
}
ExceptionFactory::
ExceptionFactory ( const ExceptionFactory::ErrorCodeEnum& errcode,
const std::string & msg,const char* format, ... )
:ExceptionAbstract(errcode,msg)
{
ExceptionFactory::ExceptionFactory(
const ExceptionFactory::ErrorCodeEnum &errcode, const std::string &msg,
const char *format, ...)
: ExceptionAbstract(errcode, msg) {
va_list args;
va_start(args,format);
va_start(args, format);
const unsigned int SIZE = 256;
char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args);
char buffer[SIZE];
vsnprintf(buffer, SIZE, format, args);
dgDEBUG(15) <<"Created "<<" with message <"
<<msg<<"> and buffer <"<<buffer<<">. "<<std::endl;
dgDEBUG(15) << "Created "
<< " with message <" << msg << "> and buffer <" << buffer << ">. "
<< std::endl;
message += buffer;
va_end(args);
dgDEBUG(1) << "Throw exception " << EXCEPTION_NAME << "[#" << errcode<<"]: "
<<"<"<< message << ">."<<std::endl;
dgDEBUG(1) << "Throw exception " << EXCEPTION_NAME << "[#" << errcode << "]: "
<< "<" << message << ">." << std::endl;
}
/*
* Local variables:
* c-basic-offset: 2
......
......@@ -5,32 +5,11 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <dynamic-graph/exception-signal.h>
#include <stdarg.h>
#include <cstdio>
using namespace dynamicgraph;
......@@ -41,32 +20,26 @@ using namespace dynamicgraph;
const std::string ExceptionSignal::EXCEPTION_NAME = "Signal";
ExceptionSignal::
ExceptionSignal ( const ExceptionSignal::ErrorCodeEnum& errcode,
const std::string & msg )
:ExceptionAbstract(errcode,msg)
{
}
ExceptionSignal::ExceptionSignal(const ExceptionSignal::ErrorCodeEnum &errcode,
const std::string &msg)
: ExceptionAbstract(errcode, msg) {}
ExceptionSignal::
ExceptionSignal ( const ExceptionSignal::ErrorCodeEnum& errcode,
const std::string & msg,const char* format, ... )
:ExceptionAbstract(errcode,msg)
{
ExceptionSignal::ExceptionSignal(const ExceptionSignal::ErrorCodeEnum &errcode,
const std::string &msg, const char *format,
...)
: ExceptionAbstract(errcode, msg) {
va_list args;
va_start(args,format);
va_start(args, format);
const unsigned int SIZE = 256;
char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args);
char buffer[SIZE];
vsnprintf(buffer, SIZE, format, args);
message += buffer;
va_end(args);
}
/*
* Local variables:
* c-basic-offset: 2
......
......@@ -5,34 +5,12 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <dynamic-graph/exception-traces.h>
#include <stdarg.h>
#include <cstdio>
#include <cstdio>
using namespace dynamicgraph;
/* --------------------------------------------------------------------- */
......@@ -41,32 +19,26 @@ using namespace dynamicgraph;
const std::string ExceptionTraces::EXCEPTION_NAME = "Traces";
ExceptionTraces::
ExceptionTraces ( const ExceptionTraces::ErrorCodeEnum& errcode,
const std::string & msg )
:ExceptionAbstract(errcode,msg)
{
}
ExceptionTraces::ExceptionTraces(const ExceptionTraces::ErrorCodeEnum &errcode,
const std::string &msg)
: ExceptionAbstract(errcode, msg) {}
ExceptionTraces::
ExceptionTraces ( const ExceptionTraces::ErrorCodeEnum& errcode,
const std::string & msg,const char* format, ... )
:ExceptionAbstract(errcode,msg)
{
ExceptionTraces::ExceptionTraces(const ExceptionTraces::ErrorCodeEnum &errcode,
const std::string &msg, const char *format,
...)
: ExceptionAbstract(errcode, msg) {
va_list args;
va_start(args,format);
va_start(args, format);
const unsigned int SIZE = 256;
char buffer[SIZE];
vsnprintf(buffer,SIZE,format,args);
char buffer[SIZE];
vsnprintf(buffer, SIZE, format, args);
message += buffer;
va_end(args);
}
/*
* Local variables:
* 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,32 +5,10 @@
*
* CNRS/AIST
*
* This file is part of dynamic-graph.
* dynamic-graph is free software:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#include <dynamic-graph/signal-array.h>
namespace dynamicgraph {
SignalArray<int> sotNOSIGNAL(0);
SignalArray<int> sotNOSIGNAL(0);
}
// -*- c++-mode -*-
// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse, Nicolas Mansard
//
// This file is part of dynamic-graph.
// dynamic-graph is free software:
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#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