From 48e05f15284f3039eeb56f381b44d5a6befcf04f Mon Sep 17 00:00:00 2001 From: Olivier Stasse <ostasse@laas.fr> Date: Sun, 18 Aug 2019 23:41:34 +0200 Subject: [PATCH] Fix typo. Enforce 80 columns policy. --- include/dynamic-graph/command-bind.h | 756 ++++++++++-------- include/dynamic-graph/command-direct-getter.h | 69 +- include/dynamic-graph/command-direct-setter.h | 72 +- include/dynamic-graph/command-getter.t.cpp | 37 +- include/dynamic-graph/command-setter.t.cpp | 568 +++++++------ include/dynamic-graph/command.h | 105 +-- include/dynamic-graph/debug.h | 149 ++-- include/dynamic-graph/eigen-io.h | 264 +++--- include/dynamic-graph/entity.h | 170 ++-- include/dynamic-graph/exception-abstract.h | 88 +- include/dynamic-graph/exception-factory.h | 64 +- include/dynamic-graph/exception-signal.h | 58 +- include/dynamic-graph/exception-traces.h | 36 +- include/dynamic-graph/factory.h | 308 +++---- include/dynamic-graph/logger.h | 69 +- include/dynamic-graph/process-list.hh | 304 +++---- include/dynamic-graph/real-time-logger.h | 312 ++++---- include/dynamic-graph/signal-array.h | 242 +++--- include/dynamic-graph/signal-base.h | 343 ++++---- include/dynamic-graph/signal-cast-helper.h | 245 +++--- include/dynamic-graph/signal-caster.h | 173 ++-- include/dynamic-graph/signal-helper.h | 38 +- include/dynamic-graph/signal-ptr.h | 235 +++--- include/dynamic-graph/signal-ptr.t.cpp | 440 +++++----- include/dynamic-graph/signal-time-dependent.h | 121 ++- include/dynamic-graph/signal.h | 182 ++--- include/dynamic-graph/signal.t.cpp | 462 ++++++----- include/dynamic-graph/time-dependency.h | 110 +-- include/dynamic-graph/time-dependency.t.cpp | 299 ++++--- include/dynamic-graph/tracer-real-time.h | 114 +-- include/dynamic-graph/tracer.h | 157 ++-- include/dynamic-graph/value.h | 178 +++-- src/CMakeLists.txt | 4 +- src/command/command.cpp | 17 +- src/command/value.cpp | 491 ++++++------ src/debug/debug.cpp | 19 +- src/debug/logger.cpp | 137 ++-- src/debug/real-time-logger.cpp | 234 +++--- src/dgraph/entity.cpp | 184 +++-- src/dgraph/factory.cpp | 130 +-- src/dgraph/pool.cpp | 150 ++-- src/exception/exception-abstract.cpp | 73 +- src/exception/exception-factory.cpp | 18 +- src/exception/exception-signal.cpp | 17 +- src/exception/exception-traces.cpp | 13 +- src/mt/process-list.cpp | 53 +- src/signal/signal-cast-helper.cpp | 124 +-- src/signal/signal-caster.cpp | 174 ++-- src/traces/tracer-real-time.cpp | 114 ++- src/traces/tracer.cpp | 107 ++- tests/command-test.cpp | 115 +-- tests/pool.cpp | 124 ++- 52 files changed, 5103 insertions(+), 3963 deletions(-) diff --git a/include/dynamic-graph/command-bind.h b/include/dynamic-graph/command-bind.h index f4387f1..0702fb2 100644 --- a/include/dynamic-graph/command-bind.h +++ b/include/dynamic-graph/command-bind.h @@ -10,13 +10,13 @@ /* Create a command from a bind directly. Examples are: * addCommand("myProcVoid", - * makeCommandVoid0(*this,&ClassName::functionNoArg, - * docCommandVoid0("Simple line doc here."))); + * makeCommandVoid0(*this,&ClassName::functionNoArg, + * docCommandVoid0("Simple line doc here."))); * addCommand("myProcOneString", - * makeCommandVoid1(*this,&EntityName::functionOneStringArg, - * docCommandVoid1("Simple line doc here.", - * "string"))); + * makeCommandVoid1(*this,&EntityName::functionOneStringArg, + * docCommandVoid1("Simple line doc here.", + * "string"))); * */ @@ -25,342 +25,452 @@ #include <boost/function.hpp> #include <boost/bind.hpp> -/* --- FUNCTION 0 ARGS ------------------------------------------------------ */ -namespace dynamicgraph { -namespace command { - -template <class E> -struct CommandVoid0 : public Command { - CommandVoid0(E& entity, boost::function<void(void)> function, const std::string& docString) - : Command(entity, EMPTY_ARG, docString), fptr(function) {} - - protected: - virtual Value doExecute() { - assert(getParameterValues().size() == 0); - fptr(); - return Value(); // void - } - - private: - boost::function<void(void)> fptr; -}; - -template <class E> -CommandVoid0<E>* makeCommandVoid0(E& entity, boost::function<void(void)> function, const std::string& docString) { - return new CommandVoid0<E>(entity, function, docString); -} - -template <class E> -CommandVoid0<E>* makeCommandVoid0(E& entity, boost::function<void(E*)> function, const std::string& docString) { - return new CommandVoid0<E>(entity, boost::bind(function, &entity), docString); -} - -template <class E> -CommandVoid0<E>* makeCommandVoid0(E& entity, void (E::*function)(void), const std::string& docString) { - return new CommandVoid0<E>(entity, boost::bind(function, &entity), docString); -} - -inline std::string docCommandVoid0(const std::string& doc) { - return std::string("\n") + doc + "\n\nNo input.\nVoid return.\n\n"; -} - -} // namespace command +/* --- FUNCTION 0 ARGS ----------------------------------------------------- */ +namespace dynamicgraph +{ + namespace command + { + + template <class E> + struct CommandVoid0 : public Command + { + CommandVoid0(E& entity, boost::function<void(void)> + function, const std::string& docString) + : Command(entity, EMPTY_ARG, docString), fptr(function) {} + + protected: + virtual Value doExecute() + { + assert(getParameterValues().size() == 0); + fptr(); + return Value(); // void + } + + private: + boost::function<void(void)> fptr; + }; + + template <class E> + CommandVoid0<E>* makeCommandVoid0 + (E& entity, boost::function<void(void)> function, + const std::string& docString) + { + return new CommandVoid0<E>(entity, function, docString); + } + + template <class E> + CommandVoid0<E>* + makeCommandVoid0 + (E& entity, boost::function<void(E*)> function, + const std::string& docString) + { + return new CommandVoid0<E>(entity, boost::bind(function, &entity), + docString); + } + + template <class E> + CommandVoid0<E>* + makeCommandVoid0 + (E& entity, void (E::*function)(void), const std::string& docString) + { + return new CommandVoid0<E>(entity, boost::bind(function, &entity), + docString); + } + + inline std::string docCommandVoid0(const std::string& doc) + { + return std::string("\n") + doc + "\n\nNo input.\nVoid return.\n\n"; + } + + } // namespace command } // namespace dynamicgraph /* --- FUNCTION 1 ARGS ------------------------------------------------------ */ -namespace dynamicgraph { -namespace command { - -template <class E, typename T> -struct CommandVoid1 : public Command { - typedef boost::function<void(const T&)> function_t; - typedef boost::function<void(E*, const T&)> memberFunction_t; - typedef void (E::*memberFunction_ptr_t)(const T&); - - CommandVoid1(E& entity, function_t function, const std::string& docString) - : Command(entity, boost::assign::list_of(ValueHelper<T>::TypeID), docString), fptr(function) {} - - protected: - virtual Value doExecute() { - assert(getParameterValues().size() == 1); - T val = getParameterValues()[0].value(); - fptr(val); - return Value(); // void - } - - private: - function_t fptr; -}; - -template <class E, typename T> -CommandVoid1<E, T>* makeCommandVoid1(E& entity, boost::function<void(const T&)> function, - // typename CommandVoid1<E,T>::function_t function , - const std::string& docString) { - return new CommandVoid1<E, T>(entity, function, docString); -} - -template <class E, typename T> -CommandVoid1<E, T>* makeCommandVoid1(E& entity, - // The following syntaxt don't compile when not specializing the template - // arg... why ??? - // typename CommandVoid1<E,T>::memberFunction_t function , - boost::function<void(E*, const T&)> function, const std::string& docString) { - return new CommandVoid1<E, T>(entity, boost::bind(function, &entity, _1), docString); -} - -template <class E, typename T> -CommandVoid1<E, T>* makeCommandVoid1(E& entity, void (E::*function)(const T&), const std::string& docString) { - return new CommandVoid1<E, T>(entity, boost::bind(function, &entity, _1), docString); - return NULL; -} - -inline std::string docCommandVoid1(const std::string& doc, const std::string& type) { - return std::string("\n") + doc + "\n\nInput:\n - A " + type + ".\nVoid return.\n\n"; -} - -} // namespace command +namespace dynamicgraph +{ + namespace command + { + + template <class E, typename T> + struct CommandVoid1 : public Command + { + typedef boost::function<void(const T&)> function_t; + typedef boost::function<void(E*, const T&)> memberFunction_t; + typedef void (E::*memberFunction_ptr_t)(const T&); + + CommandVoid1(E& entity, function_t function, const std::string& docString) + : Command(entity, boost::assign::list_of(ValueHelper<T>::TypeID), + docString), fptr(function) {} + + protected: + virtual Value doExecute() + { + assert(getParameterValues().size() == 1); + T val = getParameterValues()[0].value(); + fptr(val); + return Value(); // void + } + + private: + function_t fptr; + }; + + template <class E, typename T> + CommandVoid1<E, T>* makeCommandVoid1 + (E& entity, boost::function<void(const T&)> function, + // typename CommandVoid1<E,T>::function_t function , + const std::string& docString) + { + return new CommandVoid1<E, T>(entity, function, docString); + } + + template <class E, typename T> + CommandVoid1<E, T>* makeCommandVoid1 + (E& entity, + // The following syntaxt don't compile when not specializing the template + // arg... why ??? + // typename CommandVoid1<E,T>::memberFunction_t function , + boost::function<void(E*, const T&)> function, + const std::string& docString) { + return new CommandVoid1<E, T>(entity, boost::bind(function, &entity, _1), + docString); + } + + template <class E, typename T> + CommandVoid1<E, T>* makeCommandVoid1 + (E& entity, void (E::*function)(const T&), const std::string& docString) + { + return new CommandVoid1<E, T>(entity, boost::bind(function, &entity, _1) + , docString); + return NULL; + } + + inline std::string docCommandVoid1 + (const std::string& doc, const std::string& type) + { + return std::string("\n") + doc + "\n\nInput:\n - A " + type + + ".\nVoid return.\n\n"; + } + + } // namespace command } // namespace dynamicgraph /* --- FUNCTION 2 ARGS ------------------------------------------------------ */ -namespace dynamicgraph { -namespace command { - -template <class E, typename T1, typename T2> -struct CommandVoid2 : public Command { - typedef boost::function<void(const T1&, const T2&)> function_t; - typedef boost::function<void(E*, const T1&, const T2&)> memberFunction_t; - typedef void (E::*memberFunction_ptr_t)(const T1&, const T2&); - - CommandVoid2(E& entity, function_t function, const std::string& docString) - : Command(entity, boost::assign::list_of(ValueHelper<T1>::TypeID)(ValueHelper<T2>::TypeID), docString), - fptr(function) {} - - protected: - virtual Value doExecute() { - assert(getParameterValues().size() == 2); - T1 val1 = getParameterValues()[0].value(); - T2 val2 = getParameterValues()[1].value(); - fptr(val1, val2); - return Value(); // void - } - - private: - function_t fptr; -}; - -template <class E, typename T1, typename T2> -CommandVoid2<E, T1, T2>* makeCommandVoid2(E& entity, boost::function<void(const T1&, const T2&)> function, - const std::string& docString) { - return new CommandVoid2<E, T1, T2>(entity, function, docString); -} - -template <class E, typename T1, typename T2> -CommandVoid2<E, T1, T2>* makeCommandVoid2(E& entity, - // The following syntaxt don't compile when not specializing the template - // arg... why ??? - // typename CommandVoid2<E,T1,T2>::memberFunction_t function , - boost::function<void(E*, const T1&, const T2&)> function, - const std::string& docString) { - return new CommandVoid2<E, T1, T2>(entity, boost::bind(function, &entity, _1, _2), docString); -} - -template <class E, typename T1, typename T2> -CommandVoid2<E, T1, T2>* makeCommandVoid2(E& entity, void (E::*function)(const T1&, const T2&), - const std::string& docString) { - return new CommandVoid2<E, T1, T2>(entity, boost::bind(function, &entity, _1, _2), docString); - return NULL; -} - -inline std::string docCommandVoid2(const std::string& doc, const std::string& type1, const std::string& type2) { - return (std::string("\n") + doc + "\n\n" + "Input:\n - A " + type1 + ".\n" + "Input:\n - A " + type2 + ".\n" + - "Void return.\n\n"); -} - -} // namespace command +namespace dynamicgraph +{ + namespace command + { + + template <class E, typename T1, typename T2> + struct CommandVoid2 : public Command + { + typedef boost::function<void(const T1&, const T2&)> function_t; + typedef boost::function<void(E*, const T1&, const T2&)> memberFunction_t; + typedef void (E::*memberFunction_ptr_t)(const T1&, const T2&); + + CommandVoid2(E& entity, function_t function, const std::string& docString) + : Command(entity, boost::assign::list_of(ValueHelper<T1>::TypeID) + (ValueHelper<T2>::TypeID), docString), + fptr(function) {} + + protected: + virtual Value doExecute() + { + assert(getParameterValues().size() == 2); + T1 val1 = getParameterValues()[0].value(); + T2 val2 = getParameterValues()[1].value(); + fptr(val1, val2); + return Value(); // void + } + + private: + function_t fptr; + }; + + template <class E, typename T1, typename T2> + CommandVoid2<E, T1, T2>* + makeCommandVoid2(E& entity, + boost::function<void(const T1&, const T2&)> function, + const std::string& docString) + { + return new CommandVoid2<E, T1, T2>(entity, function, docString); + } + + template <class E, typename T1, typename T2> + CommandVoid2<E, T1, T2>* makeCommandVoid2 + (E& entity, + // The following syntaxt don't compile when not specializing the template + // arg... why ??? + // typename CommandVoid2<E,T1,T2>::memberFunction_t function , + boost::function<void(E*, const T1&, const T2&)> function, + const std::string& docString) + { + return new CommandVoid2<E, T1, T2> + (entity, boost::bind(function, &entity, _1, _2), docString); + } + + template <class E, typename T1, typename T2> + CommandVoid2<E, T1, T2>* makeCommandVoid2 + (E& entity, void (E::*function)(const T1&, const T2&), + const std::string& docString) + { + return new CommandVoid2<E, T1, T2> + (entity, boost::bind(function, &entity, _1, _2), docString); + return NULL; + } + + inline std::string docCommandVoid2 + (const std::string& doc, const std::string& type1, + const std::string& type2) + { + return (std::string("\n") + doc + "\n\n" + "Input:\n - A " + + type1 + ".\n" + "Input:\n - A " + type2 + ".\n" + + "Void return.\n\n"); + } + + } // namespace command } // namespace dynamicgraph /* --- FUNCTION 3 ARGS ------------------------------------------------------ */ -namespace dynamicgraph { -namespace command { - -template <class E, typename T1, typename T2, typename T3> -struct CommandVoid3 : public Command { - typedef boost::function<void(const T1&, const T2&, const T3&)> function_t; - typedef boost::function<void(E*, const T1&, const T2&, const T3&)> memberFunction_t; - typedef void (E::*memberFunction_ptr_t)(const T1&, const T2&, const T3); - - CommandVoid3(E& entity, function_t function, const std::string& docString) - : Command(entity, - boost::assign::list_of(ValueHelper<T1>::TypeID)(ValueHelper<T2>::TypeID)(ValueHelper<T3>::TypeID), - docString), - fptr(function) {} - - protected: - virtual Value doExecute() { - assert(getParameterValues().size() == 3); - T1 val1 = getParameterValues()[0].value(); - T2 val2 = getParameterValues()[1].value(); - T3 val3 = getParameterValues()[2].value(); - fptr(val1, val2, val3); - return Value(); // void - } - - private: - function_t fptr; -}; - -template <class E, typename T1, typename T2, typename T3> -CommandVoid3<E, T1, T2, T3>* makeCommandVoid3(E& entity, typename CommandVoid3<E, T1, T2, T3>::function_t function, - const std::string& docString) { - return new CommandVoid3<E, T1, T2, T3>(entity, function, docString); -} - -template <class E, typename T1, typename T2, typename T3> -CommandVoid3<E, T1, T2, T3>* makeCommandVoid3(E& entity, - // The following syntaxt don't compile when not specializing the template - // arg... why ??? - // typename CommandVoid3<E,T1,T2>::memberFunction_t function , - boost::function<void(E*, const T1&, const T2&, const T3&)> function, - const std::string& docString) { - return new CommandVoid3<E, T1, T2, T3>(entity, boost::bind(function, &entity, _1, _2, _3), docString); -} - -template <class E, typename T1, typename T2, typename T3> -CommandVoid3<E, T1, T2, T3>* makeCommandVoid3(E& entity, void (E::*function)(const T1&, const T2&, const T3&), - const std::string& docString) { - return new CommandVoid3<E, T1, T2, T3>(entity, boost::bind(function, &entity, _1, _2, _3), docString); - return NULL; -} - -inline std::string docCommandVoid3(const std::string& doc, const std::string& type1, const std::string& type2, - const std::string& type3) { - return (std::string("\n") + doc + "\n\n" + "Input:\n - A " + type1 + ".\n" + "Input:\n - A " + type2 + ".\n" + - "Input:\n - A " + type3 + ".\n" + "Void return.\n\n"); -} - -} // namespace command +namespace dynamicgraph +{ + namespace command + { + + template <class E, typename T1, typename T2, typename T3> + struct CommandVoid3 : public Command { + typedef boost::function<void(const T1&, const T2&, const T3&)> function_t; + typedef boost::function<void(E*, const T1&, const T2&, const T3&)> + memberFunction_t; + typedef void (E::*memberFunction_ptr_t)(const T1&, const T2&, const T3); + + CommandVoid3(E& entity, function_t function, const std::string& docString) + : Command(entity, + boost::assign::list_of(ValueHelper<T1>::TypeID) + (ValueHelper<T2>::TypeID)(ValueHelper<T3>::TypeID), + docString), + fptr(function) {} + + protected: + virtual Value doExecute() + { + assert(getParameterValues().size() == 3); + T1 val1 = getParameterValues()[0].value(); + T2 val2 = getParameterValues()[1].value(); + T3 val3 = getParameterValues()[2].value(); + fptr(val1, val2, val3); + return Value(); // void + } + + private: + function_t fptr; + }; + + template <class E, typename T1, typename T2, typename T3> + CommandVoid3<E, T1, T2, T3>* makeCommandVoid3 + (E& entity, typename CommandVoid3<E, T1, T2, T3>::function_t function, + const std::string& docString) + { + return new CommandVoid3<E, T1, T2, T3>(entity, function, docString); + } + + template <class E, typename T1, typename T2, typename T3> + CommandVoid3<E, T1, T2, T3>* + makeCommandVoid3 + (E& entity, + // The following syntaxt don't compile when not specializing the template + // arg... why ??? + // typename CommandVoid3<E,T1,T2>::memberFunction_t function , + boost::function<void(E*, const T1&, const T2&, const T3&)> function, + const std::string& docString) + { + return new CommandVoid3<E, T1, T2, T3> + (entity, boost::bind(function, &entity, _1, _2, _3), docString); + } + + template <class E, typename T1, typename T2, typename T3> + CommandVoid3<E, T1, T2, T3>* + makeCommandVoid3 + (E& entity, + void (E::*function)(const T1&, const T2&, const T3&), + const std::string& docString) { + return new CommandVoid3<E, T1, T2, T3> + (entity, boost::bind(function, &entity, _1, _2, _3), docString); + return NULL; + } + + inline std::string + docCommandVoid3 + (const std::string& doc, const std::string& type1, const std::string& type2, + const std::string& type3) + { + return (std::string("\n") + doc + "\n\n" + "Input:\n - A " + + type1 + ".\n" + + "Input:\n - A " + type2 + ".\n" + + "Input:\n - A " + type3 + ".\n" + "Void return.\n\n"); + } + + } // namespace command } // namespace dynamicgraph /* --- FUNCTION 4 ARGS ------------------------------------------------------ */ -namespace dynamicgraph { -namespace command { - -template <class E, typename T1, typename T2, typename T3, typename T4> -struct CommandVoid4 : public Command { - typedef boost::function<void(const T1&, const T2&, const T3&, const T4&)> function_t; - typedef boost::function<void(E*, const T1&, const T2&, const T3&, const T4&)> memberFunction_t; - typedef void (E::*memberFunction_ptr_t)(const T1&, const T2&, const T3&, const T4&); - - CommandVoid4(E& entity, function_t function, const std::string& docString) - : Command(entity, - boost::assign::list_of(ValueHelper<T1>::TypeID)(ValueHelper<T2>::TypeID)(ValueHelper<T3>::TypeID)( - ValueHelper<T4>::TypeID), - docString), - fptr(function) {} - - protected: - virtual Value doExecute() { - assert(getParameterValues().size() == 4); - T1 val1 = getParameterValues()[0].value(); - T2 val2 = getParameterValues()[1].value(); - T3 val3 = getParameterValues()[2].value(); - T4 val4 = getParameterValues()[3].value(); - fptr(val1, val2, val3, val4); - return Value(); // void - } - - private: - function_t fptr; -}; - -template <class E, typename T1, typename T2, typename T3, typename T4> -CommandVoid4<E, T1, T2, T3, T4>* makeCommandVoid4(E& entity, - typename CommandVoid4<E, T1, T2, T3, T4>::function_t function, - const std::string& docString) { - return new CommandVoid4<E, T1, T2, T3, T4>(entity, function, docString); -} - -template <class E, typename T1, typename T2, typename T3, typename T4> -CommandVoid4<E, T1, T2, T3, T4>* makeCommandVoid4( - E& entity, boost::function<void(E*, const T1&, const T2&, const T3&, const T4&)> function, - const std::string& docString) { - return new CommandVoid4<E, T1, T2, T3, T4>(entity, boost::bind(function, &entity, _1, _2, _3, _4), docString); -} - -template <class E, typename T1, typename T2, typename T3, typename T4> -CommandVoid4<E, T1, T2, T3, T4>* makeCommandVoid4(E& entity, - void (E::*function)(const T1&, const T2&, const T3&, const T4&), - const std::string& docString) { - return new CommandVoid4<E, T1, T2, T3, T4>(entity, boost::bind(function, &entity, _1, _2, _3, _4), docString); - return NULL; -} - -inline std::string docCommandVoid4(const std::string& doc, const std::string& type1, const std::string& type2, - const std::string& type3, const std::string& type4) { - return (std::string("\n") + doc + "\n\n" + "Input:\n - A " + type1 + ".\n" + "Input:\n - A " + type2 + ".\n" + - "Input:\n - A " + type3 + ".\n" + "Input:\n - A " + type4 + ".\n" + "Void return.\n\n"); -} - -} // namespace command +namespace dynamicgraph +{ + namespace command + { + + template <class E, typename T1, typename T2, typename T3, typename T4> + struct CommandVoid4 : public Command { + typedef boost::function + <void(const T1&, const T2&, const T3&, const T4&)> function_t; + typedef boost::function + <void(E*, const T1&, const T2&, const T3&, const T4&)> memberFunction_t; + typedef void (E::*memberFunction_ptr_t) + (const T1&, const T2&, const T3&, const T4&); + + CommandVoid4(E& entity, function_t function, const std::string& docString) + : Command(entity, + boost::assign::list_of + (ValueHelper<T1>::TypeID) + (ValueHelper<T2>::TypeID) + (ValueHelper<T3>::TypeID) + (ValueHelper<T4>::TypeID), + docString), + fptr(function) {} + + protected: + virtual Value doExecute() { + assert(getParameterValues().size() == 4); + T1 val1 = getParameterValues()[0].value(); + T2 val2 = getParameterValues()[1].value(); + T3 val3 = getParameterValues()[2].value(); + T4 val4 = getParameterValues()[3].value(); + fptr(val1, val2, val3, val4); + return Value(); // void + } + + private: + function_t fptr; + }; + + template <class E, typename T1, typename T2, typename T3, typename T4> + CommandVoid4<E, T1, T2, T3, T4>* makeCommandVoid4 + (E& entity, + typename CommandVoid4<E, T1, T2, T3, T4>::function_t function, + const std::string& docString) + { + return new CommandVoid4<E, T1, T2, T3, T4>(entity, function, docString); + } + + template <class E, typename T1, typename T2, typename T3, typename T4> + CommandVoid4<E, T1, T2, T3, T4>* makeCommandVoid4 + (E& entity, + boost::function<void(E*, const T1&, const T2&, const T3&, const T4&)> + function, + const std::string& docString) + { + return new CommandVoid4<E, T1, T2, T3, T4> + (entity, boost::bind(function, &entity, _1, _2, _3, _4), docString); + } + + template <class E, typename T1, typename T2, typename T3, typename T4> + CommandVoid4<E, T1, T2, T3, T4>* + makeCommandVoid4 + (E& entity, + void (E::*function)(const T1&, const T2&, const T3&, const T4&), + const std::string& docString) { + return new CommandVoid4<E, T1, T2, T3, T4> + (entity, boost::bind(function, &entity, _1, _2, _3, _4), docString); + return NULL; + } + + inline std::string docCommandVoid4 + (const std::string& doc, + const std::string& type1, const std::string& type2, + const std::string& type3, const std::string& type4) + { + return (std::string("\n") + doc + "\n\n" + "Input:\n - A " + + type1 + ".\n" + "Input:\n - A " + type2 + ".\n" + + "Input:\n - A " + type3 + ".\n" + "Input:\n - A " + type4 + ".\n" + + "Void return.\n\n"); + } + + } // namespace command } // namespace dynamicgraph /* --- FUNCTION VERBOSE ----------------------------------------------------- */ /* This bind a function void f( ostream& ) that display some results into * a string f( void ) that return some string results. */ -namespace dynamicgraph { -namespace command { - -template <class E> -struct CommandVerbose : public Command { - typedef boost::function<void(std::ostream&)> function_t; - typedef boost::function<void(E*, std::ostream&)> memberFunction_t; - typedef void (E::*memberFunctionConst_ptr_t)(std::ostream&) const; - typedef void (E::*memberFunction_ptr_t)(std::ostream&); - - CommandVerbose(E& entity, function_t function, const std::string& docString) - : Command(entity, EMPTY_ARG, docString), fptr(function) {} - - protected: - virtual Value doExecute() { - assert(getParameterValues().size() == 0); - std::ostringstream oss; - fptr(oss); - return Value(oss.str()); // return string - } - - private: - function_t fptr; -}; - -template <class E> -CommandVerbose<E>* makeCommandVerbose(E& entity, typename CommandVerbose<E>::function_t function, - const std::string& docString) { - return new CommandVerbose<E>(entity, function, docString); - return NULL; -} - -template <class E> -CommandVerbose<E>* makeCommandVerbose(E& entity, - // void (E::*function) (std::ostream&) const, - typename CommandVerbose<E>::memberFunctionConst_ptr_t function, - const std::string& docString) { - return new CommandVerbose<E>(entity, boost::bind(function, &entity, _1), docString); - return NULL; -} - -template <class E> -CommandVerbose<E>* makeCommandVerbose(E& entity, typename CommandVerbose<E>::memberFunction_ptr_t function, - const std::string& docString) { - return new CommandVerbose<E>(entity, boost::bind(function, &entity, _1), docString); - return NULL; -} - -inline std::string docCommandVerbose(const std::string& doc) { - return std::string("\n") + doc + "\n\nNo input.\n Return a string.\n\n"; -} - -} // namespace command +namespace dynamicgraph +{ + namespace command + { + template <class E> + struct CommandVerbose : public Command + { + typedef boost::function<void(std::ostream&)> function_t; + typedef boost::function<void(E*, std::ostream&)> memberFunction_t; + typedef void (E::*memberFunctionConst_ptr_t)(std::ostream&) const; + typedef void (E::*memberFunction_ptr_t)(std::ostream&); + + CommandVerbose(E& entity, function_t function, + const std::string& docString) + : Command(entity, EMPTY_ARG, docString), fptr(function) {} + + protected: + virtual Value doExecute() + { + assert(getParameterValues().size() == 0); + std::ostringstream oss; + fptr(oss); + return Value(oss.str()); // return string + } + + private: + function_t fptr; + }; + + template <class E> + CommandVerbose<E>* + makeCommandVerbose + (E& entity, typename CommandVerbose<E>::function_t function, + const std::string& docString) + { + return new CommandVerbose<E>(entity, function, docString); + return NULL; + } + + template <class E> + CommandVerbose<E>* + makeCommandVerbose + (E& entity, + // void (E::*function) (std::ostream&) const, + typename CommandVerbose<E>::memberFunctionConst_ptr_t function, + const std::string& docString) + { + return new CommandVerbose<E> + (entity, boost::bind(function, &entity, _1), docString); + return NULL; + } + + template <class E> + CommandVerbose<E>* + makeCommandVerbose + (E& entity, typename CommandVerbose<E>::memberFunction_ptr_t function, + const std::string& docString) + { + return new CommandVerbose<E> + (entity, boost::bind(function, &entity, _1), docString); + return NULL; + } + + inline std::string docCommandVerbose(const std::string& doc) + { + return std::string("\n") + doc + "\n\nNo input.\n Return a string.\n\n"; + } + + } // namespace command } // namespace dynamicgraph #endif // __dg_command_bind_h__ diff --git a/include/dynamic-graph/command-direct-getter.h b/include/dynamic-graph/command-direct-getter.h index bf88612..d6f826e 100644 --- a/include/dynamic-graph/command-direct-getter.h +++ b/include/dynamic-graph/command-direct-getter.h @@ -19,36 +19,45 @@ #include <boost/assign/list_of.hpp> /* --- GETTER --------------------------------------------------------- */ -namespace dynamicgraph { -namespace command { - -template <class E, typename T> -class DirectGetter : public Command { - public: - /// Pointer to method that sets parameter of type T - typedef T (E::*GetterMethod)() const; - - /// Constructor - DirectGetter(E& entity, T* ptr, const std::string& docString) - : Command(entity, std::vector<Value::Type>(), docString), T_ptr(ptr) {} - - protected: - virtual Value doExecute() { return Value(*T_ptr); } - - private: - T* T_ptr; -}; - -template <class E, typename T> -DirectGetter<E, T>* makeDirectGetter(E& entity, T* ptr, const std::string& docString) { - return new DirectGetter<E, T>(entity, ptr, docString); -} - -inline std::string docDirectGetter(const std::string& name, const std::string& type) { - return std::string("\nGet the ") + name + ".\n\nNo input.\nReturn an " + type + ".\n\n"; -} - -} // namespace command +namespace dynamicgraph +{ + namespace command + { + + template <class E, typename T> + class DirectGetter : public Command + { + public: + /// Pointer to method that sets parameter of type T + typedef T (E::*GetterMethod)() const; + + /// Constructor + DirectGetter(E& entity, T* ptr, const std::string& docString) + : Command(entity, std::vector<Value::Type>(), docString), T_ptr(ptr) + {} + + protected: + virtual Value doExecute() { return Value(*T_ptr); } + + private: + T* T_ptr; + }; + + template <class E, typename T> + DirectGetter<E, T>* makeDirectGetter + (E& entity, T* ptr, const std::string& docString) + { + return new DirectGetter<E, T>(entity, ptr, docString); + } + + inline std::string docDirectGetter + (const std::string& name, const std::string& type) + { + return std::string("\nGet the ") + name + + ".\n\nNo input.\nReturn an " + type + ".\n\n"; + } + + } // namespace command } // namespace dynamicgraph #endif // __dg_command_direct_getter_h__ diff --git a/include/dynamic-graph/command-direct-setter.h b/include/dynamic-graph/command-direct-setter.h index 3c9823d..2f04256 100644 --- a/include/dynamic-graph/command-direct-setter.h +++ b/include/dynamic-graph/command-direct-setter.h @@ -19,37 +19,47 @@ #include <boost/assign/list_of.hpp> /* --- SETTER --------------------------------------------------------- */ -namespace dynamicgraph { -namespace command { - -template <class E, typename T> -class DirectSetter : public Command { - public: - DirectSetter(E& entity, T* ptr, const std::string& docString) - : Command(entity, boost::assign::list_of(ValueHelper<T>::TypeID), docString), T_ptr(ptr) {} - - protected: - virtual Value doExecute() { - const std::vector<Value>& values = getParameterValues(); - T val = values[0].value(); - (*T_ptr) = val; - return Value(); // void - } - - private: - T* T_ptr; -}; - -template <class E, typename T> -DirectSetter<E, T>* makeDirectSetter(E& entity, T* ptr, const std::string& docString) { - return new DirectSetter<E, T>(entity, ptr, docString); -} - -inline std::string docDirectSetter(const std::string& name, const std::string& type) { - return std::string("\nSet the ") + name + ".\n\nInput:\n - a " + type + ".\nVoid return.\n\n"; -} - -} // namespace command +namespace dynamicgraph +{ + namespace command + { + + template <class E, typename T> + class DirectSetter : public Command + { + public: + DirectSetter(E& entity, T* ptr, const std::string& docString) + : Command(entity, boost::assign::list_of(ValueHelper<T>::TypeID), + docString), T_ptr(ptr) {} + + protected: + virtual Value doExecute() + { + const std::vector<Value>& values = getParameterValues(); + T val = values[0].value(); + (*T_ptr) = val; + return Value(); // void + } + + private: + T* T_ptr; + }; + + template <class E, typename T> + DirectSetter<E, T>* makeDirectSetter + (E& entity, T* ptr, const std::string& docString) + { + return new DirectSetter<E, T>(entity, ptr, docString); + } + + inline std::string docDirectSetter + (const std::string& name, const std::string& type) + { + return std::string("\nSet the ") + name + ".\n\nInput:\n - a " + type + + ".\nVoid return.\n\n"; + } + + } // namespace command } // namespace dynamicgraph #endif // __dg_command_direct_setter_h__ diff --git a/include/dynamic-graph/command-getter.t.cpp b/include/dynamic-graph/command-getter.t.cpp index 64f9400..a3e0241 100644 --- a/include/dynamic-graph/command-getter.t.cpp +++ b/include/dynamic-graph/command-getter.t.cpp @@ -9,21 +9,28 @@ #include <sstream> -namespace dynamicgraph { -class Entity; -namespace command { - -template <class E, typename T> -Getter<E, T>::Getter(E& entity, GetterMethod getterMethod, const std::string& docstring) - : Command(entity, std::vector<Value::Type>(), docstring), getterMethod_(getterMethod) {} - -template <class E, typename T> -Value Getter<E, T>::doExecute() { - E& entity = static_cast<E&>(owner()); - T value = (entity.*getterMethod_)(); - return Value(value); -} -} // namespace command +namespace dynamicgraph +{ + class Entity; + namespace command + { + + template <class E, typename T> + Getter<E, T>::Getter + (E& entity, GetterMethod getterMethod, + const std::string& docstring) + : Command(entity, std::vector<Value::Type>(), docstring), + getterMethod_(getterMethod) + {} + + template <class E, typename T> + Value Getter<E, T>::doExecute() + { + E& entity = static_cast<E&>(owner()); + T value = (entity.*getterMethod_)(); + return Value(value); + } + } // namespace command } // namespace dynamicgraph #endif // DYNAMIC_GRAPH_COMMAND_GETTER_T_CPP diff --git a/include/dynamic-graph/command-setter.t.cpp b/include/dynamic-graph/command-setter.t.cpp index c2dba66..61b3d7b 100644 --- a/include/dynamic-graph/command-setter.t.cpp +++ b/include/dynamic-graph/command-setter.t.cpp @@ -11,267 +11,313 @@ #include <boost/assign/list_of.hpp> #include "dynamic-graph/linear-algebra.h" -namespace dynamicgraph { -class Entity; -namespace command { - -// -// Template specialization: bool -// -template <class E> -class Setter<E, bool> : public Command { - public: - /// Pointer to method that sets parameter of type bool - typedef void (E::*SetterMethod)(const bool&); - /// Constructor - Setter(E& entity, SetterMethod setterMethod, const std::string& docString); - - protected: - virtual Value doExecute(); - - private: - SetterMethod setterMethod_; -}; // Class Setter - -template <class E> -Setter<E, bool>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString) - : Command(entity, boost::assign::list_of(Value::BOOL), docString), setterMethod_(setterMethod) {} - -template <class E> -Value Setter<E, bool>::doExecute() { - const std::vector<Value>& values = getParameterValues(); - // Get parameter - bool value = values[0].value(); - E& entity = static_cast<E&>(owner()); - (entity.*setterMethod_)(value); - return Value(); -} - -// -// Template specialization: unsigned -// -template <class E> -class Setter<E, unsigned> : public Command { - public: - /// Pointer to method that sets parameter of type unsigned - typedef void (E::*SetterMethod)(const unsigned&); - /// Constructor - Setter(E& entity, SetterMethod setterMethod, const std::string& docString); - - protected: - virtual Value doExecute(); - - private: - SetterMethod setterMethod_; -}; // Class Setter - -template <class E> -Setter<E, unsigned>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString) - : Command(entity, boost::assign::list_of(Value::UNSIGNED), docString), setterMethod_(setterMethod) {} - -template <class E> -Value Setter<E, unsigned>::doExecute() { - const std::vector<Value>& values = getParameterValues(); - // Get parameter - unsigned value = values[0].value(); - E& entity = static_cast<E&>(owner()); - (entity.*setterMethod_)(value); - return Value(); -} - -// -// Template specialization: int -// -template <class E> -class Setter<E, int> : public Command { - public: - /// Pointer to method that sets parameter of type int - typedef void (E::*SetterMethod)(const int&); - /// Constructor - Setter(E& entity, SetterMethod setterMethod, const std::string& docString); - - protected: - virtual Value doExecute(); - - private: - SetterMethod setterMethod_; -}; // Class Setter - -template <class E> -Setter<E, int>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString) - : Command(entity, boost::assign::list_of(Value::INT), docString), setterMethod_(setterMethod) {} - -template <class E> -Value Setter<E, int>::doExecute() { - const std::vector<Value>& values = getParameterValues(); - // Get parameter - int value = values[0].value(); - E& entity = static_cast<E&>(owner()); - (entity.*setterMethod_)(value); - return Value(); -} - -// -// Template specialization: float -// -template <class E> -class Setter<E, float> : public Command { - public: - /// Pointer to method that sets parameter of type float - typedef void (E::*SetterMethod)(const float&); - /// Constructor - Setter(E& entity, SetterMethod setterMethod, const std::string& docString); - - protected: - virtual Value doExecute(); - - private: - SetterMethod setterMethod_; -}; // Class Setter - -template <class E> -Setter<E, float>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString) - : Command(entity, boost::assign::list_of(Value::FLOAT), docString), setterMethod_(setterMethod) {} - -template <class E> -Value Setter<E, float>::doExecute() { - const std::vector<Value>& values = getParameterValues(); - // Get parameter - float value = values[0].value(); - E& entity = static_cast<E&>(owner()); - (entity.*setterMethod_)(value); - return Value(); -} - -// -// Template specialization: double -// -template <class E> -class Setter<E, double> : public Command { - public: - /// Pointer to method that sets parameter of type double - typedef void (E::*SetterMethod)(const double&); - /// Constructor - Setter(E& entity, SetterMethod setterMethod, const std::string& docString); - - protected: - virtual Value doExecute(); - - private: - SetterMethod setterMethod_; -}; // Class Setter - -template <class E> -Setter<E, double>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString) - : Command(entity, boost::assign::list_of(Value::DOUBLE), docString), setterMethod_(setterMethod) {} - -template <class E> -Value Setter<E, double>::doExecute() { - const std::vector<Value>& values = getParameterValues(); - // Get parameter - double value = values[0].value(); - E& entity = static_cast<E&>(owner()); - (entity.*setterMethod_)(value); - return Value(); -} - -// -// Template specialization: std::string -// -template <class E> -class Setter<E, std::string> : public Command { - public: - /// Pointer to method that sets parameter of type std::string - typedef void (E::*SetterMethod)(const std::string&); - /// Constructor - Setter(E& entity, SetterMethod setterMethod, const std::string& docString); - - protected: - virtual Value doExecute(); - - private: - SetterMethod setterMethod_; -}; // Class Setter - -template <class E> -Setter<E, std::string>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString) - : Command(entity, boost::assign::list_of(Value::STRING), docString), setterMethod_(setterMethod) {} - -template <class E> -Value Setter<E, std::string>::doExecute() { - const std::vector<Value>& values = getParameterValues(); - // Get parameter - std::string value = values[0].value(); - E& entity = static_cast<E&>(owner()); - (entity.*setterMethod_)(value); - return Value(); -} - -// -// Template specialization: Vector -// -template <class E> -class Setter<E, Vector> : public Command { - public: - /// Pointer to method that sets parameter of type Vector - typedef void (E::*SetterMethod)(const Vector&); - /// Constructor - Setter(E& entity, SetterMethod setterMethod, const std::string& docString); - - protected: - virtual Value doExecute(); - - private: - SetterMethod setterMethod_; -}; // Class Setter - -template <class E> -Setter<E, Vector>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString) - : Command(entity, boost::assign::list_of(Value::VECTOR), docString), setterMethod_(setterMethod) {} - -template <class E> -Value Setter<E, Vector>::doExecute() { - const std::vector<Value>& values = getParameterValues(); - // Get parameter - Vector value = values[0].value(); - E& entity = static_cast<E&>(owner()); - (entity.*setterMethod_)(value); - return Value(); -} - -// -// Template specialization: Matrix -// -template <class E> -class Setter<E, Matrix> : public Command { - public: - /// Pointer to method that sets parameter of type Matrix - typedef void (E::*SetterMethod)(const Matrix&); - /// Constructor - Setter(E& entity, SetterMethod setterMethod, const std::string& docString); - - protected: - virtual Value doExecute(); - - private: - SetterMethod setterMethod_; -}; // Class Setter - -template <class E> -Setter<E, Matrix>::Setter(E& entity, SetterMethod setterMethod, const std::string& docString) - : Command(entity, boost::assign::list_of(Value::MATRIX), docString), setterMethod_(setterMethod) {} - -template <class E> -Value Setter<E, Matrix>::doExecute() { - const std::vector<Value>& values = getParameterValues(); - // Get parameter - Matrix value = values[0].value(); - E& entity = static_cast<E&>(owner()); - (entity.*setterMethod_)(value); - return Value(); -} - -} // namespace command +namespace dynamicgraph +{ + class Entity; + namespace command + { + + // + // Template specialization: bool + // + template <class E> + class Setter<E, bool> : public Command + { + public: + /// Pointer to method that sets parameter of type bool + typedef void (E::*SetterMethod)(const bool&); + /// Constructor + Setter(E& entity, SetterMethod setterMethod, + const std::string& docString); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, bool>::Setter + (E& entity, SetterMethod setterMethod, + const std::string& docString) + : Command(entity, boost::assign::list_of(Value::BOOL), docString), + setterMethod_(setterMethod) + {} + + template <class E> + Value Setter<E, bool>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + bool value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: unsigned + // + template <class E> + class Setter<E, unsigned> : public Command + { + public: + /// Pointer to method that sets parameter of type unsigned + typedef void (E::*SetterMethod)(const unsigned&); + /// Constructor + Setter(E& entity, SetterMethod setterMethod, + const std::string& docString); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, unsigned>::Setter + (E& entity, SetterMethod setterMethod, + const std::string& docString) + : + Command(entity, boost::assign::list_of(Value::UNSIGNED), docString), + setterMethod_(setterMethod) {} + + template <class E> + Value Setter<E, unsigned>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + unsigned value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: int + // + template <class E> + class Setter<E, int> : public Command + { + public: + /// Pointer to method that sets parameter of type int + typedef void (E::*SetterMethod)(const int&); + /// Constructor + Setter(E& entity, SetterMethod setterMethod, + const std::string& docString); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, int>::Setter(E& entity, SetterMethod setterMethod, + const std::string& docString) + : Command(entity, boost::assign::list_of(Value::INT), docString), + setterMethod_(setterMethod) {} + + template <class E> + Value Setter<E, int>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + int value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: float + // + template <class E> + class Setter<E, float> : public Command + { + public: + /// Pointer to method that sets parameter of type float + typedef void (E::*SetterMethod)(const float&); + /// Constructor + Setter(E& entity, SetterMethod setterMethod, + const std::string& docString); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, float>::Setter(E& entity, + SetterMethod setterMethod, + const std::string& docString) + : Command(entity, boost::assign::list_of(Value::FLOAT), docString), + setterMethod_(setterMethod) {} + + template <class E> + Value Setter<E, float>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + float value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: double + // + template <class E> + class Setter<E, double> : public Command + { + public: + /// Pointer to method that sets parameter of type double + typedef void (E::*SetterMethod)(const double&); + /// Constructor + Setter(E& entity, SetterMethod setterMethod, + const std::string& docString); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, double>::Setter(E& entity, SetterMethod setterMethod, + const std::string& docString) + : Command(entity, boost::assign::list_of(Value::DOUBLE), docString), + setterMethod_(setterMethod) {} + + template <class E> + Value Setter<E, double>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + double value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: std::string + // + template <class E> + class Setter<E, std::string> : public Command + { + public: + /// Pointer to method that sets parameter of type std::string + typedef void (E::*SetterMethod)(const std::string&); + /// Constructor + Setter(E& entity, SetterMethod setterMethod, + const std::string& docString); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, std::string>::Setter(E& entity, SetterMethod setterMethod, + const std::string& docString) + : Command(entity, boost::assign::list_of(Value::STRING), docString), + setterMethod_(setterMethod) {} + + template <class E> + Value Setter<E, std::string>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + std::string value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: Vector + // + template <class E> + class Setter<E, Vector> : public Command + { + public: + /// Pointer to method that sets parameter of type Vector + typedef void (E::*SetterMethod)(const Vector&); + /// Constructor + Setter(E& entity, SetterMethod setterMethod, + const std::string& docString); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, Vector>::Setter(E& entity, SetterMethod setterMethod, + const std::string& docString) + : Command(entity, boost::assign::list_of(Value::VECTOR), docString), + setterMethod_(setterMethod) {} + + template <class E> + Value Setter<E, Vector>::doExecute() + { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + Vector value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + // + // Template specialization: Matrix + // + template <class E> + class Setter<E, Matrix> : public Command + { + public: + /// Pointer to method that sets parameter of type Matrix + typedef void (E::*SetterMethod)(const Matrix&); + /// Constructor + Setter(E& entity, SetterMethod setterMethod, + const std::string& docString); + + protected: + virtual Value doExecute(); + + private: + SetterMethod setterMethod_; + }; // Class Setter + + template <class E> + Setter<E, Matrix>::Setter(E& entity, SetterMethod setterMethod, + const std::string& docString) + : Command(entity, boost::assign::list_of(Value::MATRIX), docString), + setterMethod_(setterMethod) {} + + template <class E> + Value Setter<E, Matrix>::doExecute() { + const std::vector<Value>& values = getParameterValues(); + // Get parameter + Matrix value = values[0].value(); + E& entity = static_cast<E&>(owner()); + (entity.*setterMethod_)(value); + return Value(); + } + + } // namespace command } // namespace dynamicgraph #endif // DYNAMIC_GRAPH_COMMAND_SETTER_T_CPP diff --git a/include/dynamic-graph/command.h b/include/dynamic-graph/command.h index 6360cf9..232405d 100644 --- a/include/dynamic-graph/command.h +++ b/include/dynamic-graph/command.h @@ -11,59 +11,64 @@ #include "dynamic-graph/value.h" #include "dynamic-graph/dynamic-graph-api.h" -namespace dynamicgraph { -class Entity; -namespace command { -/// Abstract class for entity commands -/// -/// This class provide a mean to control entities from external python script. -/// -/// A command -/// \li is owned by an entity, -/// \li takes parameters of type Value, -/// \li return an instance of Value when calling Command::execute() -/// -/// At construction, the prototype of the command is defined by providing -/// a vector of Value::Type. -/// -/// Parameters are set by calling Command::setParameterValues with a -/// vector of Values the types of which should fit the vector specified -/// at construction. -class DYNAMIC_GRAPH_DLLAPI Command { - public: - virtual ~Command(); - /// Store the owner entity and a vector of value types - /// \param entity reference to Entity owning this command. - /// \param valueTypes vector specifying the number and types of parameters - /// \param docstring documentation of the command - Command(Entity& entity, const std::vector<Value::Type>& valueTypes, const std::string& docstring); - /// Return the value type of all parameters - const std::vector<Value::Type>& valueTypes() const; - /// Set parameter values - void setParameterValues(const std::vector<Value>& values); - /// Get parameter values - const std::vector<Value>& getParameterValues() const; - /// Execute the command after checking parameters - Value execute(); - /// Get a reference to the Entity owning this command - Entity& owner(); - /// Get documentation string - std::string getDocstring() const; +namespace dynamicgraph +{ + class Entity; + namespace command + { + /// Abstract class for entity commands + /// + /// This class provide a mean to control entities from external + /// python script. + /// + /// A command + /// \li is owned by an entity, + /// \li takes parameters of type Value, + /// \li return an instance of Value when calling Command::execute() + /// + /// At construction, the prototype of the command is defined by providing + /// a vector of Value::Type. + /// + /// Parameters are set by calling Command::setParameterValues with a + /// vector of Values the types of which should fit the vector specified + /// at construction. + class DYNAMIC_GRAPH_DLLAPI Command + { + public: + virtual ~Command(); + /// Store the owner entity and a vector of value types + /// \param entity reference to Entity owning this command. + /// \param valueTypes vector specifying the number and types of parameters + /// \param docstring documentation of the command + Command(Entity& entity, const std::vector<Value::Type>& valueTypes, + const std::string& docstring); + /// Return the value type of all parameters + const std::vector<Value::Type>& valueTypes() const; + /// Set parameter values + void setParameterValues(const std::vector<Value>& values); + /// Get parameter values + const std::vector<Value>& getParameterValues() const; + /// Execute the command after checking parameters + Value execute(); + /// Get a reference to the Entity owning this command + Entity& owner(); + /// Get documentation string + std::string getDocstring() const; - protected: - /// Specific action performed by the command - virtual Value doExecute() = 0; + protected: + /// Specific action performed by the command + virtual Value doExecute() = 0; - private: - Entity& owner_; - std::vector<Value::Type> valueTypeVector_; - std::vector<Value> valueVector_; - std::string docstring_; + private: + Entity& owner_; + std::vector<Value::Type> valueTypeVector_; + std::vector<Value> valueVector_; + std::string docstring_; - public: - static const std::vector<Value::Type> EMPTY_ARG; -}; -} // namespace command + public: + static const std::vector<Value::Type> EMPTY_ARG; + }; + } // namespace command } // namespace dynamicgraph #endif // DYNAMIC_GRAPH_COMMAND_H diff --git a/include/dynamic-graph/debug.h b/include/dynamic-graph/debug.h index 1a6545d..6b66d05 100644 --- a/include/dynamic-graph/debug.h +++ b/include/dynamic-graph/debug.h @@ -30,72 +30,81 @@ outputbuffer << tmpbuffer.str() << charbuffer << std::endl; \ } while (0) -namespace dynamicgraph { -/// \ingroup debug -/// -/// \brief Logging class. -/// -/// This class should never be used directly, please use the -/// debugging macro instead. -class DYNAMIC_GRAPH_DLLAPI DebugTrace { - public: - static const int SIZE = 512; - - std::stringstream tmpbuffer; - std::ostream& outputbuffer; - char charbuffer[SIZE + 1]; - int traceLevel; - int traceLevelTemplate; - - DebugTrace(std::ostream& os) : outputbuffer(os) {} - - inline void trace(const int level, const char* format, ...) { - if (level <= traceLevel) DG_COMMON_TRACES; - tmpbuffer.str(""); - } - - inline void trace(const char* format, ...) { - DG_COMMON_TRACES; - tmpbuffer.str(""); - } - - inline void trace(const int level = -1) { - if (level <= traceLevel) { - outputbuffer << tmpbuffer.str(); +namespace dynamicgraph +{ + /// \ingroup debug + /// + /// \brief Logging class. + /// + /// This class should never be used directly, please use the + /// debugging macro instead. + class DYNAMIC_GRAPH_DLLAPI DebugTrace + { + public: + static const int SIZE = 512; + + std::stringstream tmpbuffer; + std::ostream& outputbuffer; + char charbuffer[SIZE + 1]; + int traceLevel; + int traceLevelTemplate; + + DebugTrace(std::ostream& os) : outputbuffer(os) {} + + inline void trace(const int level, const char* format, ...) + { + if (level <= traceLevel) DG_COMMON_TRACES; tmpbuffer.str(""); } - } - - inline void traceTemplate(const int level, const char* format, ...) { - if (level <= traceLevelTemplate) DG_COMMON_TRACES; - tmpbuffer.str(""); - } - - inline void traceTemplate(const char* format, ...) { - DG_COMMON_TRACES; - tmpbuffer.str(""); - } - - inline DebugTrace& pre(const std::ostream&) { return *this; } + + inline void trace(const char* format, ...) + { + DG_COMMON_TRACES; + tmpbuffer.str(""); + } + + inline void trace(const int level = -1) + { + if (level <= traceLevel) { + outputbuffer << tmpbuffer.str(); + tmpbuffer.str(""); + } + } - inline DebugTrace& pre(const std::ostream&, int level) { - traceLevel = level; - return *this; - } + inline void traceTemplate(const int level, const char* format, ...) + { + if (level <= traceLevelTemplate) DG_COMMON_TRACES; + tmpbuffer.str(""); + } - static const char* DEBUG_FILENAME_DEFAULT; - static void openFile(const char* filename = DEBUG_FILENAME_DEFAULT); - static void closeFile(const char* filename = DEBUG_FILENAME_DEFAULT); -}; + inline void traceTemplate(const char* format, ...) + { + DG_COMMON_TRACES; + tmpbuffer.str(""); + } -DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgDEBUGFLOW; -DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgERRORFLOW; + inline DebugTrace& pre(const std::ostream&) { return *this; } + + inline DebugTrace& pre(const std::ostream&, int level) + { + traceLevel = level; + return *this; + } + + static const char* DEBUG_FILENAME_DEFAULT; + static void openFile(const char* filename = DEBUG_FILENAME_DEFAULT); + static void closeFile(const char* filename = DEBUG_FILENAME_DEFAULT); + }; + + DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgDEBUGFLOW; + DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgERRORFLOW; } // end of namespace dynamicgraph #ifdef VP_DEBUG #define dgPREDEBUG __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :" -#define dgPREERROR "\t!! " << __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :" +#define dgPREERROR "\t!! " << __FILE__ << ": " << __FUNCTION__ << \ + "(#" << __LINE__ << ") :" #define dgDEBUG(level) \ if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \ @@ -138,15 +147,19 @@ DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgERRORFLOW; if (!dgDEBUGFLOW.outputbuffer.good()) \ ; \ else \ - dgDEBUGFLOW.pre(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_TEMPLATE_DEBUG_MODE).trace + dgDEBUGFLOW.pre(dgDEBUGFLOW.tmpbuffer << \ + dgPREDEBUG, VP_TEMPLATE_DEBUG_MODE).trace -inline bool dgDEBUG_ENABLE(const int& level) { return level <= VP_DEBUG_MODE; } +inline bool dgDEBUG_ENABLE(const int& level) +{ return level <= VP_DEBUG_MODE; } -inline bool dgTDEBUG_ENABLE(const int& level) { return level <= VP_TEMPLATE_DEBUG_MODE; } +inline bool dgTDEBUG_ENABLE(const int& level) +{ return level <= VP_TEMPLATE_DEBUG_MODE; } #else // VP_DEBUG -#define dgPREERROR "\t!! " << __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :" +#define dgPREERROR "\t!! " << __FILE__ << ": " << __FUNCTION__ << \ + "(#" << __LINE__ << ") :" #define dgDEBUG(level) \ if (1) \ @@ -168,13 +181,15 @@ inline void dgERRORF(const int, const char*, ...) { return; } inline void dgERRORF(const char*, ...) { return; } -namespace dynamicgraph { -inline std::ostream& __null_stream() { - // This function should never be called. With -O3, - // it should not appear in the generated binary. - static std::ostream os(NULL); - return os; -} +namespace dynamicgraph +{ + inline std::ostream& __null_stream() + { + // This function should never be called. With -O3, + // it should not appear in the generated binary. + static std::ostream os(NULL); + return os; + } } // namespace dynamicgraph // TEMPLATE diff --git a/include/dynamic-graph/eigen-io.h b/include/dynamic-graph/eigen-io.h index 9184e77..e84df6e 100644 --- a/include/dynamic-graph/eigen-io.h +++ b/include/dynamic-graph/eigen-io.h @@ -24,127 +24,171 @@ using dynamicgraph::ExceptionSignal; * Input Vector format: [N](val1,val2,val3,...,valN) * e.g. [5](1,23,32.2,12.12,32) */ -namespace Eigen { -typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE eigen_index; - -inline std::istringstream &operator>>(std::istringstream &iss, dynamicgraph::Vector &inst) { - unsigned int _size; - double _dbl_val; - char _ch; - boost::format fmt("Failed to enter %s as vector. Reenter as [N](val1,val2,val3,...,valN)"); - fmt % iss.str(); - if (iss >> _ch && _ch != '[') { - throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - } else { - if (iss >> _size && !iss.fail()) { - inst.resize(_size); - } else - throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - if (iss >> _ch && _ch != ']') - throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - else { - if (iss >> _ch && _ch != '(') +namespace Eigen +{ + typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE eigen_index; + + inline std::istringstream &operator>> + (std::istringstream &iss, dynamicgraph::Vector &inst) + { + unsigned int _size; + double _dbl_val; + char _ch; + boost::format fmt("Failed to enter %s as vector." + " Reenter as [N](val1,val2,val3,...,valN)"); + fmt % iss.str(); + if (iss >> _ch && _ch != '[') + { throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - else { - for (unsigned int i = 0; i < _size; i++) { - iss >> _dbl_val; - if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore(); - inst(i) = _dbl_val; - } - if (iss >> _ch && _ch != ')') throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); } - } + else + { + if (iss >> _size && !iss.fail()) + { + inst.resize(_size); + } + else + throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); + if (iss >> _ch && _ch != ']') + throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); + else + { + if (iss >> _ch && _ch != '(') + throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); + else + { + for (unsigned int i = 0; i < _size; i++) + { + iss >> _dbl_val; + if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore(); + inst(i) = _dbl_val; + } + if (iss >> _ch && _ch != ')') + throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); + } + } + } + return iss; } - return iss; -} -/* \brief Eigen Matrix input from istream - * - * Matrix format: [M,N]((val11,val12,val13,...,val1N),...,(valM1,valM2,...,valMN)) - * e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2)) - */ - -template <typename Derived> -inline std::istringstream &operator>>(std::istringstream &iss, DenseBase<Derived> &inst) { - unsigned int _colsize; - unsigned int _rowsize; - double _dbl_val; - char _ch; - boost::format fmt( - "Failed to enter %s as matrix. Reenter as ((val11,val12,val13,...,val1N),...,(valM1,valM2,...,valMN))"); - MatrixXd _tmp_matrix; - fmt % iss.str(); - if (iss >> _ch && _ch != '[') { - throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - } else { - iss >> _rowsize; - if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore(); - iss >> _colsize; - if (iss.fail()) - throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - else { - _tmp_matrix.resize(_rowsize, _colsize); - if (iss >> _ch && _ch != ']') + /* \brief Eigen Matrix input from istream + * + * Matrix format: [M,N]((val11,val12,val13,...,val1N),..., + * (valM1,valM2,...,valMN)) + * e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2)) + */ + + template <typename Derived> + inline std::istringstream &operator>> + (std::istringstream &iss, DenseBase<Derived> &inst) + { + unsigned int _colsize; + unsigned int _rowsize; + double _dbl_val; + char _ch; + boost::format + fmt("Failed to enter %s as matrix. Reenter as " + "((val11,val12,val13,...,val1N)," + "...,(valM1,valM2,...,valMN))"); + MatrixXd _tmp_matrix; + fmt % iss.str(); + if (iss >> _ch && _ch != '[') + { throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - else { - if (iss >> _ch && _ch != '(') + } + else + { + iss >> _rowsize; + if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore(); + iss >> _colsize; + if (iss.fail()) throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - else { - for (unsigned int j = 0; j < _rowsize; j++) { - if (iss >> _ch && _ch != '(') throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - for (unsigned int i = 0; i < _colsize; i++) { - iss >> _dbl_val; - if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore(); - _tmp_matrix(j, i) = _dbl_val; - } - if (iss >> _ch && _ch != ')') throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore(); + else + { + _tmp_matrix.resize(_rowsize, _colsize); + if (iss >> _ch && _ch != ']') + throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); + else + { + if (iss >> _ch && _ch != '(') + throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); + else + { + for (unsigned int j = 0; j < _rowsize; j++) + { + if (iss >> _ch && _ch != '(') + throw ExceptionSignal + (ExceptionSignal::GENERIC, fmt.str()); + for (unsigned int i = 0; i < _colsize; i++) + { + iss >> _dbl_val; + if (iss.peek() == ',' || iss.peek() == ' ') + iss.ignore(); + _tmp_matrix(j, i) = _dbl_val; + } + if (iss >> _ch && _ch != ')') + throw ExceptionSignal + (ExceptionSignal::GENERIC, fmt.str()); + if (iss.peek() == ',' || iss.peek() == ' ') + iss.ignore(); + } + if (iss >> _ch && _ch != ')') + throw + ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); + } + } } - if (iss >> _ch && _ch != ')') throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); - } } - } + inst = _tmp_matrix; + return iss; } - inst = _tmp_matrix; - return iss; -} - -inline std::istringstream &operator>>(std::istringstream &iss, Transform<double, 3, Affine> &inst) { - MatrixXd M; - iss >> M; - inst.matrix() = M; - return iss; -} - -/* \brief Eigen Homogeneous Matrix output - * - * Matrix format: [M,N]((val11,val12,val13,...,val1N),...,(valM1,valM2,...,valMN)) - * e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2)) - */ -inline std::ostream &operator<<(std::ostream &os, Transform<double, 3, Affine> MH) { - IOFormat boostFmt(StreamPrecision, DontAlignCols, ",", ",", "(", ")", "(", ")"); - - os << "[4,4]" << MH.matrix().format(boostFmt); - return os; -} - -inline std::ostream &operator<<(std::ostream &os, AngleAxisd quat) { - VectorXd v(4); - v(0) = quat.angle(); - v.tail<3>() = quat.axis(); - os << v; - return os; -} - -inline std::istringstream &operator>>(std::istringstream &iss, AngleAxisd &inst) { - VectorXd v(4); - iss >> v; - inst.angle() = v(0); - inst.axis() = v.tail<3>(); - return iss; -} + inline std::istringstream &operator>> + (std::istringstream &iss, Transform<double, 3, Affine> &inst) + { + MatrixXd M; + iss >> M; + inst.matrix() = M; + return iss; + } + + /* \brief Eigen Homogeneous Matrix output + * + * Matrix format: [M,N]((val11,val12,val13,...,val1N),..., + * (valM1,valM2,...,valMN)) + * e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2)) + */ + + inline std::ostream &operator<< + (std::ostream &os, Transform<double, 3, Affine> MH) + { + IOFormat boostFmt(StreamPrecision, DontAlignCols, + ",", ",", "(", ")", "(", ")"); + + os << "[4,4]" << MH.matrix().format(boostFmt); + return os; + } + + inline std::ostream &operator<<(std::ostream &os, AngleAxisd quat) + { + VectorXd v(4); + v(0) = quat.angle(); + v.tail<3>() = quat.axis(); + os << v; + return os; + } + + inline std::istringstream &operator>> + (std::istringstream &iss, AngleAxisd &inst) + { + VectorXd v(4); + iss >> v; + inst.angle() = v(0); + inst.axis() = v.tail<3>(); + return iss; + } } // namespace Eigen #endif // DYNAMIC_GRAPH_EIGEN_IO_H + diff --git a/include/dynamic-graph/entity.h b/include/dynamic-graph/entity.h index b534d9c..09c36cb 100644 --- a/include/dynamic-graph/entity.h +++ b/include/dynamic-graph/entity.h @@ -41,87 +41,95 @@ virtual const std::string& getClassName() const { return CLASS_NAME; } \ static const std::string CLASS_NAME -namespace dynamicgraph { -/// \ingroup dgraph -/// -/// \brief This class represents an entity, i.e. a generic -/// computational unit that provides input and output signals. -/// -/// These signals link the entities together to form a complete -/// computation graph. To declare a new entity, please see the -/// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro in factory.h. -class DYNAMIC_GRAPH_DLLAPI Entity : private boost::noncopyable { - public: - typedef std::map<std::string, SignalBase<int>*> SignalMap; - typedef std::map<const std::string, command::Command*> CommandMap_t; - - explicit Entity(const std::string& name); - virtual ~Entity(); - - const std::string& getName() const { return name; } - virtual const std::string& getClassName() const { - static std::string ret("Entity"); - return ret; - } - virtual std::string getDocString() const; - bool hasSignal(const std::string& signame) const; - SignalBase<int>& getSignal(const std::string& signalName); - const SignalBase<int>& getSignal(const std::string& signalName) const; - std::ostream& displaySignalList(std::ostream& os) const; - virtual std::ostream& writeGraph(std::ostream& os) const; - virtual std::ostream& writeCompletionList(std::ostream& os) const; - - virtual void display(std::ostream& os) const; - - virtual SignalBase<int>* test() { return 0; } - - virtual void test2(SignalBase<int>*) { return; } - - const std::string& getCommandList() const; - CommandMap_t getNewStyleCommandMap(); - command::Command* getNewStyleCommand(const std::string& cmdName); - - SignalMap getSignalMap() const; - - /** \name Logger related methods */ - /** \{*/ - /// \brief Send messages \param msg with level t. Add string file and line to message. - void sendMsg(const std::string& msg, MsgType t = MSG_TYPE_INFO, const char* file = "", int line = 0); - - /// \brief Specify the verbosity level of the logger. - void setLoggerVerbosityLevel(LoggerVerbosity lv) { logger_.setVerbosity(lv); } - - /// \brief Get the logger's verbosity level. - LoggerVerbosity getLoggerVerbosityLevel() { return logger_.getVerbosity(); } - - /// \brief Set the time sample. - bool setTimeSample(double t) { return logger_.setTimeSample(t); } - - /// \brief Get the time sample. - double getTimeSample() { return logger_.getTimeSample(); } - - /// \brief Set the period of the stream period - bool setStreamPrintPeriod(double t) { return logger_.setStreamPrintPeriod(t); } - - /// \brief Get the period of the stream period - double getStreamPrintPeriod() { return logger_.getStreamPrintPeriod(); } - - protected: - void addCommand(const std::string& name, command::Command* command); - - void entityRegistration(); - void entityDeregistration(); - - void signalRegistration(const SignalArray<int>& signals); - void signalDeregistration(const std::string& name); - - std::string name; - SignalMap signalMap; - CommandMap_t commandMap; - Logger logger_; -}; - -DYNAMIC_GRAPH_DLLAPI std::ostream& operator<<(std::ostream& os, const dynamicgraph::Entity& ent); +namespace dynamicgraph +{ + /// \ingroup dgraph + /// + /// \brief This class represents an entity, i.e. a generic + /// computational unit that provides input and output signals. + /// + /// These signals link the entities together to form a complete + /// computation graph. To declare a new entity, please see the + /// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro in factory.h. + class DYNAMIC_GRAPH_DLLAPI Entity : private boost::noncopyable + { + public: + typedef std::map<std::string, SignalBase<int>*> SignalMap; + typedef std::map<const std::string, command::Command*> CommandMap_t; + + explicit Entity(const std::string& name); + virtual ~Entity(); + + const std::string& getName() const { return name; } + virtual const std::string& getClassName() const + { + static std::string ret("Entity"); + return ret; + } + virtual std::string getDocString() const; + bool hasSignal(const std::string& signame) const; + SignalBase<int>& getSignal(const std::string& signalName); + const SignalBase<int>& getSignal(const std::string& signalName) const; + std::ostream& displaySignalList(std::ostream& os) const; + virtual std::ostream& writeGraph(std::ostream& os) const; + virtual std::ostream& writeCompletionList(std::ostream& os) const; + + virtual void display(std::ostream& os) const; + + virtual SignalBase<int>* test() { return 0; } + + virtual void test2(SignalBase<int>*) { return; } + + const std::string& getCommandList() const; + CommandMap_t getNewStyleCommandMap(); + command::Command* getNewStyleCommand(const std::string& cmdName); + + SignalMap getSignalMap() const; + + /** \name Logger related methods */ + /** \{*/ + /// \brief Send messages \param msg with level t. + /// Add string file and line to message. + void sendMsg(const std::string& msg, MsgType t = MSG_TYPE_INFO, + const char* file = "", int line = 0); + + /// \brief Specify the verbosity level of the logger. + void setLoggerVerbosityLevel(LoggerVerbosity lv) + { logger_.setVerbosity(lv); } + + /// \brief Get the logger's verbosity level. + LoggerVerbosity getLoggerVerbosityLevel() { return logger_.getVerbosity(); } + + /// \brief Set the time sample. + bool setTimeSample(double t) { return logger_.setTimeSample(t); } + + /// \brief Get the time sample. + double getTimeSample() { return logger_.getTimeSample(); } + + /// \brief Set the period of the stream period + bool setStreamPrintPeriod(double t) + { return logger_.setStreamPrintPeriod(t); } + + /// \brief Get the period of the stream period + double getStreamPrintPeriod() { return logger_.getStreamPrintPeriod(); } + + protected: + void addCommand(const std::string& name, command::Command* command); + + void entityRegistration(); + void entityDeregistration(); + + void signalRegistration(const SignalArray<int>& signals); + void signalDeregistration(const std::string& name); + + std::string name; + SignalMap signalMap; + CommandMap_t commandMap; + Logger logger_; + }; + + DYNAMIC_GRAPH_DLLAPI std::ostream& operator<< + (std::ostream& os, const dynamicgraph::Entity& ent); } // end of namespace dynamicgraph #endif //! DYNAMIC_GRAPH_ENTITY_H diff --git a/include/dynamic-graph/exception-abstract.h b/include/dynamic-graph/exception-abstract.h index 4d60e13..f584a69 100644 --- a/include/dynamic-graph/exception-abstract.h +++ b/include/dynamic-graph/exception-abstract.h @@ -17,45 +17,55 @@ (const ::dynamicgraph::ExceptionAbstract& err) { throw err; } #ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM -#define DG_THROW throw ::dynamicgraph::ExceptionAbstract::Param(__LINE__, __FUNCTION__, __FILE__) + +#define DG_THROW \ + throw ::dynamicgraph::ExceptionAbstract::Param \ + (__LINE__, __FUNCTION__, __FILE__) + #else #define DG_THROW throw #endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM -namespace dynamicgraph { -/// \ingroup error -/// -/// \brief Abstract root class for all dynamic-graph exceptions. -class DYNAMIC_GRAPH_DLLAPI ExceptionAbstract : public std::exception { - public: +namespace dynamicgraph +{ /// \ingroup error /// - /// \brief Class owned by exceptions to store error locations. - class Param { - public: - static const int BUFFER_SIZE = 80; - - Param(const int& _line, const char* _function, const char* _file); - Param() : functionPTR(), function(), line(), filePTR(), file(), pointersSet(false), set(false) {} - Param& initCopy(const Param& p); - - const char* functionPTR; - char function[BUFFER_SIZE]; - int line; - const char* filePTR; - char file[BUFFER_SIZE]; - bool pointersSet; - bool set; - }; - - /// \brief Categories error code. - /// - /// Each value matches categories used by a subclass of - /// ExceptionAbstract. - /// - /// This is the programmer responsibility to make sure there is - /// enough room between two categories error code. - enum ExceptionEnum { ABSTRACT = 0, SIGNAL = 100, FACTORY = 200, TRACES = 300, TOOLS = 700 }; + /// \brief Abstract root class for all dynamic-graph exceptions. + class DYNAMIC_GRAPH_DLLAPI ExceptionAbstract : public std::exception + { + public: + /// \ingroup error + /// + /// \brief Class owned by exceptions to store error locations. + class Param + { + public: + static const int BUFFER_SIZE = 80; + + Param(const int& _line, const char* _function, const char* _file); + Param() : functionPTR(), function(), line(), filePTR(), file(), + pointersSet(false), set(false) {} + Param& initCopy(const Param& p); + + const char* functionPTR; + char function[BUFFER_SIZE]; + int line; + const char* filePTR; + char file[BUFFER_SIZE]; + bool pointersSet; + bool set; + }; + + /// \brief Categories error code. + /// + /// Each value matches categories used by a subclass of + /// ExceptionAbstract. + /// + /// This is the programmer responsibility to make sure there is + /// enough room between two categories error code. + enum ExceptionEnum { ABSTRACT = 0, + SIGNAL = 100, + FACTORY = 200, + TRACES = 300, + TOOLS = 700 }; static const std::string EXCEPTION_NAME; @@ -76,10 +86,12 @@ class DYNAMIC_GRAPH_DLLAPI ExceptionAbstract : public std::exception { /// Cannot be \e NULL. const char* getMessage() const; - virtual const char* what() const throw() { return getStringMessage().c_str(); } + virtual const char* what() const throw() + { return getStringMessage().c_str(); } /// \brief Print the error structure. - DYNAMIC_GRAPH_DLLAPI friend std::ostream& operator<<(std::ostream& os, const ExceptionAbstract& err); + DYNAMIC_GRAPH_DLLAPI friend std::ostream& operator<< + (std::ostream& os, const ExceptionAbstract& err); protected: /// \brief Error code. @@ -97,13 +109,15 @@ class DYNAMIC_GRAPH_DLLAPI ExceptionAbstract : public std::exception { mutable Param p; template <class Exc> - friend const Exc& operator+(const ExceptionAbstract::Param& p, const Exc& e) { + friend const Exc& operator+(const ExceptionAbstract::Param& p, const Exc& e) + { e.p.initCopy(p); return e; } template <class Exc> - friend Exc& operator+(const ExceptionAbstract::Param& p, Exc& e) { + friend Exc& operator+(const ExceptionAbstract::Param& p, Exc& e) + { e.p.initCopy(p); return e; } diff --git a/include/dynamic-graph/exception-factory.h b/include/dynamic-graph/exception-factory.h index 2813a95..5faac13 100644 --- a/include/dynamic-graph/exception-factory.h +++ b/include/dynamic-graph/exception-factory.h @@ -11,35 +11,43 @@ #include <dynamic-graph/dynamic-graph-api.h> #include <dynamic-graph/exception-abstract.h> -namespace dynamicgraph { -/// \ingroup error -/// -/// \brief Generic error class. -class DYNAMIC_GRAPH_DLLAPI ExceptionFactory : public ExceptionAbstract { - public: - enum ErrorCodeEnum { - GENERIC = ExceptionAbstract::FACTORY, - UNREFERED_OBJECT, - UNREFERED_SIGNAL, - UNREFERED_FUNCTION, - DYNAMIC_LOADING, - SIGNAL_CONFLICT, - FUNCTION_CONFLICT, - OBJECT_CONFLICT, - SYNTAX_ERROR, - READ_FILE +namespace dynamicgraph +{ + /// \ingroup error + /// + /// \brief Generic error class. + class DYNAMIC_GRAPH_DLLAPI ExceptionFactory : public ExceptionAbstract + { + public: + enum ErrorCodeEnum + { + GENERIC = ExceptionAbstract::FACTORY, + UNREFERED_OBJECT, + UNREFERED_SIGNAL, + UNREFERED_FUNCTION, + DYNAMIC_LOADING, + SIGNAL_CONFLICT, + FUNCTION_CONFLICT, + OBJECT_CONFLICT, + SYNTAX_ERROR, + READ_FILE + }; + + static const std::string EXCEPTION_NAME; + + explicit ExceptionFactory + (const ExceptionFactory::ErrorCodeEnum& errcode, + const std::string& msg = ""); + + ExceptionFactory + (const ExceptionFactory::ErrorCodeEnum& errcode, + const std::string& msg, const char* format, ...); + + virtual ~ExceptionFactory() throw() {} + + virtual const std::string& getExceptionName() const + { return ExceptionFactory::EXCEPTION_NAME; } }; - - static const std::string EXCEPTION_NAME; - - explicit ExceptionFactory(const ExceptionFactory::ErrorCodeEnum& errcode, const std::string& msg = ""); - - ExceptionFactory(const ExceptionFactory::ErrorCodeEnum& errcode, const std::string& msg, const char* format, ...); - - virtual ~ExceptionFactory() throw() {} - - virtual const std::string& getExceptionName() const { return ExceptionFactory::EXCEPTION_NAME; } -}; } // end of namespace dynamicgraph #endif //! DYNAMIC_GRAPH_EXCEPTION_FACTORY_H diff --git a/include/dynamic-graph/exception-signal.h b/include/dynamic-graph/exception-signal.h index b7a108c..9482cfd 100644 --- a/include/dynamic-graph/exception-signal.h +++ b/include/dynamic-graph/exception-signal.h @@ -10,34 +10,40 @@ #include <dynamic-graph/dynamic-graph-api.h> #include <dynamic-graph/exception-abstract.h> -namespace dynamicgraph { -/// \ingroup error -/// -/// \brief Exceptions raised when an error related to signals -/// happen. -class DYNAMIC_GRAPH_DLLAPI ExceptionSignal : public ExceptionAbstract { - public: - enum ErrorCodeEnum { - GENERIC = ExceptionAbstract::SIGNAL - - , - READWRITE_LOCK, - COPY_NOT_INITIALIZED, - NOT_INITIALIZED, - PLUG_IMPOSSIBLE, - SET_IMPOSSIBLE, - BAD_CAST +namespace dynamicgraph +{ + /// \ingroup error + /// + /// \brief Exceptions raised when an error related to signals + /// happen. + class DYNAMIC_GRAPH_DLLAPI ExceptionSignal : public ExceptionAbstract + { + public: + enum ErrorCodeEnum + { + GENERIC = ExceptionAbstract::SIGNAL, + READWRITE_LOCK, + COPY_NOT_INITIALIZED, + NOT_INITIALIZED, + PLUG_IMPOSSIBLE, + SET_IMPOSSIBLE, + BAD_CAST + }; + + static const std::string EXCEPTION_NAME; + + explicit ExceptionSignal + (const ExceptionSignal::ErrorCodeEnum& errcode, + const std::string& msg = ""); + ExceptionSignal + (const ExceptionSignal::ErrorCodeEnum& errcode, + const std::string& msg, const char* format, ...); + virtual ~ExceptionSignal() throw() {} + + virtual const std::string& getExceptionName() const + { return EXCEPTION_NAME; } }; - static const std::string EXCEPTION_NAME; - - explicit ExceptionSignal(const ExceptionSignal::ErrorCodeEnum& errcode, const std::string& msg = ""); - ExceptionSignal(const ExceptionSignal::ErrorCodeEnum& errcode, const std::string& msg, const char* format, ...); - virtual ~ExceptionSignal() throw() {} - - virtual const std::string& getExceptionName() const { return EXCEPTION_NAME; } -}; - } // end of namespace dynamicgraph #endif //! DYNAMIC_GRAPH_EXCEPTION_SIGNAL_H diff --git a/include/dynamic-graph/exception-traces.h b/include/dynamic-graph/exception-traces.h index e7d559b..cd078b9 100644 --- a/include/dynamic-graph/exception-traces.h +++ b/include/dynamic-graph/exception-traces.h @@ -11,22 +11,26 @@ #include <dynamic-graph/dynamic-graph-api.h> #include <dynamic-graph/exception-abstract.h> -namespace dynamicgraph { -/// \ingroup error -/// -/// \brief Exceptions raised when an error related to traces happen. -class DYNAMIC_GRAPH_DLLAPI ExceptionTraces : public ExceptionAbstract { - public: - enum ErrorCodeEnum { GENERIC = ExceptionAbstract::TRACES, NOT_OPEN }; - - static const std::string EXCEPTION_NAME; - - explicit ExceptionTraces(const ExceptionTraces::ErrorCodeEnum& errcode, const std::string& msg = ""); - ExceptionTraces(const ExceptionTraces::ErrorCodeEnum& errcode, const std::string& msg, const char* format, ...); - virtual ~ExceptionTraces() throw() {} - - virtual const std::string& getExceptionName() const { return EXCEPTION_NAME; } -}; +namespace dynamicgraph +{ + /// \ingroup error + /// + /// \brief Exceptions raised when an error related to traces happen. + class DYNAMIC_GRAPH_DLLAPI ExceptionTraces : public ExceptionAbstract { + public: + enum ErrorCodeEnum { GENERIC = ExceptionAbstract::TRACES, NOT_OPEN }; + + static const std::string EXCEPTION_NAME; + + explicit ExceptionTraces(const ExceptionTraces::ErrorCodeEnum& errcode, + const std::string& msg = ""); + ExceptionTraces(const ExceptionTraces::ErrorCodeEnum& errcode, + const std::string& msg, const char* format, ...); + virtual ~ExceptionTraces() throw() {} + + virtual const std::string& getExceptionName() const + { return EXCEPTION_NAME; } + }; } // end of namespace dynamicgraph. #endif //! DYNAMIC_GRAPH_EXCEPTION_TRACES_H diff --git a/include/dynamic-graph/factory.h b/include/dynamic-graph/factory.h index 1770689..25337a7 100644 --- a/include/dynamic-graph/factory.h +++ b/include/dynamic-graph/factory.h @@ -24,172 +24,178 @@ /// \param CLASSNAME the name of the Entity to be registered (this must /// be a std::string or a type implicitly castable into a std::string /// such as classic C string delimited by double quotes). -#define DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CLASSTYPE, CLASSNAME) \ - const std::string CLASSTYPE::CLASS_NAME = CLASSNAME; \ - extern "C" { \ - ::dynamicgraph::Entity* EntityMaker_##CLASSTYPE(const std::string& objname) { return new CLASSTYPE(objname); } \ - ::dynamicgraph::EntityRegisterer reg_##CLASSTYPE(CLASSNAME, &EntityMaker_##CLASSTYPE); \ - } \ +#define DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CLASSTYPE, CLASSNAME) \ + const std::string CLASSTYPE::CLASS_NAME = CLASSNAME; \ + extern "C" { \ + ::dynamicgraph::Entity* \ + EntityMaker_##CLASSTYPE(const std::string& objname) \ + { return new CLASSTYPE(objname); } \ + ::dynamicgraph::EntityRegisterer \ + reg_##CLASSTYPE(CLASSNAME, &EntityMaker_##CLASSTYPE); \ + } \ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n namespace dynamicgraph { -/// \ingroup dgraph -/// -/// \brief Provides a way to create Entity objects from their class -/// name. -/// -/// The dynamic graph frameworks relies on entities (see Entity) -/// which defines atomic processing units. This class provides a -/// robust way to enumerate and instantiate these entities. -/// Each entity has a name (its type name) and can be instantiated. -/// Each instance also has a name. -/// -/// For instance one can define a C++ class called MyEntity which -/// inherits from dynamicgraph::Entity. This type can be registered -/// into the factory to teach the framework that: -/// - this entity exists -/// - this entity can be instantiated (and how to instantiate it). -/// -/// To achieve this, one must pass an entity name and a function pointer. -/// -/// The entity name will identify the class <b>at run-time</b> -/// (be careful: this may not be equivalent to the C++ class name -/// even if it is recommended to do so). -/// -/// The function pointer must point on a function taking a string as -/// input and returning an instance of the Entity (the concrete -/// subclass, not directly the upper Entity class). -/// -/// The instances returned by this function <b>must</b> be -/// dynamically allocated and the caller <b>must</b> get the -/// ownership of the instance (i.e. it will free it when required). -/// -/// To finish, please note that the instance name indicates to the -/// entity how the instance itself is called at run-time. This name -/// does not need to be unique and no check is done on it. It is -/// the caller responsibility to make sure that the instance name is -/// appropriate and to check for uniqueness if required. -/// -/// -/// This class is a singleton. The rationale is that each -/// unique name must identify a unique Entity. The use of a single -/// instance of this class enforces this behavior, instantiating one -/// yourself would break this property. -class DYNAMIC_GRAPH_DLLAPI FactoryStorage : private boost::noncopyable { - public: - /// \brief Function pointer providing an entity instance from its - /// name. - typedef Entity* (*EntityConstructor_ptr)(const std::string&); - - ~FactoryStorage(); - - /// \brief Get pointer to unique object of the class - static FactoryStorage* getInstance(); - - /// \brief Destroy the unique instance of the class - static void destroy(); - - /// \brief Add a new entity to the factory. + /// \ingroup dgraph /// - /// It is not allowed to have several entities using the same - /// name. If this is the case, an ExceptionFactory exception will - /// be raised with the code OBJECT_CONFLICT. - /// - /// If the function pointer is null, an ExceptionFactory exception - /// will be raised with the code OBJECT_CONFLICT. - /// - /// \param entname the name used to subscribe the entity. - /// \param ent pointer to a function allocating an entity from an - /// instance name. - void registerEntity(const std::string& entname, EntityConstructor_ptr ent); - - /// \brief Delete an entity from the factory. - /// - /// If the provided entity name does not exist in the factory, - /// an ExceptionFactory exception will be raised with the code - /// OBJECT_CONFLICT. + /// \brief Provides a way to create Entity objects from their class + /// name. /// - /// \param entname the entity name (as passed to registerEntity before) - void deregisterEntity(const std::string& entname); - - /// \brief Instantiate (and allocate) an entity. + /// The dynamic graph frameworks relies on entities (see Entity) + /// which defines atomic processing units. This class provides a + /// robust way to enumerate and instantiate these entities. + /// Each entity has a name (its type name) and can be instantiated. + /// Each instance also has a name. /// - /// An instance called objname of the entity which type is classname - /// will be allocated by this method. + /// For instance one can define a C++ class called MyEntity which + /// inherits from dynamicgraph::Entity. This type can be registered + /// into the factory to teach the framework that: + /// - this entity exists + /// - this entity can be instantiated (and how to instantiate it). /// - /// It is <b>the caller</b> responsibility to free the - /// returned object. + /// To achieve this, one must pass an entity name and a function pointer. /// - /// If the class name does not exist, an ExceptionFactory - /// exception will be raised with the code UNREFERED_OBJECT. + /// The entity name will identify the class <b>at run-time</b> + /// (be careful: this may not be equivalent to the C++ class name + /// even if it is recommended to do so). /// - /// The instance name (objname) is passed to the Entity - /// constructor and it is the caller responsibility to avoid - /// instance name conflicts if necessary. + /// The function pointer must point on a function taking a string as + /// input and returning an instance of the Entity (the concrete + /// subclass, not directly the upper Entity class). /// - /// \param classname the name of the Entity type - /// \param objname the instance name - /// \return Dynamically allocated instance of classname. - Entity* newEntity(const std::string& classname, const std::string& objname) const; - - /// \brief Check if an Entity associated with a particular name - /// has already been registered. + /// The instances returned by this function <b>must</b> be + /// dynamically allocated and the caller <b>must</b> get the + /// ownership of the instance (i.e. it will free it when required). /// - /// \param name entity name - /// \return Do the entity exist? - bool existEntity(const std::string& name) const; - - /// \brief List the available entities. + /// To finish, please note that the instance name indicates to the + /// entity how the instance itself is called at run-time. This name + /// does not need to be unique and no check is done on it. It is + /// the caller responsibility to make sure that the instance name is + /// appropriate and to check for uniqueness if required. /// - /// Available entities are appended to the method argument. /// - /// \param list Available entities will be appended to list. - void listEntities(std::vector<std::string>& list) const; - - private: - /// \brief Constructor the factory. + /// This class is a singleton. The rationale is that each + /// unique name must identify a unique Entity. The use of a single + /// instance of this class enforces this behavior, instantiating one + /// yourself would break this property. + class DYNAMIC_GRAPH_DLLAPI FactoryStorage : private boost::noncopyable { + public: + /// \brief Function pointer providing an entity instance from its + /// name. + typedef Entity* (*EntityConstructor_ptr)(const std::string&); + + ~FactoryStorage(); + + /// \brief Get pointer to unique object of the class + static FactoryStorage* getInstance(); + + /// \brief Destroy the unique instance of the class + static void destroy(); + + /// \brief Add a new entity to the factory. + /// + /// It is not allowed to have several entities using the same + /// name. If this is the case, an ExceptionFactory exception will + /// be raised with the code OBJECT_CONFLICT. + /// + /// If the function pointer is null, an ExceptionFactory exception + /// will be raised with the code OBJECT_CONFLICT. + /// + /// \param entname the name used to subscribe the entity. + /// \param ent pointer to a function allocating an entity from an + /// instance name. + void registerEntity(const std::string& entname, EntityConstructor_ptr ent); + + /// \brief Delete an entity from the factory. + /// + /// If the provided entity name does not exist in the factory, + /// an ExceptionFactory exception will be raised with the code + /// OBJECT_CONFLICT. + /// + /// \param entname the entity name (as passed to registerEntity before) + void deregisterEntity(const std::string& entname); + + /// \brief Instantiate (and allocate) an entity. + /// + /// An instance called objname of the entity which type is classname + /// will be allocated by this method. + /// + /// It is <b>the caller</b> responsibility to free the + /// returned object. + /// + /// If the class name does not exist, an ExceptionFactory + /// exception will be raised with the code UNREFERED_OBJECT. + /// + /// The instance name (objname) is passed to the Entity + /// constructor and it is the caller responsibility to avoid + /// instance name conflicts if necessary. + /// + /// \param classname the name of the Entity type + /// \param objname the instance name + /// \return Dynamically allocated instance of classname. + Entity* newEntity(const std::string& classname, + const std::string& objname) const; + + /// \brief Check if an Entity associated with a particular name + /// has already been registered. + /// + /// \param name entity name + /// \return Do the entity exist? + bool existEntity(const std::string& name) const; + + /// \brief List the available entities. + /// + /// Available entities are appended to the method argument. + /// + /// \param list Available entities will be appended to list. + void listEntities(std::vector<std::string>& list) const; + + private: + /// \brief Constructor the factory. + /// + /// After the initialization, no entities will be available. + /// registerEntity has to be used to add new entities to the + /// object. + explicit FactoryStorage(); + + /// \brief Entity map type. + /// + /// This maps entity names to functions pointers which can be + /// used to instantiate an Entity. + typedef std::map<std::string, EntityConstructor_ptr> EntityMap; + + /// \brief The entity map storing information about how to + /// instantiate an Entity. + EntityMap entityMap; + + /// \pointer to the unique object of the class + static FactoryStorage* instance_; + }; + + /// \ingroup dgraph /// - /// After the initialization, no entities will be available. - /// registerEntity has to be used to add new entities to the - /// object. - explicit FactoryStorage(); - - /// \brief Entity map type. + /// \brief This class automatically register an Entity to the + /// global factory at initialization and unregister it during + /// instance destruction. /// - /// This maps entity names to functions pointers which can be - /// used to instantiate an Entity. - typedef std::map<std::string, EntityConstructor_ptr> EntityMap; - - /// \brief The entity map storing information about how to - /// instantiate an Entity. - EntityMap entityMap; - - /// \pointer to the unique object of the class - static FactoryStorage* instance_; -}; - -/// \ingroup dgraph -/// -/// \brief This class automatically register an Entity to the -/// global factory at initialization and unregister it during -/// instance destruction. -/// -/// This class is mainly used by the -/// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro and is of little interest -/// by itself. -class DYNAMIC_GRAPH_DLLAPI EntityRegisterer : private boost::noncopyable { - public: - /// \brief Register entity to the global factory. - explicit EntityRegisterer(const std::string& entityClassName, FactoryStorage::EntityConstructor_ptr maker); - - /// \brief Unregister entity to the global factory. - ~EntityRegisterer(); - - private: - /// \brief Name of the entity registered when the instance has - /// been initialized. - const std::string entityName; -}; + /// This class is mainly used by the + /// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro and is of little interest + /// by itself. + class DYNAMIC_GRAPH_DLLAPI EntityRegisterer : private boost::noncopyable + { + public: + /// \brief Register entity to the global factory. + explicit EntityRegisterer(const std::string& entityClassName, + FactoryStorage::EntityConstructor_ptr maker); + + /// \brief Unregister entity to the global factory. + ~EntityRegisterer(); + + private: + /// \brief Name of the entity registered when the instance has + /// been initialized. + const std::string entityName; + }; } // end of namespace dynamicgraph #endif //! DYNAMIC_GRAPH_FACTORY_HH diff --git a/include/dynamic-graph/logger.h b/include/dynamic-graph/logger.h index 94ec93b..95f0fe2 100644 --- a/include/dynamic-graph/logger.h +++ b/include/dynamic-graph/logger.h @@ -73,34 +73,42 @@ std::string toString(const T& v, const int precision=3, const int width=-1) }*/ template <typename T> -std::string toString(const std::vector<T>& v, const int precision = 3, const int width = -1, +std::string toString(const std::vector<T>& v, + const int precision = 3, const int width = -1, const std::string separator = ", ") { std::stringstream ss; if (width > precision) { for (int i = 0; i < v.size() - 1; i++) - ss << std::fixed << std::setw(width) << std::setprecision(precision) << v[i] << separator; - ss << std::fixed << std::setw(width) << std::setprecision(precision) << v[v.size() - 1]; + ss << std::fixed << std::setw(width) + << std::setprecision(precision) + << v[i] << separator; + ss << std::fixed << std::setw(width) + << std::setprecision(precision) << v[v.size() - 1]; } else { - for (int i = 0; i < v.size() - 1; i++) ss << std::fixed << std::setprecision(precision) << v[i] << separator; + for (int i = 0; i < v.size() - 1; i++) + ss << std::fixed << std::setprecision(precision) << v[i] << separator; ss << std::fixed << std::setprecision(precision) << v[v.size() - 1]; } return ss.str(); } -// template<typename T, int N> -// std::string toString(const Eigen::Matrix<T, N, 1, 0, N, 1>& v, const std::string separator=", ", -// const int precision=3, const int width=-1) template <typename T> -std::string toString(const Eigen::MatrixBase<T>& v, const int precision = 3, const int width = -1, - const std::string separator = ", ") { +std::string toString(const Eigen::MatrixBase<T>& v, + const int precision = 3, + const int width = -1, + const std::string separator = ", ") +{ std::stringstream ss; if (width > precision) { for (int i = 0; i < v.size() - 1; i++) - ss << std::fixed << std::setw(width) << std::setprecision(precision) << v[i] << separator; - ss << std::fixed << std::setw(width) << std::setprecision(precision) << v[v.size() - 1]; + ss << std::fixed << std::setw(width) + << std::setprecision(precision) << v[i] << separator; + ss << std::fixed << std::setw(width) + << std::setprecision(precision) << v[v.size() - 1]; } else { - for (int i = 0; i < v.size() - 1; i++) ss << std::fixed << std::setprecision(precision) << v[i] << separator; + for (int i = 0; i < v.size() - 1; i++) + ss << std::fixed << std::setprecision(precision) << v[i] << separator; ss << std::setprecision(precision) << v[v.size() - 1]; } @@ -132,7 +140,8 @@ enum LoggerVerbosity { /// } /// /// // Somewhere in your library -/// dynamicgraph::LoggerVerbosity aLoggerVerbosityLevel = VERBOSITY_WARNING_ERROR; +/// dynamicgraph::LoggerVerbosity aLoggerVerbosityLevel = +/// VERBOSITY_WARNING_ERROR; /// entity.setLoggerVerbosityLevel(aLoggerVerbosityLevel); /// ... /// std::string aMsg=aBaseMsg+" WARNING"; @@ -158,7 +167,10 @@ class Logger { * the point where sendMsg is called so that streaming messages are * printed only every streamPrintPeriod iterations. */ - void sendMsg(std::string msg, MsgType type, const char* file = "", int line = 0); + void sendMsg(std::string msg, + MsgType type, + const char* file = "", + int line = 0); /** Set the sampling time at which the method countdown() * is going to be called. */ @@ -182,25 +194,34 @@ class Logger { protected: LoggerVerbosity m_lv; /// verbosity of the logger - double m_timeSample; /// specify the period of call of the countdown method + double m_timeSample; + /// specify the period of call of the countdown method double m_streamPrintPeriod; /// specify the time period of the stream prints - double m_printCountdown; /// every time this is < 0 (i.e. every _streamPrintPeriod sec) print stuff + double m_printCountdown; + /// every time this is < 0 (i.e. every _streamPrintPeriod sec) print stuff - /** Pointer to the dynamic structure which holds the collection of streaming messages */ + /** Pointer to the dynamic structure which holds + the collection of streaming messages */ std::map<std::string, double> m_stream_msg_counters; - bool isStreamMsg(MsgType m) { - return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_DEBUG_STREAM || m == MSG_TYPE_INFO_STREAM || - m == MSG_TYPE_WARNING_STREAM; + bool isStreamMsg(MsgType m) + { + return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_DEBUG_STREAM || + m == MSG_TYPE_INFO_STREAM || + m == MSG_TYPE_WARNING_STREAM; } - bool isDebugMsg(MsgType m) { return m == MSG_TYPE_DEBUG_STREAM || m == MSG_TYPE_DEBUG; } + bool isDebugMsg(MsgType m) + { return m == MSG_TYPE_DEBUG_STREAM || m == MSG_TYPE_DEBUG; } - bool isInfoMsg(MsgType m) { return m == MSG_TYPE_INFO_STREAM || m == MSG_TYPE_INFO; } + bool isInfoMsg(MsgType m) + { return m == MSG_TYPE_INFO_STREAM || m == MSG_TYPE_INFO; } - bool isWarningMsg(MsgType m) { return m == MSG_TYPE_WARNING_STREAM || m == MSG_TYPE_WARNING; } + bool isWarningMsg(MsgType m) + { return m == MSG_TYPE_WARNING_STREAM || m == MSG_TYPE_WARNING; } - bool isErrorMsg(MsgType m) { return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_ERROR; } + bool isErrorMsg(MsgType m) + { return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_ERROR; } }; } // namespace dynamicgraph diff --git a/include/dynamic-graph/process-list.hh b/include/dynamic-graph/process-list.hh index 046d8e0..ba9ea92 100644 --- a/include/dynamic-graph/process-list.hh +++ b/include/dynamic-graph/process-list.hh @@ -13,153 +13,163 @@ #include <dynamic-graph/fwd.hh> #include <dynamic-graph/dynamic-graph-api.h> -namespace dynamicgraph { -namespace CPU { -class DYNAMIC_GRAPH_DLLAPI ProcessData {}; - -class DYNAMIC_GRAPH_DLLAPI ProcessList { - public: - ProcessList(); -}; - -/// \class This class gather information on a specific CPU. -/// -class DYNAMIC_GRAPH_DLLAPI CPUData { - public: - CPUData(); - int cpu_id_; - - inline unsigned long long int computePeriod(unsigned long long int &a, unsigned long long int &b) { - return (a > b) ? a - b : 0; - } - - /// \brief Various classes of time spend by the CPU - /// @{ - /// Total time - unsigned long long int total_time_; - /// Time spend in user mode - unsigned long long int user_mode_time_; - /// Time spend in user mode with low priority (nice mode) - unsigned long long int nice_time_; - /// Time spend in system mode - unsigned long long int system_time_; - /// Time spend in system mode - unsigned long long int system_all_time_; - /// Time spend in doing nothing. - unsigned long long int idle_time_; - /// Time spend in doing nothing. - unsigned long long int idle_all_time_; - /// Time spend in waiting an input/output to complete. - unsigned long long int iowait_time_; - /// Time spend in servicing hardware interrupts. - unsigned long long int irq_time_; - /// Time spend in servicing software interrupts. - unsigned long long int softirq_time_; - /// Time spend in other operating systems in a virtualized environments - /// Never doing this for control ! - unsigned long long int steal_time_; - /// Time spend running a virtual CPU for guest operating systems - /// under the control of the Linux kernel - unsigned long long int guest_time_; - /// Time spent running a niced guest - /// (virtual CPU for guest operating systems under the - /// control of the Linux kernel) - unsigned long long int guest_nice_time_; - /// @} - - /// \brief Various classes of time spend by the CPU by period - /// @{ - /// Total time - unsigned long long int total_period_; - /// Time spend in user mode - unsigned long long int user_mode_period_; - /// Time spend in user mode with low priority (nice mode) - unsigned long long int nice_period_; - /// Time spend in system mode - unsigned long long int system_period_; - /// Time spend in all system mode - unsigned long long int system_all_period_; - /// Time spend in doing nothing. - unsigned long long int idle_period_; - /// Time spend in doing nothing. - unsigned long long int idle_all_period_; - /// Time spend in waiting an input/output to complete. - unsigned long long int iowait_period_; - /// Time spend in servicing hardware interrupts. - unsigned long long int irq_period_; - /// Time spend in servicing software interrupts. - unsigned long long int softirq_period_; - /// Time spend in other operating systems in a virtualized environments - /// Never doing this for control ! - unsigned long long int steal_period_; - /// Time spend running a virtual CPU for guest operating systems - /// under the control of the Linux kernel - unsigned long long int guest_period_; - /// @} - - double percent_; - void ProcessLine(std::istringstream &aCPULine); - - friend class boost::serialization::access; - - template <class Archive> - void serialize(Archive &ar, const unsigned int version) { - ar &version; - ar &total_time_; - ar &user_mode_time_; - ar &nice_time_; - ar &system_time_; - ar &system_all_time_; - ar &idle_time_; - ar &idle_all_time_; - ar &iowait_time_; - ar &irq_time_; - ar &softirq_time_; - ar &steal_time_; - ar &guest_time_; - ar &guest_nice_time_; - ar &percent_; - } -}; - -/// \class This class gathers information on a computer. -/// This includes a list of CPU -class DYNAMIC_GRAPH_DLLAPI System { - private: - bool init_; - - public: - System(); - - /// Read /proc/state file to extract CPU count. - void init(); - - /// Update CPU data information from /proc/stat - void readProcStat(); - - /// Friend class for serialization. - friend class boost::serialization::access; - - /// Number of CPU. - unsigned int cpuNb_; - - void ProcessCPULine(unsigned int cpunb, std::istringstream &aCPULine); - - /// \brief Vector of CPU informations. - std::vector<CPUData> vCPUData_; - - /// \brief Global CPU information. - CPUData gCPUData_; - - template <class Archive> - void serialize(Archive &ar, const unsigned int version) { - ar &version; - ar &cpuNb_; - ar &gCPUData_; - ar &vCPUData_; - } -}; -} // namespace CPU +namespace dynamicgraph +{ + namespace CPU + { + class DYNAMIC_GRAPH_DLLAPI ProcessData {}; + + class DYNAMIC_GRAPH_DLLAPI ProcessList + { + public: + ProcessList(); + }; + + /// \class This class gather information on a specific CPU. + /// + class DYNAMIC_GRAPH_DLLAPI CPUData + { + public: + CPUData(); + int cpu_id_; + + inline unsigned long long int computePeriod + (unsigned long long int &a, unsigned long long int &b) + { + return (a > b) ? a - b : 0; + } + + /// \brief Various classes of time spend by the CPU + /// @{ + /// Total time + unsigned long long int total_time_; + /// Time spend in user mode + unsigned long long int user_mode_time_; + /// Time spend in user mode with low priority (nice mode) + unsigned long long int nice_time_; + /// Time spend in system mode + unsigned long long int system_time_; + /// Time spend in system mode + unsigned long long int system_all_time_; + /// Time spend in doing nothing. + unsigned long long int idle_time_; + /// Time spend in doing nothing. + unsigned long long int idle_all_time_; + /// Time spend in waiting an input/output to complete. + unsigned long long int iowait_time_; + /// Time spend in servicing hardware interrupts. + unsigned long long int irq_time_; + /// Time spend in servicing software interrupts. + unsigned long long int softirq_time_; + /// Time spend in other operating systems in a virtualized environments + /// Never doing this for control ! + unsigned long long int steal_time_; + /// Time spend running a virtual CPU for guest operating systems + /// under the control of the Linux kernel + unsigned long long int guest_time_; + /// Time spent running a niced guest + /// (virtual CPU for guest operating systems under the + /// control of the Linux kernel) + unsigned long long int guest_nice_time_; + /// @} + + /// \brief Various classes of time spend by the CPU by period + /// @{ + /// Total time + unsigned long long int total_period_; + /// Time spend in user mode + unsigned long long int user_mode_period_; + /// Time spend in user mode with low priority (nice mode) + unsigned long long int nice_period_; + /// Time spend in system mode + unsigned long long int system_period_; + /// Time spend in all system mode + unsigned long long int system_all_period_; + /// Time spend in doing nothing. + unsigned long long int idle_period_; + /// Time spend in doing nothing. + unsigned long long int idle_all_period_; + /// Time spend in waiting an input/output to complete. + unsigned long long int iowait_period_; + /// Time spend in servicing hardware interrupts. + unsigned long long int irq_period_; + /// Time spend in servicing software interrupts. + unsigned long long int softirq_period_; + /// Time spend in other operating systems in a virtualized environments + /// Never doing this for control ! + unsigned long long int steal_period_; + /// Time spend running a virtual CPU for guest operating systems + /// under the control of the Linux kernel + unsigned long long int guest_period_; + /// @} + + double percent_; + void ProcessLine(std::istringstream &aCPULine); + + friend class boost::serialization::access; + + template <class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar &version; + ar &total_time_; + ar &user_mode_time_; + ar &nice_time_; + ar &system_time_; + ar &system_all_time_; + ar &idle_time_; + ar &idle_all_time_; + ar &iowait_time_; + ar &irq_time_; + ar &softirq_time_; + ar &steal_time_; + ar &guest_time_; + ar &guest_nice_time_; + ar &percent_; + } + }; + + /// \class This class gathers information on a computer. + /// This includes a list of CPU + class DYNAMIC_GRAPH_DLLAPI System + { + private: + bool init_; + + public: + System(); + + /// Read /proc/state file to extract CPU count. + void init(); + + /// Update CPU data information from /proc/stat + void readProcStat(); + + /// Friend class for serialization. + friend class boost::serialization::access; + + /// Number of CPU. + unsigned int cpuNb_; + + void ProcessCPULine(unsigned int cpunb, std::istringstream &aCPULine); + + /// \brief Vector of CPU informations. + std::vector<CPUData> vCPUData_; + + /// \brief Global CPU information. + CPUData gCPUData_; + + template <class Archive> + void serialize(Archive &ar, const unsigned int version) + { + ar &version; + ar &cpuNb_; + ar &gCPUData_; + ar &vCPUData_; + } + }; + } // namespace CPU } // namespace dynamicgraph #endif /* DYNAMIC_GRAPH_PROCESS_LIST_H_ */ + diff --git a/include/dynamic-graph/real-time-logger.h b/include/dynamic-graph/real-time-logger.h index a2f6130..a18c643 100644 --- a/include/dynamic-graph/real-time-logger.h +++ b/include/dynamic-graph/real-time-logger.h @@ -14,160 +14,180 @@ #include <dynamic-graph/config.hh> #include <dynamic-graph/debug.h> -namespace dynamicgraph { -/// \ingroup debug -/// -/// \brief Stream for the real-time logger. -/// -/// You should inherit from this class in order to redirect the logs where you -/// want. -/// \sa LoggerIOStream -class LoggerStream { - public: - virtual void write(const char* c) = 0; -}; - -/// Write to an ostream object. -/// -/// The easieast is to use the macro \ref dgADD_OSTREAM_TO_RTLOG(ostr) where -/// `ostr` can be `std::cout` or an std::ofstream... -class LoggerIOStream : public LoggerStream { - public: - LoggerIOStream(std::ostream& os) : os_(os) {} - virtual void write(const char* c) { os_ << c; } - - private: - std::ostream& os_; -}; -typedef boost::shared_ptr<LoggerStream> LoggerStreamPtr_t; - -class RealTimeLogger; - -/// \cond DEVEL -/// \brief write entries to intenal buffer. -/// -/// The entry starts when an instance is created and ends when is is deleted. -/// This class is only used by RealTimeLogger. -class RTLoggerStream { - public: - RTLoggerStream(RealTimeLogger* logger, std::ostream& os) : logger_(logger), os_(os) {} - template <typename T> - inline RTLoggerStream& operator<<(T t) { - if (logger_ != NULL) os_ << t; - return *this; - } - inline RTLoggerStream& operator<<(std::ostream& (*pf)(std::ostream&)) { - if (logger_ != NULL) os_ << pf; - return *this; - } - - ~RTLoggerStream(); - - private: - RealTimeLogger* logger_; - std::ostream& os_; -}; -/// \endcond DEVEL - -/// \ingroup debug -/// -/// \brief Main class of the real-time logger. -/// -/// It is intended to be used like this: -/// \code -/// #define ENABLE_RT_LOG -/// #include <dynamic-graph/real-time-logger.h> -/// -/// // Somewhere in the main function of your executable -/// int main (int argc, char** argv) { -/// dgADD_OSTREAM_TO_RTLOG (std::cout); -/// } -/// -/// // Somewhere in your library -/// dgRTLOG() << "your message. Prefer to use \n than std::endl." -/// \endcode -/// -/// \note Thread safety. This class expects to have: -/// - only one reader: the one who take the log entries and write them somewhere. -/// - one writer at a time. Writing to the logs is **never** a blocking -/// operation. If the resource is busy, the log entry is discarded. -class DYNAMIC_GRAPH_DLLAPI RealTimeLogger { - public: - static RealTimeLogger& instance(); - - static void destroy(); - - /// \todo add an argument to preallocate the internal string to a given size. - RealTimeLogger(const std::size_t& bufferSize); - - inline void clearOutputStreams() { outputs_.clear(); } - - inline void addOutputStream(const LoggerStreamPtr_t& os) { outputs_.push_back(os); } - - /// Write next message to output. - /// It does nothing if the buffer is empty. - /// \return true if it wrote something - bool spinOnce(); - - /// Return an object onto which a real-time thread can write. - /// The message is considered finished when the object is destroyed. - RTLoggerStream front(); - - inline void frontReady() { - backIdx_ = (backIdx_ + 1) % buffer_.size(); - wmutex.unlock(); - } - - inline bool empty() const { return frontIdx_ == backIdx_; } - - inline bool full() const { return ((backIdx_ + 1) % buffer_.size()) == frontIdx_; } - - inline std::size_t size() const { - if (frontIdx_ <= backIdx_) - return backIdx_ - frontIdx_; - else - return backIdx_ + buffer_.size() - frontIdx_; - } - - inline std::size_t getBufferSize() { return buffer_.size(); } - - ~RealTimeLogger(); - - private: - struct Data { - std::stringbuf buf; +namespace dynamicgraph +{ + /// \ingroup debug + /// + /// \brief Stream for the real-time logger. + /// + /// You should inherit from this class in order to redirect the logs where you + /// want. + /// \sa LoggerIOStream + class LoggerStream + { + public: + virtual void write(const char* c) = 0; }; - std::vector<LoggerStreamPtr_t> outputs_; - std::vector<Data*> buffer_; - /// Index of the next value to be read. - std::size_t frontIdx_; - /// Index of the slot where to write next value (does not contain valid data). - std::size_t backIdx_; - std::ostream oss_; - - /// The writer mutex. - boost::mutex wmutex; - std::size_t nbDiscarded_; - - struct thread; - - static RealTimeLogger* instance_; - static thread* thread_; -}; + /// Write to an ostream object. + /// + /// The easieast is to use the macro \ref dgADD_OSTREAM_TO_RTLOG(ostr) where + /// `ostr` can be `std::cout` or an std::ofstream... + class LoggerIOStream : public LoggerStream + { + public: + LoggerIOStream(std::ostream& os) : os_(os) {} + virtual void write(const char* c) { os_ << c; } + + private: + std::ostream& os_; + }; + typedef boost::shared_ptr<LoggerStream> LoggerStreamPtr_t; + + class RealTimeLogger; + + /// \cond DEVEL + /// \brief write entries to intenal buffer. + /// + /// The entry starts when an instance is created and ends when is is deleted. + /// This class is only used by RealTimeLogger. + class RTLoggerStream + { + public: + RTLoggerStream(RealTimeLogger* logger, std::ostream& os) : + logger_(logger), os_(os) {} + template <typename T> + inline RTLoggerStream& operator<<(T t) + { + if (logger_ != NULL) os_ << t; + return *this; + } + inline RTLoggerStream& operator<<(std::ostream& (*pf)(std::ostream&)) + { + if (logger_ != NULL) os_ << pf; + return *this; + } + + ~RTLoggerStream(); + + private: + RealTimeLogger* logger_; + std::ostream& os_; + }; + /// \endcond DEVEL + + /// \ingroup debug + /// + /// \brief Main class of the real-time logger. + /// + /// It is intended to be used like this: + /// \code + /// #define ENABLE_RT_LOG + /// #include <dynamic-graph/real-time-logger.h> + /// + /// // Somewhere in the main function of your executable + /// int main (int argc, char** argv) { + /// dgADD_OSTREAM_TO_RTLOG (std::cout); + /// } + /// + /// // Somewhere in your library + /// dgRTLOG() << "your message. Prefer to use \n than std::endl." + /// \endcode + /// + /// \note Thread safety. This class expects to have: + /// - only one reader: the one who take the log entries and write them + /// somewhere. + /// - one writer at a time. Writing to the logs is **never** a blocking + /// operation. If the resource is busy, the log entry is discarded. + class DYNAMIC_GRAPH_DLLAPI RealTimeLogger + { + public: + static RealTimeLogger& instance(); + + static void destroy(); + + /// \todo add an argument to preallocate the internal string + /// to a given size. + RealTimeLogger(const std::size_t& bufferSize); + + inline void clearOutputStreams() { outputs_.clear(); } + + inline void addOutputStream(const LoggerStreamPtr_t& os) + { outputs_.push_back(os); } + + /// Write next message to output. + /// It does nothing if the buffer is empty. + /// \return true if it wrote something + bool spinOnce(); + + /// Return an object onto which a real-time thread can write. + /// The message is considered finished when the object is destroyed. + RTLoggerStream front(); + + inline void frontReady() + { + backIdx_ = (backIdx_ + 1) % buffer_.size(); + wmutex.unlock(); + } + + inline bool empty() const + { return frontIdx_ == backIdx_; } + + inline bool full() const + { return ((backIdx_ + 1) % buffer_.size()) == frontIdx_; } + + inline std::size_t size() const + { + if (frontIdx_ <= backIdx_) + return backIdx_ - frontIdx_; + else + return backIdx_ + buffer_.size() - frontIdx_; + } + + inline std::size_t getBufferSize() { return buffer_.size(); } + + ~RealTimeLogger(); + + private: + struct Data + { + std::stringbuf buf; + }; + + std::vector<LoggerStreamPtr_t> outputs_; + std::vector<Data*> buffer_; + /// Index of the next value to be read. + std::size_t frontIdx_; + /// Index of the slot where to write next value + /// (does not contain valid data). + std::size_t backIdx_; + std::ostream oss_; + + /// The writer mutex. + boost::mutex wmutex; + std::size_t nbDiscarded_; + + struct thread; + + static RealTimeLogger* instance_; + static thread* thread_; + }; } // end of namespace dynamicgraph #ifdef ENABLE_RT_LOG -#define dgADD_OSTREAM_TO_RTLOG(ostr) \ - ::dynamicgraph::RealTimeLogger::instance().addOutputStream( \ - ::dynamicgraph::LoggerStreamPtr_t(new ::dynamicgraph::LoggerIOStream(ostr))) +#define dgADD_OSTREAM_TO_RTLOG(ostr) \ + ::dynamicgraph::RealTimeLogger::instance(). \ + addOutputStream \ + ( ::dynamicgraph::LoggerStreamPtr_t \ + (new ::dynamicgraph::LoggerIOStream(ostr))) + #define dgRTLOG() ::dynamicgraph::RealTimeLogger::instance().front() #else // ENABLE_RT_LOG #define dgADD_OSTREAM_TO_RTLOG(ostr) struct __end_with_semicolon -#define dgRTLOG() \ - if (1) \ - ; \ - else \ +#define dgRTLOG() \ + if (1) \ + ; \ + else \ __null_stream() #endif diff --git a/include/dynamic-graph/signal-array.h b/include/dynamic-graph/signal-array.h index 1b4b282..fb7829a 100644 --- a/include/dynamic-graph/signal-array.h +++ b/include/dynamic-graph/signal-array.h @@ -10,128 +10,160 @@ #include <vector> #include <stdio.h> -namespace dynamicgraph { - -/// \ingroup dgraph -/// -/// \brief TODO -template <class Time> -class SignalArray_const { - public: - static const int DEFAULT_SIZE = 20; - - protected: - std::vector<const SignalBase<Time>*> const_array; - unsigned int size, rank; - - public: - SignalArray_const<Time>(const unsigned int& sizeARG = DEFAULT_SIZE) : const_array(sizeARG), size(sizeARG), rank(0) {} +namespace dynamicgraph +{ + + /// \ingroup dgraph + /// + /// \brief TODO + template <class Time> + class SignalArray_const + { + + public: + static const int DEFAULT_SIZE = 20; + + protected: + std::vector<const SignalBase<Time>*> const_array; + unsigned int size, rank; + + public: + SignalArray_const<Time>(const unsigned int& sizeARG = DEFAULT_SIZE) : + const_array(sizeARG), size(sizeARG), rank(0) {} + + SignalArray_const<Time>(const SignalBase<Time>& sig) : + const_array(DEFAULT_SIZE), size(DEFAULT_SIZE), rank(0) + { + addElmt(&sig); + } - SignalArray_const<Time>(const SignalBase<Time>& sig) : const_array(DEFAULT_SIZE), size(DEFAULT_SIZE), rank(0) { - addElmt(&sig); - } + SignalArray_const<Time>(const SignalArray<Time>& siga) + : const_array(siga.getSize()), + size(siga.getSize()), + rank(siga.getSize()) + { + for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i]; + } + + SignalArray_const<Time>(const SignalArray_const<Time>& siga) + : const_array(siga.getSize()), + size(siga.getSize()), + rank(siga.getSize()) + { + for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i]; + } + + virtual ~SignalArray_const<Time>() {} + + protected: + void addElmt(const SignalBase<Time>* el) + { + if (rank >= size) + { + size += DEFAULT_SIZE; + const_array.resize(size); + } + const_array[rank++] = el; + } - SignalArray_const<Time>(const SignalArray<Time>& siga) - : const_array(siga.getSize()), size(siga.getSize()), rank(siga.getSize()) { - for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i]; - } + public: + virtual SignalArray_const<Time>& operator<<(const SignalBase<Time>& sig) + { + addElmt(&sig); + return *this; + } - SignalArray_const<Time>(const SignalArray_const<Time>& siga) - : const_array(siga.getSize()), size(siga.getSize()), rank(siga.getSize()) { - for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i]; + public: + virtual const SignalBase<Time>& operator[](const unsigned int& idx) const + { return *const_array[idx]; } + virtual unsigned int getSize() const { return rank; } + }; + + template <class Time> + SignalArray_const<Time> operator<< + (const SignalBase<Time>& sig1, const SignalBase<Time>& sig2) + { + SignalArray_const<Time> res(sig1); + res << sig2; + return res; } - virtual ~SignalArray_const<Time>() {} - - protected: - void addElmt(const SignalBase<Time>* el) { - if (rank >= size) { - size += DEFAULT_SIZE; - const_array.resize(size); + /// \ingroup dgraph + /// + /// \brief TODO + template <class Time> + class SignalArray : public SignalArray_const<Time> { + public: + using SignalArray_const<Time>::DEFAULT_SIZE; + using SignalArray_const<Time>::size; + using SignalArray_const<Time>::rank; + + protected: + mutable std::vector<SignalBase<Time>*> array; + + public: + SignalArray<Time>(const unsigned int& sizeARG = DEFAULT_SIZE) : + SignalArray_const<Time>(0), array(sizeARG) + { + size = sizeARG; } - const_array[rank++] = el; - } - public: - virtual SignalArray_const<Time>& operator<<(const SignalBase<Time>& sig) { - addElmt(&sig); - return *this; - } - - public: - virtual const SignalBase<Time>& operator[](const unsigned int& idx) const { return *const_array[idx]; } - virtual unsigned int getSize() const { return rank; } -}; - -template <class Time> -SignalArray_const<Time> operator<<(const SignalBase<Time>& sig1, const SignalBase<Time>& sig2) { - SignalArray_const<Time> res(sig1); - res << sig2; - return res; -} - -/// \ingroup dgraph -/// -/// \brief TODO -template <class Time> -class SignalArray : public SignalArray_const<Time> { - public: - using SignalArray_const<Time>::DEFAULT_SIZE; - using SignalArray_const<Time>::size; - using SignalArray_const<Time>::rank; - - protected: - mutable std::vector<SignalBase<Time>*> array; - - public: - SignalArray<Time>(const unsigned int& sizeARG = DEFAULT_SIZE) : SignalArray_const<Time>(0), array(sizeARG) { - size = sizeARG; - } + SignalArray<Time>(SignalBase<Time>& sig) : + SignalArray_const<Time>(0), array(DEFAULT_SIZE) + { + size = DEFAULT_SIZE; + addElmt(&sig); + } - SignalArray<Time>(SignalBase<Time>& sig) : SignalArray_const<Time>(0), array(DEFAULT_SIZE) { - size = DEFAULT_SIZE; - addElmt(&sig); - } + SignalArray<Time>(const SignalArray<Time>& siga) : + SignalArray_const<Time>(siga.getSize()), array(siga.getSize()) + { + rank = siga.getSize(); + for (unsigned int i = 0; i < rank; ++i) array[i] = &siga[i]; + } - SignalArray<Time>(const SignalArray<Time>& siga) : SignalArray_const<Time>(siga.getSize()), array(siga.getSize()) { - rank = siga.getSize(); - for (unsigned int i = 0; i < rank; ++i) array[i] = &siga[i]; - } + virtual ~SignalArray<Time>() {} + + protected: + void addElmt(SignalBase<Time>* el) + { + if (rank >= size) + { + size += DEFAULT_SIZE; + array.resize(size); + } + array[rank++] = el; + } - virtual ~SignalArray<Time>() {} + public: + virtual SignalArray<Time>& operator<<(SignalBase<Time>& sig) + { + addElmt(&sig); + return *this; + } - protected: - void addElmt(SignalBase<Time>* el) { - if (rank >= size) { - size += DEFAULT_SIZE; - array.resize(size); + virtual SignalArray_const<Time> operator<< + (const SignalBase<Time>& sig) const + { + SignalArray_const<Time> res(*this); + res << sig; + return res; } - array[rank++] = el; - } - public: - virtual SignalArray<Time>& operator<<(SignalBase<Time>& sig) { - addElmt(&sig); - return *this; - } + virtual SignalBase<Time>& operator[] + (const unsigned int& idx) const + { return *array[idx]; } + }; - virtual SignalArray_const<Time> operator<<(const SignalBase<Time>& sig) const { - SignalArray_const<Time> res(*this); - res << sig; + template <class Time> + SignalArray<Time> operator<<(SignalBase<Time>& sig1, SignalBase<Time>& sig2) + { + SignalArray<Time> res(sig1); + res << sig2; return res; } - virtual SignalBase<Time>& operator[](const unsigned int& idx) const { return *array[idx]; } -}; - -template <class Time> -SignalArray<Time> operator<<(SignalBase<Time>& sig1, SignalBase<Time>& sig2) { - SignalArray<Time> res(sig1); - res << sig2; - return res; -} - -DYNAMIC_GRAPH_DLLAPI extern SignalArray<int> sotNOSIGNAL; + DYNAMIC_GRAPH_DLLAPI extern SignalArray<int> sotNOSIGNAL; } // end of namespace dynamicgraph. diff --git a/include/dynamic-graph/signal-base.h b/include/dynamic-graph/signal-base.h index 9d41c1c..3b3f9ba 100644 --- a/include/dynamic-graph/signal-base.h +++ b/include/dynamic-graph/signal-base.h @@ -1,6 +1,7 @@ // -*- mode: c++ -*- // Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse, // JRL, CNRS/AIST. +// LAAS, CNRS // #ifndef DYNAMIC_GRAPH_SIGNAL_BASE_H @@ -13,174 +14,214 @@ #include <dynamic-graph/fwd.hh> #include <dynamic-graph/exception-signal.h> -namespace dynamicgraph { - -/** \brief The base class for signals: not to be used as such. - - Signal values can be accessed programmatically using the access - () or accessCopy () methods; the former directly accesses the - value of the signal, which can involve an extra computation, - while the latter accesses a cached value, or 'copy'. -*/ -template <class Time> -class SignalBase : public boost::noncopyable { - public: - explicit SignalBase(std::string name = "") : name(name), signalTime(0), ready(false) {} - - virtual ~SignalBase() {} - - /// \name Time - /// \{ - virtual const Time& getTime() const { return signalTime; } - - virtual void setTime(const Time& t) { signalTime = t; } - - const bool& getReady() const { return ready; } - - const std::string& getName() const { return name; } - - void getClassName(std::string& aClassName) const { aClassName = typeid(this).name(); } - - virtual void setPeriodTime(const Time&) {} - - virtual Time getPeriodTime() const { return 1; } - - /// \} - - /// \name Dependencies - /// \{ - - virtual void addDependency(const SignalBase<Time>&) {} - - virtual void removeDependency(const SignalBase<Time>&) {} - - virtual void clearDependencies() {} - - virtual bool needUpdate(const Time&) const { return ready; } - - inline void setReady(const bool sready = true) { ready = sready; } - - virtual std::ostream& writeGraph(std::ostream& os) const { return os; } - - virtual std::ostream& displayDependencies(std::ostream& os, const int = -1, std::string space = "", - std::string next1 = "", std::string = "") const { - os << space << next1 << "-- "; - display(os); - return os; - } - - /// \} - - /// \name Plug - /// \{ - - /* Plug the arg-signal on the <this> object. Plug-in is always - * a descending operation (the actual <this> object will call the arg-signal - * and not the opposite). - */ - virtual void plug(SignalBase<Time>* sigarg) { - DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Plug-in operation not possible with this signal. ", - "(while trying to plug %s on %s).", sigarg->getName().c_str(), this->getName().c_str()); - } - - virtual void unplug() { - DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Plug-in operation not possible with this signal. ", - "(while trying to unplug %s).", this->getName().c_str()); - } - - virtual bool isPlugged() const { return false; } +namespace dynamicgraph +{ + + /** \brief The base class for signals: not to be used as such. + + Signal values can be accessed programmatically using the access + () or accessCopy () methods; the former directly accesses the + value of the signal, which can involve an extra computation, + while the latter accesses a cached value, or 'copy'. + */ + template <class Time> + class SignalBase : public boost::noncopyable + { + public: + explicit SignalBase(std::string name = "") : + name(name), signalTime(0), ready(false) {} + + virtual ~SignalBase() {} + + /// \name Time + /// \{ + virtual const Time& getTime() const { return signalTime; } + + virtual void setTime(const Time& t) { signalTime = t; } + + const bool& getReady() const { return ready; } + + const std::string& getName() const { return name; } + + void getClassName(std::string& aClassName) const + { aClassName = typeid(this).name(); } + + virtual void setPeriodTime(const Time&) {} + + virtual Time getPeriodTime() const { return 1; } + + /// \} + + /// \name Dependencies + /// \{ + + virtual void addDependency(const SignalBase<Time>&) {} + + virtual void removeDependency(const SignalBase<Time>&) {} + + virtual void clearDependencies() {} + + virtual bool needUpdate(const Time&) const { return ready; } + + inline void setReady(const bool sready = true) { ready = sready; } + + virtual std::ostream& writeGraph(std::ostream& os) const { return os; } + + virtual std::ostream& displayDependencies + (std::ostream& os, const int = -1, std::string space = "", + std::string next1 = "", std::string = "") const + { + os << space << next1 << "-- "; + display(os); + return os; + } - virtual SignalBase<Time>* getPluged() const { return NULL; } + /// \} + + /// \name Plug + /// \{ + + /* Plug the arg-signal on the <this> object. Plug-in is always + * a descending operation (the actual <this> object will call the arg-signal + * and not the opposite). + */ + virtual void plug(SignalBase<Time>* sigarg) + { + DG_THROW ExceptionSignal + (ExceptionSignal::PLUG_IMPOSSIBLE, + "Plug-in operation not possible with this signal. ", + "(while trying to plug %s on %s).", + sigarg->getName().c_str(), this->getName().c_str()); + } + + virtual void unplug() + { + DG_THROW ExceptionSignal + (ExceptionSignal::PLUG_IMPOSSIBLE, + "Plug-in operation not possible with this signal. ", + "(while trying to unplug %s).", this->getName().c_str()); + } - virtual void setConstantDefault() { - DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Plug-in operation not possible with this signal. ", - "(while trying to save %s).", this->getName().c_str()); - } + virtual bool isPlugged() const { return false; } - /// \} + virtual SignalBase<Time>* getPluged() const { return NULL; } - /// \name Set - /// \{ + virtual void setConstantDefault() + { + DG_THROW ExceptionSignal + (ExceptionSignal::PLUG_IMPOSSIBLE, + "Plug-in operation not possible with this signal. ", + "(while trying to save %s).", this->getName().c_str()); + } - /* Generic set function. Should be reimplemented by the specific - * Signal. Sets a signal value - */ - virtual void set(std::istringstream&) { - DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "Set operation not possible with this signal. ", - "(while trying to set %s).", this->getName().c_str()); - } + /// \} - virtual void get(std::ostream&) const { - DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "Get operation not possible with this signal. ", - "(while trying to get %s).", this->getName().c_str()); - } + /// \name Set + /// \{ - virtual inline void recompute(const Time&) { - DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "Recompute operation not possible with this signal. ", - "(while trying to recompute %s).", this->getName().c_str()); - } + /* Generic set function. Should be reimplemented by the specific + * Signal. Sets a signal value + */ + virtual void set(std::istringstream&) + { + DG_THROW ExceptionSignal + (ExceptionSignal::SET_IMPOSSIBLE, + "Set operation not possible with this signal. ", + "(while trying to set %s).", this->getName().c_str()); + } + + virtual void get(std::ostream&) const + { + DG_THROW ExceptionSignal + (ExceptionSignal::SET_IMPOSSIBLE, + "Get operation not possible with this signal. ", + "(while trying to get %s).", this->getName().c_str()); + } - virtual void trace(std::ostream&) const { - DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "Trace operation not possible with this signal. ", - "(while trying to trace %s).", this->getName().c_str()); - } + virtual inline void recompute(const Time&) + { + DG_THROW ExceptionSignal + (ExceptionSignal::SET_IMPOSSIBLE, + "Recompute operation not possible with this signal. ", + "(while trying to recompute %s).", this->getName().c_str()); + } - /// \} + virtual void trace(std::ostream&) const + { + DG_THROW ExceptionSignal + (ExceptionSignal::SET_IMPOSSIBLE, + "Trace operation not possible with this signal. ", + "(while trying to trace %s).", + this->getName().c_str()); + } - /// \name Display - /// \{ + /// \} - virtual std::ostream& display(std::ostream& os) const { - os << "Sig:" << name; - return os; - } + /// \name Display + /// \{ - std::string shortName() const { - std::istringstream iss(name); - const int SIZE = 128; - char buffer[SIZE]; - while (iss.good()) { - iss.getline(buffer, SIZE, ':'); + virtual std::ostream& display(std::ostream& os) const + { + os << "Sig:" << name; + return os; } - const std::string res(buffer); - return res; - } - /// \} - /// \name Information providers - /// \{ - - virtual void ExtractNodeAndLocalNames(std::string& LocalName, std::string& NodeName) const { - std::string fullname = this->getName(); - - size_t IdxPosLocalName = fullname.rfind(":"); - LocalName = fullname.substr(IdxPosLocalName + 1, fullname.length() - IdxPosLocalName + 1); - size_t IdxPosNodeNameStart = fullname.find("("); - size_t IdxPosNodeNameEnd = fullname.find(")"); - NodeName = fullname.substr(IdxPosNodeNameStart + 1, IdxPosNodeNameEnd - IdxPosNodeNameStart - 1); - } + std::string shortName() const + { + std::istringstream iss(name); + const int SIZE = 128; + char buffer[SIZE]; + while (iss.good()) + { + iss.getline(buffer, SIZE, ':'); + } + const std::string res(buffer); + return res; + } + /// \} + + /// \name Information providers + /// \{ + + virtual void ExtractNodeAndLocalNames + (std::string& LocalName, std::string& NodeName) const + { + std::string fullname = this->getName(); + + size_t IdxPosLocalName = fullname.rfind(":"); + LocalName = fullname.substr(IdxPosLocalName + 1, + fullname.length() - IdxPosLocalName + 1); + size_t IdxPosNodeNameStart = fullname.find("("); + size_t IdxPosNodeNameEnd = fullname.find(")"); + NodeName = fullname.substr(IdxPosNodeNameStart + 1, + IdxPosNodeNameEnd - IdxPosNodeNameStart - 1); + } - /// \} + /// \} - /// \name Test - /// \{ - virtual void checkCompatibility() { - DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Abstract signal not compatible with anything.", - "(while trying to plug <%s>).", this->getName().c_str()); + /// \name Test + /// \{ + virtual void checkCompatibility() + { + DG_THROW ExceptionSignal + (ExceptionSignal::PLUG_IMPOSSIBLE, + "Abstract signal not compatible with anything.", + "(while trying to plug <%s>).", this->getName().c_str()); + } + /// \} + + protected: + std::string name; + Time signalTime; + bool ready; + }; + + /// Forward to a virtual fonction. + template <class Time> + std::ostream& operator<<(std::ostream& os, const SignalBase<Time>& sig) + { + return sig.display(os); } - /// \} - - protected: - std::string name; - Time signalTime; - bool ready; -}; - -/// Forward to a virtual fonction. -template <class Time> -std::ostream& operator<<(std::ostream& os, const SignalBase<Time>& sig) { - return sig.display(os); -} } // end of namespace dynamicgraph. #endif //! DYNAMIC_GRAPH_SIGNAL_BASE_H diff --git a/include/dynamic-graph/signal-cast-helper.h b/include/dynamic-graph/signal-cast-helper.h index 89784ae..3673926 100644 --- a/include/dynamic-graph/signal-cast-helper.h +++ b/include/dynamic-graph/signal-cast-helper.h @@ -1,5 +1,6 @@ // -*- c++-mode -*- -// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse, Nicolas Mansard +// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse, +// Nicolas Mansard // #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH @@ -21,71 +22,80 @@ #include "dynamic-graph/exception-signal.h" #include "dynamic-graph/signal-caster.h" -namespace dynamicgraph { - -/* --- NON GENERIC CASTER ------------------------------------------------- */ - -/// This class can be used to register default casts, i.e. casts -/// already supported by the object to an std::iostream through the -/// operators >> and << . -template <typename T> -class DefaultCastRegisterer : public SignalCastRegisterer { - public: - DefaultCastRegisterer() : SignalCastRegisterer(typeid(T), disp, cast, trace) {} - - static boost::any cast(std::istringstream& iss); - - static void disp(const boost::any& object, std::ostream& os) { os << boost::any_cast<T>(object) << std::endl; } - - static void trace(const boost::any& object, std::ostream& os) { disp(object, os); } -}; - -/// A default version of the caster, to serialize directly from -/// std::in. -template <typename T> -boost::any DefaultCastRegisterer<T>::cast(std::istringstream& iss) { - T inst; - iss >> inst; - if (iss.fail()) { - boost::format fmt("failed to serialize %s "); - fmt % iss.str(); - throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); +namespace dynamicgraph +{ + + /* --- NON GENERIC CASTER ------------------------------------------------- */ + + /// This class can be used to register default casts, i.e. casts + /// already supported by the object to an std::iostream through the + /// operators >> and << . + template <typename T> + class DefaultCastRegisterer : public SignalCastRegisterer { + public: + DefaultCastRegisterer() : SignalCastRegisterer(typeid(T), disp, cast, trace) + {} + + static boost::any cast(std::istringstream& iss); + + static void disp(const boost::any& object, std::ostream& os) + { os << boost::any_cast<T>(object) << std::endl; } + + static void trace(const boost::any& object, std::ostream& os) + { disp(object, os); } + }; + + /// A default version of the caster, to serialize directly from + /// std::in. + template <typename T> + boost::any DefaultCastRegisterer<T>::cast(std::istringstream& iss) + { + T inst; + iss >> inst; + if (iss.fail()) { + boost::format fmt("failed to serialize %s "); + fmt % iss.str(); + throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str()); + } + return inst; } - return inst; -} -/* --- GENERIC CASTER ----------------------------------------------------- */ -/*! - * This class is only used to group together static functions who differ by - * a template parameter. It is never actually instanced (the private constructor - * makes sure of that). - * Typical use of this class is to add the caster in the dg graph: - * dynamicgraph::SignalCastRegisterer sotCastRegisterer_TYPE - * (typeid(TYPE), - * SignalCast<TYPE>::disp_, - * SignalCast<TYPE>::cast_, - * SignalCast<TYPE>::trace_); - - * NMSD: I don't really understand the use of this additional class. IMHO - * (comme on dit), it should be possible to rewrite the same-spec macros - * using specialization of the template class DefaultCastRegisterer. No? - */ -template <class T> -class SignalCast { - public: - static T cast(std::istringstream&) { throw 1; } - static void disp(const T&, std::ostream&) { throw 1; } - static void trace(const T& t, std::ostream& os) { disp(t, os); } - - public: - // adapter functions for SignalCast - static boost::any cast_(std::istringstream& stringValue) { return boost::any_cast<T>(cast(stringValue)); } - static void disp_(const boost::any& t, std::ostream& os) { disp(boost::any_cast<T>(t), os); } - static void trace_(const boost::any& t, std::ostream& os) { trace(boost::any_cast<T>(t), os); } - - private: - SignalCast() {} -}; + /* --- GENERIC CASTER ----------------------------------------------------- */ + /*! + * This class is only used to group together static functions who differ by + * a template parameter. It is never actually instanced + * (the private constructor + * makes sure of that). + * Typical use of this class is to add the caster in the dg graph: + * dynamicgraph::SignalCastRegisterer sotCastRegisterer_TYPE + * (typeid(TYPE), + * SignalCast<TYPE>::disp_, + * SignalCast<TYPE>::cast_, + * SignalCast<TYPE>::trace_); + + * NMSD: I don't really understand the use of this additional class. IMHO + * (comme on dit), it should be possible to rewrite the same-spec macros + * using specialization of the template class DefaultCastRegisterer. No? + */ + template <class T> + class SignalCast { + public: + static T cast(std::istringstream&) { throw 1; } + static void disp(const T&, std::ostream&) { throw 1; } + static void trace(const T& t, std::ostream& os) { disp(t, os); } + + public: + // adapter functions for SignalCast + static boost::any cast_(std::istringstream& stringValue) + { return boost::any_cast<T>(cast(stringValue)); } + static void disp_(const boost::any& t, std::ostream& os) + { disp(boost::any_cast<T>(t), os); } + static void trace_(const boost::any& t, std::ostream& os) + { trace(boost::any_cast<T>(t), os); } + + private: + SignalCast() {} + }; } // namespace dynamicgraph @@ -97,79 +107,88 @@ class SignalCast { * order for casts to be registered. */ -#define DG_SIGNAL_CAST_DECLARATION(TYPE) \ - ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##TYPE(typeid(TYPE), SignalCast<TYPE>::disp_, \ - SignalCast<TYPE>::cast_, SignalCast<TYPE>::trace_) - -#define DG_SIGNAL_CAST_DECLARATION_NAMED(TYPE, NAME) \ - ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##NAME(typeid(TYPE), SignalCast<TYPE>::disp_, \ - SignalCast<TYPE>::cast_, SignalCast<TYPE>::trace_) - -/* Standard definition macros: the three functions can be specified - * in the macros. To define then in the cpp, just put ';' in the args. - */ -#define DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, CAST, DISP, TRACE) \ - template <> \ - class SignalCast<TYPE> { \ - public: \ - static TYPE cast(std::istringstream& iss) CAST static void disp(TYPE const& t, std::ostream& os) DISP \ - static void trace(TYPE const& t, std::ostream& os) TRACE public : static boost::any \ - cast_(std::istringstream& stringValue) { \ - return boost::any_cast<TYPE>(cast(stringValue)); \ - } \ - static void disp_(const boost::any& t, std::ostream& os) { disp(boost::any_cast<TYPE>(t), os); } \ - static void trace_(const boost::any& t, std::ostream& os) { trace(boost::any_cast<TYPE>(t), os); } \ - } +#define DG_SIGNAL_CAST_DECLARATION(TYPE) \ + ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##TYPE \ + (typeid(TYPE), SignalCast<TYPE>::disp_, \ + SignalCast<TYPE>::cast_, SignalCast<TYPE>::trace_) + +#define DG_SIGNAL_CAST_DECLARATION_NAMED(TYPE, NAME) \ + ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##NAME \ + (typeid(TYPE), SignalCast<TYPE>::disp_, \ + SignalCast<TYPE>::cast_, SignalCast<TYPE>::trace_) + + /* Standard definition macros: the three functions can be specified + * in the macros. To define then in the cpp, just put ';' in the args. + */ +#define DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, CAST, DISP, TRACE) \ + template <> \ + class SignalCast<TYPE> { \ + public: \ + static TYPE cast(std::istringstream& iss) CAST \ + static void disp(TYPE const& t, std::ostream& os) DISP \ + static void trace(TYPE const& t, std::ostream& os) TRACE \ + public : static boost::any \ + cast_(std::istringstream& stringValue) \ + { \ + return boost::any_cast<TYPE>(cast(stringValue)); \ +} \ +static void disp_(const boost::any& t, std::ostream& os) \ +{ disp(boost::any_cast<TYPE>(t), os); } \ +static void trace_(const boost::any& t, std::ostream& os) \ +{ trace(boost::any_cast<TYPE>(t), os); } \ +} /* Standard definition macros: the functions <cast> and <disp> have * to be implemented in the cpp files. The function <trace> is * implemented as a proxy on <disp>. */ -#define DG_SIGNAL_CAST_DEFINITION_HPP(TYPE) DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, ;, ;, { disp(t, os); }) +#define DG_SIGNAL_CAST_DEFINITION_HPP(TYPE) \ + DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, ;, ;, { disp(t, os); }) /* Lazy definition: <cast> and <disp> are to proxys on the standard * std input (>>) and output (<<). The function <trace> has to be * implemented in the cpp. */ -#define DG_SIGNAL_CAST_DEFINITION_TRACE_HPP(TYPE, TRACE) \ - DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \ - { \ - TYPE res; \ - iss >> res; \ - return res; \ - }, \ +#define DG_SIGNAL_CAST_DEFINITION_TRACE_HPP(TYPE, TRACE) \ + DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \ + { \ + TYPE res; \ + iss >> res; \ + return res; \ + }, \ { os << t << std::endl; }, TRACE) /* Lazy lazy definition: the three functions are implemented as * proxys on std::io operation. */ -#define DG_SIGNAL_CAST_DEFINITION(TYPE) \ - DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \ - { \ - TYPE res; \ - iss >> res; \ - return res; \ - }, \ +#define DG_SIGNAL_CAST_DEFINITION(TYPE) \ + DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \ + { \ + TYPE res; \ + iss >> res; \ + return res; \ + }, \ { os << t << std::endl; }, { disp(t, os); }) /* Lazy definition of <cast> and <disp> with implementation of * <trace> in the cpp. */ -#define DG_SIGNAL_CAST_DEFINITION_TRACE(TYPE) \ - DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \ - { \ - TYPE res; \ - iss >> res; \ - return res; \ - }, \ - { os << t << std::endl; }, \ +#define DG_SIGNAL_CAST_DEFINITION_TRACE(TYPE) \ + DG_SIGNAL_CAST_FULL_DEFINITION(TYPE, \ + { \ + TYPE res; \ + iss >> res; \ + return res; \ + }, \ + { os << t << std::endl; }, \ ;) /* Macro to add the define SignalCast in the dg graph. Typical use is: * DG_ADD_CASTER( Matrix,matrix ) */ -#define DG_ADD_CASTER(TYPE, ID) \ - ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##ID(typeid(TYPE), SignalCast<TYPE>::disp_, \ - SignalCast<TYPE>::cast_, SignalCast<TYPE>::trace_) +#define DG_ADD_CASTER(TYPE, ID) \ + ::dynamicgraph::SignalCastRegisterer sotCastRegisterer_##ID \ + (typeid(TYPE), SignalCast<TYPE>::disp_, \ + SignalCast<TYPE>::cast_, SignalCast<TYPE>::trace_) #endif // #ifndef DYNAMIC_GRAPH_SIGNAL_CASTER_HELPER_HH diff --git a/include/dynamic-graph/signal-caster.h b/include/dynamic-graph/signal-caster.h index 35ce044..982ef3c 100644 --- a/include/dynamic-graph/signal-caster.h +++ b/include/dynamic-graph/signal-caster.h @@ -18,97 +18,110 @@ #include <dynamic-graph/dynamic-graph-api.h> #include "dynamic-graph/exception-signal.h" -namespace dynamicgraph { -/// This singleton class allows serialization of a number of objects into -/// (disp) and from (cast) std i/o streams. -/// -/// The transformation is done at run-time, i.e. SignalCaster -/// doesn't know about the type of objects it casts to. -/// -/// It also allows registering of user-defined casts. A cast is -/// identified by the compiler. The mapping from a type to a -/// serialization function is dynamic, hence it is more complex than -/// a typical template-based compile-time resolve. So disp, cast and -/// trace are costly functions and should be used as such. -class DYNAMIC_GRAPH_DLLAPI SignalCaster { - public: - virtual ~SignalCaster(); - /// Destroy the unique instance. - static void destroy(); - /// Typedef of displayer functions that take an encapsulated 'any' - /// object and displays, cast, or trace it on an output stream - /// (serialization). - typedef boost::function2<void, const boost::any&, std::ostream&> displayer_type; - typedef boost::function1<boost::any, std::istringstream&> caster_type; - typedef boost::function2<void, const boost::any&, std::ostream&> tracer_type; +namespace dynamicgraph +{ + /// This singleton class allows serialization of a number of objects into + /// (disp) and from (cast) std i/o streams. + /// + /// The transformation is done at run-time, i.e. SignalCaster + /// doesn't know about the type of objects it casts to. + /// + /// It also allows registering of user-defined casts. A cast is + /// identified by the compiler. The mapping from a type to a + /// serialization function is dynamic, hence it is more complex than + /// a typical template-based compile-time resolve. So disp, cast and + /// trace are costly functions and should be used as such. + class DYNAMIC_GRAPH_DLLAPI SignalCaster + { + public: + virtual ~SignalCaster(); + /// Destroy the unique instance. + static void destroy(); + /// Typedef of displayer functions that take an encapsulated 'any' + /// object and displays, cast, or trace it on an output stream + /// (serialization). + typedef boost::function2<void, const boost::any&, std::ostream&> + displayer_type; + typedef boost::function1<boost::any, std::istringstream&> + caster_type; + typedef boost::function2<void, const boost::any&, std::ostream&> + tracer_type; - /// Get a reference to the unique object of the class. - static SignalCaster* getInstance(void); - /// Displays an object using a registered displayer function. - void disp(const boost::any& object, std::ostream& os); - /// Traces an object using a registered trace function. - void trace(const boost::any& object, std::ostream& os); - /// Casts an object using a registered cast function. - boost::any cast(const std::type_info&, std::istringstream& iss); - /// Registers a cast. - void registerCast(const std::type_info& type, displayer_type displayer, caster_type caster, tracer_type tracer); - /// Unregister a cast. - void unregisterCast(const std::type_info& type); - /// Checks if there is a displayer registered with type_name. - bool existsCast(const std::type_info& type) const; - /// Return the list of type names registered. - std::vector<std::string> listTypenames() const; + /// Get a reference to the unique object of the class. + static SignalCaster* getInstance(void); + /// Displays an object using a registered displayer function. + void disp(const boost::any& object, std::ostream& os); + /// Traces an object using a registered trace function. + void trace(const boost::any& object, std::ostream& os); + /// Casts an object using a registered cast function. + boost::any cast(const std::type_info&, std::istringstream& iss); + /// Registers a cast. + void registerCast(const std::type_info& type, + displayer_type displayer, + caster_type caster, + tracer_type tracer); + /// Unregister a cast. + void unregisterCast(const std::type_info& type); + /// Checks if there is a displayer registered with type_name. + bool existsCast(const std::type_info& type) const; + /// Return the list of type names registered. + std::vector<std::string> listTypenames() const; - private: - /// Container for the three cast functions. - typedef boost::tuple<displayer_type, caster_type, tracer_type> cast_functions_type; + private: + /// Container for the three cast functions. + typedef boost::tuple<displayer_type, caster_type, tracer_type> + cast_functions_type; - /// \brief Retrieve cast structure from its name. - cast_functions_type& getCast(const std::string& type_name); + /// \brief Retrieve cast structure from its name. + cast_functions_type& getCast(const std::string& type_name); - /// This map associates the typename of objects and the corresponding - /// using boost::function with 'compatible' syntax - std::map<std::string, cast_functions_type> functions_; + /// This map associates the typename of objects and the corresponding + /// using boost::function with 'compatible' syntax + std::map<std::string, cast_functions_type> functions_; - std::map<std::string, const std::type_info*> type_info_; + std::map<std::string, const std::type_info*> type_info_; - private: - explicit SignalCaster(); - /// Pointer to the unique instance of the class. - static SignalCaster* instance_; -}; + private: + explicit SignalCaster(); + /// Pointer to the unique instance of the class. + static SignalCaster* instance_; + }; -/// The SignalCast registerer class. Can be used to automatically -/// register a cast when instanced somewhere in a cpp file. Pass the -/// typeid () of the type you want to register a cast to as the first -/// argument. The code is provided here so the class does not need -/// to be exported. -class DYNAMIC_GRAPH_DLLAPI SignalCastRegisterer { - public: - inline SignalCastRegisterer(const std::type_info& type, SignalCaster::displayer_type displayer, - SignalCaster::caster_type caster, SignalCaster::tracer_type tracer) { - SignalCaster::getInstance()->registerCast(type, displayer, caster, tracer); + /// The SignalCast registerer class. Can be used to automatically + /// register a cast when instanced somewhere in a cpp file. Pass the + /// typeid () of the type you want to register a cast to as the first + /// argument. The code is provided here so the class does not need + /// to be exported. + class DYNAMIC_GRAPH_DLLAPI SignalCastRegisterer { + public: + inline SignalCastRegisterer(const std::type_info& type, + SignalCaster::displayer_type displayer, + SignalCaster::caster_type caster, + SignalCaster::tracer_type tracer) + { + SignalCaster::getInstance()->registerCast(type, displayer, caster, tracer); } -}; + }; -/// Global signal cast template (helper) functions -/// -/// Using these avoid using the typeid () operator and keeps the -/// implementation details hidden. -template <typename T> -void signal_disp(const T& value, std::ostream& os) { - SignalCaster::getInstance()->disp(value, os); -} + /// Global signal cast template (helper) functions + /// + /// Using these avoid using the typeid () operator and keeps the + /// implementation details hidden. + template <typename T> + void signal_disp(const T& value, std::ostream& os) { + SignalCaster::getInstance()->disp(value, os); + } -template <typename T> -T signal_cast(std::istringstream& iss) { - return boost::any_cast<T>(SignalCaster::getInstance()->cast(typeid(T), iss)); -} + template <typename T> + T signal_cast(std::istringstream& iss) { + return boost::any_cast<T>(SignalCaster::getInstance()-> + cast(typeid(T), iss)); + } -template <typename T> -void signal_trace(const T& value, std::ostream& os) { - SignalCaster::getInstance()->trace(value, os); -} + template <typename T> + void signal_trace(const T& value, std::ostream& os) { + SignalCaster::getInstance()->trace(value, os); + } } // end of namespace dynamicgraph. #endif //! DYNAMIC_GRAPH_SIGNAL_CASTER_HH diff --git a/include/dynamic-graph/signal-helper.h b/include/dynamic-graph/signal-helper.h index db69bb2..dfd22f3 100644 --- a/include/dynamic-graph/signal-helper.h +++ b/include/dynamic-graph/signal-helper.h @@ -19,21 +19,28 @@ /* --- MACROS ---------------------------------------------------------- */ #define SIGNAL_OUT_FUNCTION_NAME(name) name##SOUT_function -#define DECLARE_SIGNAL(name, IO, type) ::dynamicgraph::Signal<type, int> m_##name##S##IO +#define DECLARE_SIGNAL(name, IO, type) \ + ::dynamicgraph::Signal<type, int> m_##name##S##IO #define CONSTRUCT_SIGNAL(name, IO, type) \ - m_##name##S##IO(getClassName() + "(" + getName() + ")::" + #IO + "put(" + #type + ")::" + #name) + m_##name##S##IO(getClassName() + "(" + getName() + ")::" \ + + #IO + "put(" + #type + ")::" + #name) #define BIND_SIGNAL_TO_FUNCTION(name, IO, type) \ - m_##name##S##IO.setFunction(boost::bind(&EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name), this, _1, _2)); + m_##name##S##IO.setFunction \ + (boost::bind(&EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name), \ + this, _1, _2)); /**/ -#define DECLARE_SIGNAL_IN(name, type) ::dynamicgraph::SignalPtr<type, int> m_##name##SIN +#define DECLARE_SIGNAL_IN(name, type) \ + ::dynamicgraph::SignalPtr<type, int> m_##name##SIN #define CONSTRUCT_SIGNAL_IN(name, type) \ - m_##name##SIN(NULL, getClassName() + "(" + getName() + ")::input(" + #type + ")::" + #name) + m_##name##SIN(NULL, getClassName() + "(" + getName() + \ + ")::input(" + #type + ")::" + #name) /**/ -#define DECLARE_SIGNAL_OUT_FUNCTION(name, type) type& SIGNAL_OUT_FUNCTION_NAME(name)(type&, int) +#define DECLARE_SIGNAL_OUT_FUNCTION(name, type) \ + type& SIGNAL_OUT_FUNCTION_NAME(name)(type&, int) #define DEFINE_SIGNAL_OUT_FUNCTION(name, type) \ type& EntityClassName::SIGNAL_OUT_FUNCTION_NAME(name)(type & s, int iter) @@ -47,14 +54,17 @@ protected: \ type& SIGNAL_OUT_FUNCTION(name)(type&, int) -#define CONSTRUCT_SIGNAL_OUT(name, type, dep) \ - m_##name##SOUT(boost::bind(&EntityClassName::name##SOUT_function, this, _1, _2), dep, \ - getClassName() + "(" + getName() + ")::output(" + #type + ")::" + #name) +#define CONSTRUCT_SIGNAL_OUT(name, type, dep) \ + m_##name##SOUT(boost::bind(&EntityClassName::name##SOUT_function, \ + this, _1, _2), dep, \ + getClassName() + "(" + getName() + \ + ")::output(" + #type + ")::" + #name) /**************** INNER SIGNALS *******************/ #define SIGNAL_INNER_FUNCTION_NAME(name) name##SINNER_function -#define DECLARE_SIGNAL_INNER_FUNCTION(name, type) type& SIGNAL_INNER_FUNCTION_NAME(name)(type&, int) +#define DECLARE_SIGNAL_INNER_FUNCTION(name, type) type& \ + SIGNAL_INNER_FUNCTION_NAME(name)(type&, int) #define DEFINE_SIGNAL_INNER_FUNCTION(name, type) \ type& EntityClassName::SIGNAL_INNER_FUNCTION_NAME(name)(type & s, int iter) @@ -66,8 +76,10 @@ protected: \ DECLARE_SIGNAL_INNER_FUNCTION(name, type) -#define CONSTRUCT_SIGNAL_INNER(name, type, dep) \ - m_##name##SINNER(boost::bind(&EntityClassName::name##SINNER_function, this, _1, _2), dep, \ - getClassName() + "(" + getName() + ")::inner(" + #type + ")::" + #name) +#define CONSTRUCT_SIGNAL_INNER(name, type, dep) \ + m_##name##SINNER(boost::bind \ + (&EntityClassName::name##SINNER_function, this, _1, _2), dep, \ + getClassName() + "(" + getName() + ")::inner(" + #type + ")::" \ + + #name) #endif // __dynamic_graph_signal_helper_H__ diff --git a/include/dynamic-graph/signal-ptr.h b/include/dynamic-graph/signal-ptr.h index e475947..30894bb 100644 --- a/include/dynamic-graph/signal-ptr.h +++ b/include/dynamic-graph/signal-ptr.h @@ -11,124 +11,139 @@ #include <dynamic-graph/deprecated.hh> -namespace dynamicgraph { -/// \ingroup dgraph -/// -/// \brief This is the only type of signal that can be plugged to, -/// using the plug () command. -/// -/// In that sense, when plugged into, it acts as a "pointer" to the -/// input signal, hence the name. Operator -> is also overloaded and -/// can be used to access the pointed signal. -template <class T, class Time> -class SignalPtr : public virtual Signal<T, Time> { - public: - using SignalBase<Time>::getName; - - protected: - Signal<T, Time>* signalPtr; - bool modeNoThrow; - bool transmitAbstract; - SignalBase<Time>* abstractTransmitter; - T* transmitAbstractData; - - inline bool autoref() const { return signalPtr == this; } - - public: /* --- CONSTRUCTORS --- */ - SignalPtr(Signal<T, Time>* ptr, std::string name = "") +namespace dynamicgraph +{ + /// \ingroup dgraph + /// + /// \brief This is the only type of signal that can be plugged to, + /// using the plug () command. + /// + /// In that sense, when plugged into, it acts as a "pointer" to the + /// input signal, hence the name. Operator -> is also overloaded and + /// can be used to access the pointed signal. + template <class T, class Time> + class SignalPtr : public virtual Signal<T, Time> + { + public: + using SignalBase<Time>::getName; + + protected: + Signal<T, Time>* signalPtr; + bool modeNoThrow; + bool transmitAbstract; + SignalBase<Time>* abstractTransmitter; + T* transmitAbstractData; + + inline bool autoref() const { return signalPtr == this; } + + public: /* --- CONSTRUCTORS --- */ + SignalPtr(Signal<T, Time>* ptr, std::string name = "") : Signal<T, Time>(name), signalPtr(ptr), modeNoThrow(false), transmitAbstract(false), abstractTransmitter(NULL) {} - virtual ~SignalPtr() { signalPtr = NULL; } - - public: /* --- PLUG-IN OPERATION --- */ - Signal<T, Time>* getPtr(); // throw - const Signal<T, Time>* getPtr() const; // throw - SignalBase<Time>* getAbstractPtr(); // throw - const SignalBase<Time>* getAbstractPtr() const; // throw - virtual void plug(SignalBase<Time>* ref); - - virtual void unplug() { plug(NULL); } - - virtual bool isPlugged() const { return (NULL != signalPtr); } - virtual SignalBase<Time>* getPluged() const { return signalPtr; } - virtual bool isAbstractPluged() const; - virtual const Time& getTime() const; - - /* Equivalent operator-like definitions. */ - inline Signal<T, Time>* operator->() { return getPtr(); } - inline const Signal<T, Time>* operator->() const { return getPtr(); } - inline Signal<T, Time>& operator*() { return *getPtr(); } - inline const Signal<T, Time>& operator*() const { return *getPtr(); } - inline operator bool() const { return isPlugged(); } - - public: /* --- INHERITANCE --- */ - virtual bool needUpdate(const Time& t) const; - virtual std::ostream& writeGraph(std::ostream& os) const; - virtual std::ostream& display(std::ostream& os) const; - - /* For compatibility, .access () is equivalent to ->access (). For explicit - * pointer dereference : - * Prefere -> () to () - */ - virtual const T& operator()(const Time& t); - /* Similarly, Prefere ->access to .access - */ - virtual const T& access(const Time& t); - virtual const T& accessCopy() const; - - inline void setConstantDefault(const T& t) { - Signal<T, Time>::setConstant(t); - modeNoThrow = true; - } - virtual inline void setConstantDefault() { setConstantDefault(accessCopy()); } - inline void unsetConstantDefault() { modeNoThrow = false; } - - virtual void checkCompatibility(); - - public: /* --- INHERITANCE --- */ - /* SignalPtr could be used as a classical signal, through the normal - * setting functions. The behavior is to plugged the signalPtr on - * the classical mother Signal layer of the object. - */ - virtual void setConstant(const T& t) { - plug(this); - Signal<T, Time>::setConstant(t); - } - virtual void setReference(const T* t, typename Signal<T, Time>::Mutex* m = NULL) { - plug(this); - Signal<T, Time>::setReference(t, m); - } - virtual void setFunction(boost::function2<T&, T&, Time> t, typename Signal<T, Time>::Mutex* m = NULL) { - plug(this); - Signal<T, Time>::setFunction(t, m); - } - - /* template< class Provider > */ - /* void setFunction( T& (Provider::*fun)(Time,T&),Provider& obj, */ - /* boost::try_mutex *mutexref=NULL ) */ - /* { plug(this); Signal<T,Time>::setFunction(fun,obj,mutexref); } */ - - virtual inline Signal<T, Time>& operator=(const T& t) { - setConstant(t); - return *this; - } - - virtual std::ostream& displayDependencies(std::ostream& os, const int depth = -1, std::string space = "", - std::string next1 = "", std::string next2 = "") const; - - protected: // Interdiction of the rest of the heritage - using Signal<T, Time>::addDependency; - virtual void addDependency() {} - using Signal<T, Time>::removeDependency; - virtual void removeDependency() {} - virtual void clearDependencies() {} -}; + virtual ~SignalPtr() { signalPtr = NULL; } + + public: + /* --- PLUG-IN OPERATION --- */ + Signal<T, Time>* getPtr(); // throw + const Signal<T, Time>* getPtr() const; // throw + SignalBase<Time>* getAbstractPtr(); // throw + const SignalBase<Time>* getAbstractPtr() const; // throw + virtual void plug(SignalBase<Time>* ref); + + virtual void unplug() { plug(NULL); } + + virtual bool isPlugged() const { return (NULL != signalPtr); } + virtual SignalBase<Time>* getPluged() const { return signalPtr; } + virtual bool isAbstractPluged() const; + virtual const Time& getTime() const; + + /* Equivalent operator-like definitions. */ + inline Signal<T, Time>* operator->() { return getPtr(); } + inline const Signal<T, Time>* operator->() const { return getPtr(); } + inline Signal<T, Time>& operator*() { return *getPtr(); } + inline const Signal<T, Time>& operator*() const { return *getPtr(); } + inline operator bool() const { return isPlugged(); } + + public: /* --- INHERITANCE --- */ + virtual bool needUpdate(const Time& t) const; + virtual std::ostream& writeGraph(std::ostream& os) const; + virtual std::ostream& display(std::ostream& os) const; + + /* For compatibility, .access () is equivalent to ->access (). For explicit + * pointer dereference : + * Prefere -> () to () + */ + virtual const T& operator()(const Time& t); + /* Similarly, Prefere ->access to .access + */ + virtual const T& access(const Time& t); + virtual const T& accessCopy() const; + + inline void setConstantDefault(const T& t) + { + Signal<T, Time>::setConstant(t); + modeNoThrow = true; + } + virtual inline void setConstantDefault() + { setConstantDefault(accessCopy()); } + inline void unsetConstantDefault() { modeNoThrow = false; } + + virtual void checkCompatibility(); + + public: /* --- INHERITANCE --- */ + /* SignalPtr could be used as a classical signal, through the normal + * setting functions. The behavior is to plugged the signalPtr on + * the classical mother Signal layer of the object. + */ + virtual void setConstant(const T& t) + { + plug(this); + Signal<T, Time>::setConstant(t); + } + virtual void setReference + (const T* t, + typename Signal<T, Time>::Mutex* m = NULL) + { + plug(this); + Signal<T, Time>::setReference(t, m); + } + virtual void setFunction + (boost::function2<T&, T&, Time> t, + typename Signal<T, Time>::Mutex* m = NULL) + { + plug(this); + Signal<T, Time>::setFunction(t, m); + } + + /* template< class Provider > */ + /* void setFunction( T& (Provider::*fun)(Time,T&),Provider& obj, */ + /* boost::try_mutex *mutexref=NULL ) */ + /* { plug(this); Signal<T,Time>::setFunction(fun,obj,mutexref); } */ + + virtual inline Signal<T, Time>& operator=(const T& t) + { + setConstant(t); + return *this; + } + + virtual std::ostream& displayDependencies + (std::ostream& os, const int depth = -1, std::string space = "", + std::string next1 = "", std::string next2 = "") const; + + protected: // Interdiction of the rest of the heritage + using Signal<T, Time>::addDependency; + virtual void addDependency() {} + using Signal<T, Time>::removeDependency; + virtual void removeDependency() {} + virtual void clearDependencies() {} + }; } // end of namespace dynamicgraph #include <dynamic-graph/signal-ptr.t.cpp> #endif //! DYNAMIC_GRAPH_SIGNAL_PTR_H + diff --git a/include/dynamic-graph/signal-ptr.t.cpp b/include/dynamic-graph/signal-ptr.t.cpp index 3644833..d747a53 100644 --- a/include/dynamic-graph/signal-ptr.t.cpp +++ b/include/dynamic-graph/signal-ptr.t.cpp @@ -11,204 +11,278 @@ #define VP_TEMPLATE_DEBUG_MODE 0 #include <dynamic-graph/debug.h> -namespace dynamicgraph { -template <class T, class Time> -bool SignalPtr<T, Time>::isAbstractPluged() const { - return ((NULL != signalPtr) || (abstractTransmitter)); -} - -template <class T, class Time> -Signal<T, Time>* SignalPtr<T, Time>::getPtr() { - dgTDEBUGIN(25); - if (!isPlugged()) - DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED, "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", - getName().c_str()); - dgTDEBUGOUT(25); - return signalPtr; -} - -template <class T, class Time> -const Signal<T, Time>* SignalPtr<T, Time>::getPtr() const { - dgTDEBUGIN(25) << SignalBase<Time>::name << "(" << isPlugged() << ")" << this << "->" << signalPtr << std::endl; - dgTDEBUGIN(25); - if (!isPlugged()) { - DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED, "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", - getName().c_str()); +namespace dynamicgraph +{ + template <class T, class Time> + bool SignalPtr<T, Time>::isAbstractPluged() const + { + return ((NULL != signalPtr) || (abstractTransmitter)); } - dgTDEBUGOUT(25); - return signalPtr; -} - -template <class T, class Time> -SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() { - if (!isAbstractPluged()) { - DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED, "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", - getName().c_str()); - } - if (NULL != signalPtr) + + template <class T, class Time> + Signal<T, Time>* SignalPtr<T, Time>::getPtr() + { + dgTDEBUGIN(25); + if (!isPlugged()) + DG_THROW + ExceptionSignal + (ExceptionSignal::NOT_INITIALIZED, + "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", + getName().c_str()); + dgTDEBUGOUT(25); return signalPtr; - else - return abstractTransmitter; -} - -template <class T, class Time> -const SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() const { - if (!isAbstractPluged()) { - DG_THROW ExceptionSignal(ExceptionSignal::NOT_INITIALIZED, "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", - getName().c_str()); } - if (NULL != signalPtr) + + template <class T, class Time> + const Signal<T, Time>* SignalPtr<T, Time>::getPtr() const + { + dgTDEBUGIN(25) << SignalBase<Time>::name << "(" + << isPlugged() << ")" << this << "->" + << signalPtr << std::endl; + dgTDEBUGIN(25); + if (!isPlugged()) + { + DG_THROW ExceptionSignal + (ExceptionSignal::NOT_INITIALIZED, + "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", + getName().c_str()); + } + dgTDEBUGOUT(25); return signalPtr; - else - return abstractTransmitter; -} - -template <class T, class Time> -void SignalPtr<T, Time>::plug(SignalBase<Time>* unknown_ref) { - dgTDEBUGIN(5); - if (!unknown_ref) { - signalPtr = NULL; - transmitAbstract = false; + } + + template <class T, class Time> + SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() + { + if (!isAbstractPluged()) + { + DG_THROW ExceptionSignal + (ExceptionSignal::NOT_INITIALIZED, + "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", + getName().c_str()); + } + if (NULL != signalPtr) + return signalPtr; + else + return abstractTransmitter; + } + + template <class T, class Time> + const SignalBase<Time>* SignalPtr<T, Time>::getAbstractPtr() const + { + if (!isAbstractPluged()) + { + DG_THROW ExceptionSignal + (ExceptionSignal::NOT_INITIALIZED, + "In SignalPtr: SIN ptr not set.", " (in signal <%s>)", + getName().c_str()); + } + if (NULL != signalPtr) + return signalPtr; + else + return abstractTransmitter; + } + + template <class T, class Time> + void SignalPtr<T, Time>::plug(SignalBase<Time>* unknown_ref) + { + dgTDEBUGIN(5); + if (!unknown_ref) + { + signalPtr = NULL; + transmitAbstract = false; + dgTDEBUGOUT(5); + return; + } + + dgTDEBUG(5) << "# In T = " << getName() << " =" + << typeid(Signal<T, Time>::Tcopy1).name() + << "{ " << std::endl; + + Signal<T, Time>* ref = dynamic_cast<Signal<T, Time>*>(unknown_ref); + if (NULL == ref) + { + try + { + unknown_ref->checkCompatibility(); + } + catch (T* t) + { + dgTDEBUG(25) << "Cast THROW ok." << std::endl; + Signal<T, Time>::setReference(t); + transmitAbstract = true; + abstractTransmitter = unknown_ref; + transmitAbstractData = t; + } + catch (...) + { + dgTDEBUG(25) << "Fatal error." << std::endl; + transmitAbstract = false; + DG_THROW ExceptionSignal + (ExceptionSignal::PLUG_IMPOSSIBLE, + "Compl. Uncompatible types for plugin.", + "(while trying to plug <%s> on <%s>)" + " with types <%s> on <%s>.", + unknown_ref->getName().c_str(), + this->getName().c_str(), typeid(T).name(), + typeid(unknown_ref).name()); + } + } + else + { + dgTDEBUG(25) << "Cast ok." << std::endl; + transmitAbstract = false; + signalPtr = ref; + } dgTDEBUGOUT(5); - return; } - dgTDEBUG(5) << "# In T = " << getName() << " =" << typeid(Signal<T, Time>::Tcopy1).name() << "{ " << std::endl; - - Signal<T, Time>* ref = dynamic_cast<Signal<T, Time>*>(unknown_ref); - if (NULL == ref) { - try { - unknown_ref->checkCompatibility(); - } catch (T* t) { - dgTDEBUG(25) << "Cast THROW ok." << std::endl; - Signal<T, Time>::setReference(t); - transmitAbstract = true; - abstractTransmitter = unknown_ref; - transmitAbstractData = t; - } catch (...) { - dgTDEBUG(25) << "Fatal error." << std::endl; - transmitAbstract = false; - DG_THROW ExceptionSignal(ExceptionSignal::PLUG_IMPOSSIBLE, "Compl. Uncompatible types for plugin.", - "(while trying to plug <%s> on <%s>)" - " with types <%s> on <%s>.", - unknown_ref->getName().c_str(), this->getName().c_str(), typeid(T).name(), - typeid(unknown_ref).name()); - } - } else { - dgTDEBUG(25) << "Cast ok." << std::endl; - transmitAbstract = false; - signalPtr = ref; + template <class T, class Time> + void SignalPtr<T, Time>::checkCompatibility() + { + if (isPlugged() && (!autoref())) + { + getPtr()->checkCompatibility(); + } + else + if (isAbstractPluged() && (!autoref())) + { + abstractTransmitter->checkCompatibility(); + } + else + Signal<T, Time>::checkCompatibility(); } - dgTDEBUGOUT(5); -} - -template <class T, class Time> -void SignalPtr<T, Time>::checkCompatibility() { - if (isPlugged() && (!autoref())) { - getPtr()->checkCompatibility(); - } else if (isAbstractPluged() && (!autoref())) { - abstractTransmitter->checkCompatibility(); - } else - Signal<T, Time>::checkCompatibility(); -} - -template <class T, class Time> -bool SignalPtr<T, Time>::needUpdate(const Time& t) const { - if ((isAbstractPluged()) && (!autoref())) { - return getAbstractPtr()->needUpdate(t); - } else - return Signal<T, Time>::needUpdate(t); -} - -template <class T, class Time> -const Time& SignalPtr<T, Time>::getTime() const { - if ((isAbstractPluged()) && (!autoref())) { - return getAbstractPtr()->getTime(); + + template <class T, class Time> + bool SignalPtr<T, Time>::needUpdate(const Time& t) const + { + if ((isAbstractPluged()) && (!autoref())) + { + return getAbstractPtr()->needUpdate(t); + } + else + return Signal<T, Time>::needUpdate(t); + } + + template <class T, class Time> + const Time& SignalPtr<T, Time>::getTime() const + { + if ((isAbstractPluged()) && (!autoref())) + { + return getAbstractPtr()->getTime(); + } + return Signal<T, Time>::getTime(); } - return Signal<T, Time>::getTime(); -} - -template <class T, class Time> -const T& SignalPtr<T, Time>::operator()(const Time& t) { - return access(t); -} - -template <class T, class Time> -const T& SignalPtr<T, Time>::access(const Time& t) { - dgTDEBUGIN(15); - if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit) { - dgTDEBUGOUT(15); - return Signal<T, Time>::accessCopy(); - } else if (autoref()) { - dgTDEBUGOUT(15); - return Signal<T, Time>::access(t); - } else if (transmitAbstract) { - abstractTransmitter->recompute(t); - dgTDEBUGOUT(15); - return *transmitAbstractData; - } else { - dgTDEBUGOUT(15); - return getPtr()->access(t); + + template <class T, class Time> + const T& SignalPtr<T, Time>::operator()(const Time& t) + { + return access(t); } -} -template <class T, class Time> -const T& SignalPtr<T, Time>::accessCopy() const { - if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit) - return Signal<T, Time>::accessCopy(); - else if (autoref()) - return Signal<T, Time>::accessCopy(); - else if (transmitAbstract) - return *transmitAbstractData; - else - return getPtr()->accessCopy(); -} -template <class T, class Time> -std::ostream& SignalPtr<T, Time>::writeGraph(std::ostream& os) const { - std::string LeaderLocalName; - std::string LeaderNodeName; - Signal<T, Time>::ExtractNodeAndLocalNames(LeaderLocalName, LeaderNodeName); - if (isAbstractPluged() && !autoref()) { - std::string itLocalName, itNodeName; - getAbstractPtr()->ExtractNodeAndLocalNames(itLocalName, itNodeName); - os << "\t\"" << itNodeName << "\" -> \"" << LeaderNodeName << "\"" << std::endl - << "\t [ headlabel = \"" << LeaderLocalName << "\" , taillabel = \"" << itLocalName - << "\", fontsize=7, fontcolor=red ]" << std::endl; + + template <class T, class Time> + const T& SignalPtr<T, Time>::access(const Time& t) + { + dgTDEBUGIN(15); + if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit) + { + dgTDEBUGOUT(15); + return Signal<T, Time>::accessCopy(); + } + else + if (autoref()) + { + dgTDEBUGOUT(15); + return Signal<T, Time>::access(t); + } + else + if (transmitAbstract) + { + abstractTransmitter->recompute(t); + dgTDEBUGOUT(15); + return *transmitAbstractData; + } + else + { + dgTDEBUGOUT(15); + return getPtr()->access(t); + } } - return os; -} - -template <class T, class Time> -std::ostream& SignalPtr<T, Time>::display(std::ostream& os) const { - dgTDEBUGIN(25) << SignalBase<Time>::name << this << "||" << isPlugged() << "||" << signalPtr; - { Signal<T, Time>::display(os); } - - if ((isAbstractPluged()) && (!autoref())) { - // dgTDEBUG(25) << "Display pointed."<<std::endl; - // getPtr ()->display(os<<"PTR->"); - os << " -->-- PLUGGED"; - } else { - if (!isAbstractPluged()) - os << " UNPLUGGED"; + + template <class T, class Time> + const T& SignalPtr<T, Time>::accessCopy() const + { + if (modeNoThrow && (!isPlugged()) && Signal<T, Time>::copyInit) + return Signal<T, Time>::accessCopy(); else if (autoref()) - os << " AUTOPLUGGED"; + return Signal<T, Time>::accessCopy(); + else if (transmitAbstract) + return *transmitAbstractData; + else + return getPtr()->accessCopy(); + } + template <class T, class Time> + std::ostream& SignalPtr<T, Time>::writeGraph(std::ostream& os) const + { + std::string LeaderLocalName; + std::string LeaderNodeName; + Signal<T, Time>::ExtractNodeAndLocalNames(LeaderLocalName, LeaderNodeName); + if (isAbstractPluged() && !autoref()) + { + std::string itLocalName, itNodeName; + getAbstractPtr()->ExtractNodeAndLocalNames(itLocalName, itNodeName); + os << "\t\"" << itNodeName << "\" -> \"" + << LeaderNodeName << "\"" << std::endl + << "\t [ headlabel = \"" << LeaderLocalName << "\" , taillabel = \"" + << itLocalName + << "\", fontsize=7, fontcolor=red ]" << std::endl; + } + return os; + } + + template <class T, class Time> + std::ostream& SignalPtr<T, Time>::display(std::ostream& os) const + { + dgTDEBUGIN(25) << SignalBase<Time>::name << this + << "||" << isPlugged() << "||" << signalPtr; + { Signal<T, Time>::display(os); } + + if ((isAbstractPluged()) && (!autoref())) + { + os << " -->-- PLUGGED"; + } + else + { + if (!isAbstractPluged()) + os << " UNPLUGGED"; + else if (autoref()) + os << " AUTOPLUGGED"; + } + + dgTDEBUGOUT(25); + return os; } - dgTDEBUGOUT(25); - return os; -} - -template <class T, class Time> -std::ostream& SignalPtr<T, Time>::displayDependencies(std::ostream& os, const int depth, std::string space, - std::string next1, std::string next2) const { - dgTDEBUGIN(25); - if ((isAbstractPluged()) && (!autoref())) { - getAbstractPtr()->displayDependencies(os, depth, space, next1 + "-- " + SignalBase<Time>::name + " -->", next2); - } else { - SignalBase<Time>::displayDependencies(os, depth, space, next1, next2); + template <class T, class Time> + std::ostream& SignalPtr<T, Time>:: + displayDependencies + (std::ostream& os, const int depth, std::string space, + std::string next1, std::string next2) const + { + dgTDEBUGIN(25); + if ((isAbstractPluged()) && (!autoref())) + { + getAbstractPtr()->displayDependencies(os, depth, space, next1 + "-- " + + SignalBase<Time>::name + " -->", + next2); + } + else + { + SignalBase<Time>::displayDependencies(os, depth, space, next1, next2); + } + dgTDEBUGOUT(25); + return os; } - dgTDEBUGOUT(25); - return os; -} } // end of namespace dynamicgraph. diff --git a/include/dynamic-graph/signal-time-dependent.h b/include/dynamic-graph/signal-time-dependent.h index 40c91de..765f929 100644 --- a/include/dynamic-graph/signal-time-dependent.h +++ b/include/dynamic-graph/signal-time-dependent.h @@ -8,24 +8,36 @@ #include <dynamic-graph/signal.h> #include <dynamic-graph/time-dependency.h> -namespace dynamicgraph { -/*! \brief A type of signal that enforces a time dependency between other signals, - making sure its inputs are up to date on access, using a incrementing time tick as reference. - It works this way: for a given SignalTimeDependent S, the user manually adds dependent signals through the - use of the addDependency function. On access (calling the signal S operator () or access(Time) function), - if the dependent signals are not up-to-date, i.e. if their [last update] time is less than the - current time, their value will be access ()'ed to bring them up-to-date. Thus, the value of dependent - signals can be accessed \b quickly and \b repeatedly through the accessCopy () function. -*/ -template <class T, class Time> -class SignalTimeDependent : public virtual Signal<T, Time>, public TimeDependency<Time> { - // TimeDependency<Time> timeDependency; - - public: - SignalTimeDependent(std::string name = ""); - SignalTimeDependent(const SignalArray_const<Time>& arr, std::string name = ""); - SignalTimeDependent(boost::function2<T&, T&, Time> t, const SignalArray_const<Time>& sig, std::string name = ""); - +namespace dynamicgraph +{ + /*! \brief A type of signal that enforces a time dependency between other + signals, + making sure its inputs are up to date on access, using a incrementing time + tick as reference. + It works this way: for a given SignalTimeDependent S, the user manually + adds dependent signals through the + use of the addDependency function. On access (calling the signal S + operator () or access(Time) function), + if the dependent signals are not up-to-date, i.e. if their [last update] + time is less than the + current time, their value will be access ()'ed to bring them up-to-date. + Thus, the value of dependent + signals can be accessed \b quickly and \b repeatedly through the + accessCopy () function. + */ + template <class T, class Time> + class SignalTimeDependent : + public virtual Signal<T, Time>, public TimeDependency<Time> { + // TimeDependency<Time> timeDependency; + + public: + SignalTimeDependent(std::string name = ""); + SignalTimeDependent(const SignalArray_const<Time>& arr, + std::string name = ""); + SignalTimeDependent(boost::function2<T&, T&, Time> t, + const SignalArray_const<Time>& sig, + std::string name = ""); + virtual ~SignalTimeDependent() {} inline const T& operator()(const Time& t1) { return access(t1); } @@ -37,10 +49,13 @@ class SignalTimeDependent : public virtual Signal<T, Time>, public TimeDependenc std::ostream& writeGraph(std::ostream& os) const { return os; } - std::ostream& displayDependencies(std::ostream& os, const int depth = -1, std::string space = "", - std::string next1 = "", std::string next2 = "") const { - return TimeDependency<Time>::displayDependencies(os, depth, space, next1, next2); - } + std::ostream& displayDependencies + (std::ostream& os, const int depth = -1, std::string space = "", + std::string next1 = "", std::string next2 = "") const + { + return TimeDependency<Time>:: + displayDependencies(os, depth, space, next1, next2); + } virtual bool needUpdate(const Time& t) const; virtual void setPeriodTime(const Time& p); @@ -50,63 +65,83 @@ class SignalTimeDependent : public virtual Signal<T, Time>, public TimeDependenc /* -------------------------------------------- */ template <class T, class Time> -SignalTimeDependent<T, Time>::SignalTimeDependent(std::string name) +SignalTimeDependent<T, Time>::SignalTimeDependent +(std::string name) : Signal<T, Time>(name), TimeDependency<Time>(this) {} template <class T, class Time> -SignalTimeDependent<T, Time>::SignalTimeDependent(const SignalArray_const<Time>& arr, std::string name) +SignalTimeDependent<T, Time>::SignalTimeDependent +(const SignalArray_const<Time>& arr, std::string name) : Signal<T, Time>(name), TimeDependency<Time>(this, arr) {} template <class T, class Time> -SignalTimeDependent<T, Time>::SignalTimeDependent(boost::function2<T&, T&, Time> t, const SignalArray_const<Time>& sig, - std::string name) - : Signal<T, Time>(name), TimeDependency<Time>(this, sig) { +SignalTimeDependent<T, Time>::SignalTimeDependent +(boost::function2<T&, T&, Time> t, const SignalArray_const<Time>& sig, + std::string name) + : Signal<T, Time>(name), TimeDependency<Time>(this, sig) +{ this->setFunction(t); } template <class T, class Time> -const T& SignalTimeDependent<T, Time>::access(const Time& t1) { +const T& SignalTimeDependent<T, Time>::access(const Time& t1) +{ const bool up = TimeDependency<Time>::needUpdate(t1); // SignalBase<Time>::setReady(false); /* std::cout << "Time before: "<< signalTime << " -- " */ - /* << t1<< " -> Up: "<<up <<std::endl ; */ - if (up) { - TimeDependency<Time>::lastAskForUpdate = false; - const T& Tres = Signal<T, Time>::access(t1); - SignalBase<Time>::setReady(false); - return Tres; - } else { - return Signal<T, Time>::accessCopy(); - } + /* << t1<< " -> Up: "<<up <<std::endl ; */ + if (up) + { + TimeDependency<Time>::lastAskForUpdate = false; + const T& Tres = Signal<T, Time>::access(t1); + SignalBase<Time>::setReady(false); + return Tres; + } + else + { + return Signal<T, Time>::accessCopy(); + } } template <class T, class Time> -void SignalTimeDependent<T, Time>::addDependency(const SignalBase<Time>& signal) { +void SignalTimeDependent<T, Time>:: +addDependency(const SignalBase<Time>& signal) +{ TimeDependency<Time>::addDependency(signal); } template <class T, class Time> -void SignalTimeDependent<T, Time>::removeDependency(const SignalBase<Time>& signal) { +void SignalTimeDependent<T, Time>:: +removeDependency(const SignalBase<Time>& signal) +{ TimeDependency<Time>::removeDependency(signal); } template <class T, class Time> -void SignalTimeDependent<T, Time>::clearDependencies() { +void SignalTimeDependent<T, Time>:: +clearDependencies() +{ TimeDependency<Time>::clearDependency(); } template <class T, class Time> -bool SignalTimeDependent<T, Time>::needUpdate(const Time& t) const { +bool SignalTimeDependent<T, Time>:: +needUpdate(const Time& t) const +{ return TimeDependency<Time>::needUpdate(t); } template <class T, class Time> -void SignalTimeDependent<T, Time>::setPeriodTime(const Time& p) { +void SignalTimeDependent<T, Time>:: +setPeriodTime(const Time& p) +{ TimeDependency<Time>::setPeriodTime(p); } template <class T, class Time> -Time SignalTimeDependent<T, Time>::getPeriodTime() const { +Time SignalTimeDependent<T, Time>:: +getPeriodTime() const +{ return TimeDependency<Time>::getPeriodTime(); } diff --git a/include/dynamic-graph/signal.h b/include/dynamic-graph/signal.h index 842a69f..a1f3de2 100644 --- a/include/dynamic-graph/signal.h +++ b/include/dynamic-graph/signal.h @@ -22,98 +22,102 @@ #include <boost/thread.hpp> #endif -namespace dynamicgraph { - -/*! \ingroup dgraph - \brief Signals link I/O ports of entities. They can be - constant-valued signals, or copy the value of a heap variable, - or evaluated as a function. - See SignalPtr and SignalTimeDependent for other types of signals, - and SignalArray for a way of grouping them. - - There are several ways to specify the value output by a signal: - \li using the function setConstant(T) to set the value of the signal to T; - \li using the function setReference(mutex, T*) to set the value from a pointer, - whose access is restricted by a mutex; - \li using the function setFunction(boost::function2) that will be called when the - signal's value is accessed. - */ -template <class T, class Time> -class Signal : public SignalBase<Time> { - protected: - enum SignalType { CONSTANT, REFERENCE, REFERENCE_NON_CONST, FUNCTION }; - static const SignalType SIGNAL_TYPE_DEFAULT = CONSTANT; - - SignalType signalType; - T Tcopy1, Tcopy2; - T* Tcopy; - bool copyInit; - - const T* Treference; - T* TreferenceNonConst; - boost::function2<T&, T&, Time> Tfunction; - - bool keepReference; - const static bool KEEP_REFERENCE_DEFAULT = false; - - public: +namespace dynamicgraph +{ + + /*! \ingroup dgraph + \brief Signals link I/O ports of entities. They can be + constant-valued signals, or copy the value of a heap variable, + or evaluated as a function. + See SignalPtr and SignalTimeDependent for other types of signals, + and SignalArray for a way of grouping them. + + There are several ways to specify the value output by a signal: + \li using the function setConstant(T) to set the value of the signal to T; + \li using the function setReference(mutex, T*) to set the value + from a pointer, whose access is restricted by a mutex; + \li using the function setFunction(boost::function2) that will be called + when the signal's value is accessed. + */ + template <class T, class Time> + class Signal : public SignalBase<Time> + { + protected: + enum SignalType { CONSTANT, REFERENCE, REFERENCE_NON_CONST, FUNCTION }; + static const SignalType SIGNAL_TYPE_DEFAULT = CONSTANT; + + SignalType signalType; + T Tcopy1, Tcopy2; + T* Tcopy; + bool copyInit; + + const T* Treference; + T* TreferenceNonConst; + boost::function2<T&, T&, Time> Tfunction; + + bool keepReference; + const static bool KEEP_REFERENCE_DEFAULT = false; + + public: #ifdef HAVE_LIBBOOST_THREAD - typedef boost::try_mutex Mutex; - typedef boost::lock_error MutexError; + typedef boost::try_mutex Mutex; + typedef boost::lock_error MutexError; #else - typedef int* Mutex; - typedef int* MutexError; + typedef int* Mutex; + typedef int* MutexError; #endif - - protected: - Mutex* providerMutex; - using SignalBase<Time>::signalTime; - - public: - using SignalBase<Time>::setReady; - - public: - /* --- Constructor/destrusctor --- */ - Signal(std::string name); - virtual ~Signal() {} - - /* --- Generic In/Out function --- */ - virtual void get(std::ostream& value) const; - virtual void set(std::istringstream& value); - virtual void trace(std::ostream& os) const; - - /* --- Generic Set function --- */ - virtual void setConstant(const T& t); - virtual void setReference(const T* t, Mutex* mutexref = NULL); - virtual void setReferenceNonConstant(T* t, Mutex* mutexref = NULL); - virtual void setFunction(boost::function2<T&, T&, Time> t, Mutex* mutexref = NULL); - - inline bool getKeepReference() { return keepReference; } - inline void setKeepReference(const bool& b) { keepReference = b; } - - /* --- Signal computation --- */ - virtual const T& access(const Time& t); - virtual inline void recompute(const Time& t) { access(t); } - virtual const T& accessCopy() const; - - virtual std::ostream& display(std::ostream& os) const; - - /* --- Operators --- */ - virtual inline const T& operator()(const Time& t) { return access(t); } - virtual Signal<T, Time>& operator=(const T& t); - inline operator const T&() const { return accessCopy(); } - virtual void getClassName(std::string& aClassName) const { aClassName = typeid(this).name(); } - - public: - virtual void checkCompatibility() { throw Tcopy; } - - private: - const T& setTcopy(const T& t); - T& getTwork(); - const T& getTwork() const; - const T& switchTcopy(); -}; - + + protected: + Mutex* providerMutex; + using SignalBase<Time>::signalTime; + + public: + using SignalBase<Time>::setReady; + + public: + /* --- Constructor/destrusctor --- */ + Signal(std::string name); + virtual ~Signal() {} + + /* --- Generic In/Out function --- */ + virtual void get(std::ostream& value) const; + virtual void set(std::istringstream& value); + virtual void trace(std::ostream& os) const; + + /* --- Generic Set function --- */ + virtual void setConstant(const T& t); + virtual void setReference(const T* t, Mutex* mutexref = NULL); + virtual void setReferenceNonConstant(T* t, Mutex* mutexref = NULL); + virtual void setFunction(boost::function2<T&, T&, Time> t, + Mutex* mutexref = NULL); + + inline bool getKeepReference() { return keepReference; } + inline void setKeepReference(const bool& b) { keepReference = b; } + + /* --- Signal computation --- */ + virtual const T& access(const Time& t); + virtual inline void recompute(const Time& t) { access(t); } + virtual const T& accessCopy() const; + + virtual std::ostream& display(std::ostream& os) const; + + /* --- Operators --- */ + virtual inline const T& operator()(const Time& t) { return access(t); } + virtual Signal<T, Time>& operator=(const T& t); + inline operator const T&() const { return accessCopy(); } + virtual void getClassName(std::string& aClassName) const + { aClassName = typeid(this).name(); } + + public: + virtual void checkCompatibility() { throw Tcopy; } + + private: + const T& setTcopy(const T& t); + T& getTwork(); + const T& getTwork() const; + const T& switchTcopy(); + }; + } // end of namespace dynamicgraph #include <dynamic-graph/signal.t.cpp> diff --git a/include/dynamic-graph/signal.t.cpp b/include/dynamic-graph/signal.t.cpp index 79a74ed..636dad1 100644 --- a/include/dynamic-graph/signal.t.cpp +++ b/include/dynamic-graph/signal.t.cpp @@ -12,222 +12,280 @@ #define VP_TEMPLATE_DEBUG_MODE 0 #include <dynamic-graph/debug.h> -#define __SIGNAL_INIT(name, Tcpy, Tref, TrefNC, mutex) \ - SignalBase<Time>(name), signalType(SIGNAL_TYPE_DEFAULT), Tcopy1(Tcpy), Tcopy2(Tcpy), Tcopy(&Tcopy1), \ - Treference(Tref), TreferenceNonConst(TrefNC), Tfunction(), keepReference(KEEP_REFERENCE_DEFAULT), \ - providerMutex(mutex) - -namespace dynamicgraph { - -template <class T, class Time> -Signal<T, Time>::Signal(std::string name) : __SIGNAL_INIT(name, T(), NULL, NULL, NULL) { - return; -} - -/* -------------------------------------------------------------------------- */ - -template <class T, class Time> -void Signal<T, Time>::set(std::istringstream& stringValue) { - (*this) = signal_cast<T>(stringValue); -} - -template <class T, class Time> -void Signal<T, Time>::get(std::ostream& os) const { - signal_disp<T>(this->accessCopy(), os); -} - -template <class T, class Time> -void Signal<T, Time>::trace(std::ostream& os) const { - try { - signal_trace<T>(this->accessCopy(), os); - } catch DG_RETHROW catch (...) { - DG_THROW ExceptionSignal(ExceptionSignal::SET_IMPOSSIBLE, "TRACE operation not possible with this signal. ", - "(bad cast while getting value from %s).", SignalBase<Time>::getName().c_str()); - } -} - -/* -------------------------------------------------------------------------- */ - -template <class T, class Time> -const T& Signal<T, Time>::setTcopy(const T& t) { - if (Tcopy == &Tcopy1) { - Tcopy2 = t; - copyInit = true; - Tcopy = &Tcopy2; - return Tcopy2; - } else { - Tcopy1 = t; - copyInit = true; - Tcopy = &Tcopy1; - return Tcopy1; - } -} - -template <class T, class Time> -T& Signal<T, Time>::getTwork() { - if (Tcopy == &Tcopy1) - return Tcopy2; - else - return Tcopy1; -} - -template <class T, class Time> -const T& Signal<T, Time>::getTwork() const { - if (Tcopy == &Tcopy1) - return Tcopy2; - else - return Tcopy1; -} - -template <class T, class Time> -const T& Signal<T, Time>::switchTcopy() { - if (Tcopy == &Tcopy1) { - Tcopy = &Tcopy2; - return Tcopy2; - } else { - Tcopy = &Tcopy1; - return Tcopy1; - } -} - -template <class T, class Time> -void Signal<T, Time>::setConstant(const T& t) { - signalType = CONSTANT; - setTcopy(t); - setReady(); -} - -template <class T, class Time> -void Signal<T, Time>::setReference(const T* t, Mutex* mutexref) { - signalType = REFERENCE; - Treference = t; - providerMutex = mutexref; - copyInit = false; - setReady(); -} - -template <class T, class Time> -void Signal<T, Time>::setReferenceNonConstant(T* t, Mutex* mutexref) { - signalType = REFERENCE_NON_CONST; - Treference = t; - TreferenceNonConst = t; - providerMutex = mutexref; - copyInit = false; - setReady(); -} - -template <class T, class Time> -void Signal<T, Time>::setFunction(boost::function2<T&, T&, Time> t, Mutex* mutexref) { - signalType = FUNCTION; - Tfunction = t; - providerMutex = mutexref; - copyInit = false; - setReady(); -} - -template <class T, class Time> -const T& Signal<T, Time>::accessCopy() const { - return *Tcopy; -} - -template <class T, class Time> -const T& Signal<T, Time>::access(const Time& t) { - // dgTDEBUG(20) << "# In (" << SignalBase<Time>::name <<")"<<std::endl; - switch (signalType) { - case REFERENCE: - case REFERENCE_NON_CONST: { - if (NULL == providerMutex) { - copyInit = true; - signalTime = t; - return setTcopy(*Treference); - } else { - try { -#ifdef HAVE_LIBBOOST_THREAD - boost::try_mutex::scoped_try_lock lock(*providerMutex); -#endif - copyInit = true; - signalTime = t; - return setTcopy(*Treference); - } catch (const MutexError&) { - return accessCopy(); - } - } +#define __SIGNAL_INIT(name, Tcpy, Tref, TrefNC, mutex) \ + SignalBase<Time>(name), signalType(SIGNAL_TYPE_DEFAULT), Tcopy1(Tcpy),\ + Tcopy2(Tcpy), Tcopy(&Tcopy1), \ + Treference(Tref), TreferenceNonConst(TrefNC), Tfunction(), \ + keepReference(KEEP_REFERENCE_DEFAULT), \ + providerMutex(mutex) + +namespace dynamicgraph +{ + + template <class T, class Time> + Signal<T, Time>::Signal(std::string name) : + __SIGNAL_INIT(name, T(), NULL, NULL, NULL) + { + return; + } + + /* ------------------------------------------------------------------------ */ + + template <class T, class Time> + void Signal<T, Time>::set(std::istringstream& stringValue) + { + (*this) = signal_cast<T>(stringValue); + } + + template <class T, class Time> + void Signal<T, Time>::get(std::ostream& os) const + { + signal_disp<T>(this->accessCopy(), os); + } - break; + template <class T, class Time> + void Signal<T, Time>::trace(std::ostream& os) const + { + try { + signal_trace<T>(this->accessCopy(), os); } + catch DG_RETHROW + catch (...) + { + DG_THROW ExceptionSignal + (ExceptionSignal::SET_IMPOSSIBLE, + "TRACE operation not possible with this signal. ", + "(bad cast while getting value from %s).", + SignalBase<Time>::getName().c_str()); + } + } - case FUNCTION: { - if (NULL == providerMutex) { - signalTime = t; - Tfunction(getTwork(), t); + /* ------------------------------------------------------------------------ */ + + template <class T, class Time> + const T& Signal<T, Time>::setTcopy(const T& t) + { + if (Tcopy == &Tcopy1) + { + Tcopy2 = t; copyInit = true; - return switchTcopy(); - } else { - try { + Tcopy = &Tcopy2; + return Tcopy2; + } + else + { + Tcopy1 = t; + copyInit = true; + Tcopy = &Tcopy1; + return Tcopy1; + } + } + + template <class T, class Time> + T& Signal<T, Time>::getTwork() + { + if (Tcopy == &Tcopy1) + return Tcopy2; + else + return Tcopy1; + } + + template <class T, class Time> + const T& Signal<T, Time>::getTwork() const + { + if (Tcopy == &Tcopy1) + return Tcopy2; + else + return Tcopy1; + } + + template <class T, class Time> + const T& Signal<T, Time>::switchTcopy() + { + if (Tcopy == &Tcopy1) + { + Tcopy = &Tcopy2; + return Tcopy2; + } + else + { + Tcopy = &Tcopy1; + return Tcopy1; + } + } + + template <class T, class Time> + void Signal<T, Time>::setConstant(const T& t) + { + signalType = CONSTANT; + setTcopy(t); + setReady(); + } + + template <class T, class Time> + void Signal<T, Time>::setReference(const T* t, Mutex* mutexref) + { + signalType = REFERENCE; + Treference = t; + providerMutex = mutexref; + copyInit = false; + setReady(); + } + + template <class T, class Time> + void Signal<T, Time>::setReferenceNonConstant(T* t, Mutex* mutexref) + { + signalType = REFERENCE_NON_CONST; + Treference = t; + TreferenceNonConst = t; + providerMutex = mutexref; + copyInit = false; + setReady(); + } + + template <class T, class Time> + void Signal<T, Time>::setFunction + (boost::function2<T&, T&, Time> t, Mutex* mutexref) + { + signalType = FUNCTION; + Tfunction = t; + providerMutex = mutexref; + copyInit = false; + setReady(); + } + + template <class T, class Time> + const T& Signal<T, Time>::accessCopy() const + { + return *Tcopy; + } + + template <class T, class Time> + const T& Signal<T, Time>::access(const Time& t) + { + switch (signalType) + { + case REFERENCE: + case REFERENCE_NON_CONST: + { + if (NULL == providerMutex) + { + copyInit = true; + signalTime = t; + return setTcopy(*Treference); + } + else + { + try + { #ifdef HAVE_LIBBOOST_THREAD - boost::try_mutex::scoped_try_lock lock(*providerMutex); + boost::try_mutex::scoped_try_lock lock(*providerMutex); #endif - signalTime = t; - Tfunction(getTwork(), t); - copyInit = true; - return switchTcopy(); - } catch (const MutexError&) { - return accessCopy(); + copyInit = true; + signalTime = t; + return setTcopy(*Treference); + } + catch (const MutexError&) + { + return accessCopy(); + } + } + + break; } + + case FUNCTION: + { + if (NULL == providerMutex) + { + signalTime = t; + Tfunction(getTwork(), t); + copyInit = true; + return switchTcopy(); + } + else + { + try + { +#ifdef HAVE_LIBBOOST_THREAD + boost::try_mutex::scoped_try_lock lock(*providerMutex); +#endif + signalTime = t; + Tfunction(getTwork(), t); + copyInit = true; + return switchTcopy(); + } + catch (const MutexError&) + { + return accessCopy(); + } + } + break; } - break; - } case CONSTANT: default: - if (this->getReady()) { - setReady(false); - this->setTime(t); - } + if (this->getReady()) + { + setReady(false); + this->setTime(t); + } return accessCopy(); - }; -} - -template <class T, class Time> -Signal<T, Time>& Signal<T, Time>::operator=(const T& t) { - if (keepReference && (REFERENCE_NON_CONST == signalType) && (NULL != TreferenceNonConst)) { - if (NULL == providerMutex) { - setTcopy(t); - (*TreferenceNonConst) = t; - } else { - try { + }; + } + + template <class T, class Time> + Signal<T, Time>& Signal<T, Time>::operator=(const T& t) + { + if (keepReference && (REFERENCE_NON_CONST == signalType) && + (NULL != TreferenceNonConst)) + { + if (NULL == providerMutex) + { + setTcopy(t); + (*TreferenceNonConst) = t; + } + else + { + try + { #ifdef HAVE_LIBBOOST_THREAD - boost::try_mutex::scoped_try_lock lock(*providerMutex); + boost::try_mutex::scoped_try_lock lock(*providerMutex); #endif - setTcopy(t); - (*TreferenceNonConst) = t; - } catch (const MutexError&) { /* TODO ERROR */ + setTcopy(t); + (*TreferenceNonConst) = t; + } + catch (const MutexError&) + { /* TODO ERROR */ } + } } - } - } else { - setConstant(t); - } - return *this; -} - -template <class T, class Time> -std::ostream& Signal<T, Time>::display(std::ostream& os) const { - os << "Sig:" << this->name << " (Type "; - switch (this->signalType) { - case Signal<T, Time>::CONSTANT: - os << "Cst"; - break; - case Signal<T, Time>::REFERENCE: - os << "Ref"; - break; - case Signal<T, Time>::REFERENCE_NON_CONST: - os << "RefNonCst"; - break; - case Signal<T, Time>::FUNCTION: - os << "Fun"; - break; - } - return os << ")"; -} + else + { + setConstant(t); + } + return *this; + } + + template <class T, class Time> + std::ostream& Signal<T, Time>::display(std::ostream& os) const + { + os << "Sig:" << this->name << " (Type "; + switch (this->signalType) + { + case Signal<T, Time>::CONSTANT: + os << "Cst"; + break; + case Signal<T, Time>::REFERENCE: + os << "Ref"; + break; + case Signal<T, Time>::REFERENCE_NON_CONST: + os << "RefNonCst"; + break; + case Signal<T, Time>::FUNCTION: + os << "Fun"; + break; + } + return os << ")"; + } } // end of namespace dynamicgraph. diff --git a/include/dynamic-graph/time-dependency.h b/include/dynamic-graph/time-dependency.h index e7516c6..025a71c 100644 --- a/include/dynamic-graph/time-dependency.h +++ b/include/dynamic-graph/time-dependency.h @@ -11,56 +11,66 @@ #include <dynamic-graph/signal-base.h> #include <dynamic-graph/signal-array.h> -namespace dynamicgraph { -/** \brief A helper class for setting and specifying dependencies - between signals. -*/ -template <class Time> -class TimeDependency { - public: - enum DependencyType { TIME_DEPENDENT, BOOL_DEPENDENT, ALWAYS_READY }; - - mutable Time lastAskForUpdate; - - public: - SignalBase<Time>& leader; - - typedef std::list<const SignalBase<Time>*> Dependencies; - static const DependencyType DEPENDENCY_TYPE_DEFAULT = TIME_DEPENDENT; - - Dependencies dependencies; - bool updateFromAllChildren; - static const bool ALL_READY_DEFAULT = false; - - DependencyType dependencyType; - - Time periodTime; - static const Time PERIOD_TIME_DEFAULT = 1; - - public: - TimeDependency(SignalBase<Time>* sig, const DependencyType dep = DEPENDENCY_TYPE_DEFAULT); - TimeDependency(SignalBase<Time>* sig, const SignalArray_const<Time>& arr, - const DependencyType dep = DEPENDENCY_TYPE_DEFAULT); - virtual ~TimeDependency() {} - - void addDependency(const SignalBase<Time>& sig); - void removeDependency(const SignalBase<Time>& sig); - void clearDependency(); - - virtual std::ostream& writeGraph(std::ostream& os) const; - std::ostream& displayDependencies(std::ostream& os, const int depth = -1, std::string space = "", - std::string next1 = "", std::string next2 = "") const; - - bool needUpdate(const Time& t1) const; - - void setDependencyType(DependencyType dep) { dependencyType = dep; } - - void setNeedUpdateFromAllChildren(const bool b = true) { updateFromAllChildren = b; } - bool getNeedUpdateFromAllChildren() const { return updateFromAllChildren; } - - void setPeriodTime(const Time& p) { periodTime = p; } - Time getPeriodTime() const { return periodTime; } -}; +namespace dynamicgraph +{ + /** \brief A helper class for setting and specifying dependencies + between signals. + */ + template <class Time> + class TimeDependency + { + public: + enum DependencyType { TIME_DEPENDENT, BOOL_DEPENDENT, ALWAYS_READY }; + + mutable Time lastAskForUpdate; + + public: + SignalBase<Time>& leader; + + typedef std::list<const SignalBase<Time>*> Dependencies; + static const DependencyType DEPENDENCY_TYPE_DEFAULT = TIME_DEPENDENT; + + Dependencies dependencies; + bool updateFromAllChildren; + static const bool ALL_READY_DEFAULT = false; + + DependencyType dependencyType; + + Time periodTime; + static const Time PERIOD_TIME_DEFAULT = 1; + + public: + TimeDependency(SignalBase<Time>* sig, + const DependencyType dep = DEPENDENCY_TYPE_DEFAULT); + TimeDependency(SignalBase<Time>* sig, + const SignalArray_const<Time>& arr, + const DependencyType dep = DEPENDENCY_TYPE_DEFAULT); + virtual ~TimeDependency() {} + + void addDependency(const SignalBase<Time>& sig); + void removeDependency(const SignalBase<Time>& sig); + void clearDependency(); + + virtual std::ostream& writeGraph(std::ostream& os) const; + std::ostream& displayDependencies(std::ostream& os, + const int depth = -1, + std::string space = "", + std::string next1 = "", + std::string next2 = "") const; + + bool needUpdate(const Time& t1) const; + + void setDependencyType(DependencyType dep) + { dependencyType = dep; } + + void setNeedUpdateFromAllChildren(const bool b = true) + { updateFromAllChildren = b; } + bool getNeedUpdateFromAllChildren() const + { return updateFromAllChildren; } + + void setPeriodTime(const Time& p) { periodTime = p; } + Time getPeriodTime() const { return periodTime; } + }; } // end of namespace dynamicgraph diff --git a/include/dynamic-graph/time-dependency.t.cpp b/include/dynamic-graph/time-dependency.t.cpp index 0b2c1fb..fd70382 100644 --- a/include/dynamic-graph/time-dependency.t.cpp +++ b/include/dynamic-graph/time-dependency.t.cpp @@ -11,152 +11,197 @@ #define VP_TEMPLATE_DEBUG_MODE 0 #include <dynamic-graph/debug.h> -#define __TIME_DEPENDENCY_INIT(sig, dep) \ - leader(*sig), dependencies(), updateFromAllChildren(ALL_READY_DEFAULT), dependencyType(dep), \ - periodTime(PERIOD_TIME_DEFAULT) - -namespace dynamicgraph { -template <class Time> -TimeDependency<Time>::TimeDependency(SignalBase<Time>* sig, const DependencyType dep) +#define __TIME_DEPENDENCY_INIT(sig, dep) \ + leader(*sig), dependencies(), \ + updateFromAllChildren(ALL_READY_DEFAULT), \ + dependencyType(dep), \ + periodTime(PERIOD_TIME_DEFAULT) + +namespace dynamicgraph +{ + template <class Time> + TimeDependency<Time>::TimeDependency + (SignalBase<Time>* sig, const DependencyType dep) : __TIME_DEPENDENCY_INIT(sig, dep) {} - -template <class Time> -TimeDependency<Time>::TimeDependency(SignalBase<Time>* sig, const SignalArray_const<Time>& ar, - const DependencyType dep) - : __TIME_DEPENDENCY_INIT(sig, dep) { - for (unsigned int i = 0; i < ar.getSize(); ++i) { - addDependency(ar[i]); + + template <class Time> + TimeDependency<Time>::TimeDependency + (SignalBase<Time>* sig, + const SignalArray_const<Time>& ar, + const DependencyType dep) + : __TIME_DEPENDENCY_INIT(sig, dep) + { + for (unsigned int i = 0; i < ar.getSize(); ++i) + { + addDependency(ar[i]); + } + + return; } - return; -} - -/* -------------------------------------------------------------------------- */ -template <class Time> -void TimeDependency<Time>::addDependency(const SignalBase<Time>& sig) { - dependencies.push_front(&sig); -} - -template <class Time> -void TimeDependency<Time>::removeDependency(const SignalBase<Time>& sig) { - dependencies.remove(&sig); -} -template <class Time> -void TimeDependency<Time>::clearDependency() { - dependencies.clear(); -} - -template <class Time> -bool TimeDependency<Time>::needUpdate(const Time& t1) const { - dgTDEBUG(15) << "# In {" << leader.getName() << " : (" << leader.getReady() << ") " << t1 << " >? " - << leader.getTime() << std::endl; + /* ------------------------------------------------------------------------ */ + template <class Time> + void TimeDependency<Time>::addDependency(const SignalBase<Time>& sig) + { + dependencies.push_front(&sig); + } - if (leader.getReady()) { - dgTDEBUGOUT(15); - return true; + template <class Time> + void TimeDependency<Time>::removeDependency(const SignalBase<Time>& sig) + { + dependencies.remove(&sig); } - if (lastAskForUpdate) { - dgTDEBUGOUT(15); - return true; + + template <class Time> + void TimeDependency<Time>::clearDependency() + { + dependencies.clear(); } - switch (dependencyType) { - case ALWAYS_READY: { - dgTDEBUGOUT(15); - return true; - } - case BOOL_DEPENDENT: - break; - case TIME_DEPENDENT: { - if (t1 < leader.getTime() + periodTime) { + template <class Time> + bool TimeDependency<Time>::needUpdate(const Time& t1) const + { + dgTDEBUG(15) << "# In {" << leader.getName() << " : (" + << leader.getReady() << ") " << t1 << " >? " + << leader.getTime() << std::endl; + + if (leader.getReady()) + { dgTDEBUGOUT(15); - return false; + return true; + } + if (lastAskForUpdate) + { + dgTDEBUGOUT(15); + return true; } - break; - } - }; - - bool res = updateFromAllChildren; - const typename Dependencies::const_iterator itend = dependencies.end(); - for (typename Dependencies::const_iterator it = dependencies.begin(); it != itend; ++it) { - const SignalBase<Time>& sig = **it; - dgTDEBUG(15) << "Ask update for " << sig << std::endl; - if ((sig.getTime() > leader.getTime()) || (sig.needUpdate(t1))) { - if (updateFromAllChildren) - continue; - else { - res = true; + switch (dependencyType) + { + case ALWAYS_READY: + { + dgTDEBUGOUT(15); + return true; + } + case BOOL_DEPENDENT: break; + case TIME_DEPENDENT: + { + if (t1 < leader.getTime() + periodTime) + { + dgTDEBUGOUT(15); + return false; + } + break; + } + }; + + bool res = updateFromAllChildren; + const typename Dependencies::const_iterator itend = dependencies.end(); + for (typename Dependencies::const_iterator it = dependencies.begin(); + it != itend; ++it) + { + const SignalBase<Time>& sig = **it; + dgTDEBUG(15) << "Ask update for " << sig << std::endl; + + if ((sig.getTime() > leader.getTime()) || (sig.needUpdate(t1))) + { + if (updateFromAllChildren) + continue; + else + { + res = true; + break; + } + } + else + { + if (updateFromAllChildren) + { + res = false; + break; + } + else + continue; + } } - } else { - if (updateFromAllChildren) { - res = false; - break; - } else - continue; - } - } - lastAskForUpdate = res; + lastAskForUpdate = res; - dgTDEBUGOUT(15); - return res; -} + dgTDEBUGOUT(15); + return res; + } -template <class Time> -std::ostream& TimeDependency<Time>::writeGraph(std::ostream& os) const { - std::string LeaderLocalName; - std::string LeaderNodeName; - leader.ExtractNodeAndLocalNames(LeaderLocalName, LeaderNodeName); - if (dependencies.size() != 0) { - const typename Dependencies::const_iterator itend = dependencies.end(); - for (typename Dependencies::const_iterator it = dependencies.begin(); it != itend; ++it) { - std::string itLocalName, itNodeName; - (*it)->ExtractNodeAndLocalNames(itLocalName, itNodeName); - os << "\"" << itNodeName << "\" -> \"" << LeaderNodeName << "\"" << std::endl - << " [ headlabel = \"" << LeaderLocalName << "\" , taillabel = \"" << itLocalName << "\" ]" << std::endl; - } + template <class Time> + std::ostream& TimeDependency<Time>::writeGraph(std::ostream& os) const + { + std::string LeaderLocalName; + std::string LeaderNodeName; + leader.ExtractNodeAndLocalNames(LeaderLocalName, LeaderNodeName); + if (dependencies.size() != 0) + { + const typename Dependencies::const_iterator itend = dependencies.end(); + for (typename Dependencies::const_iterator it = dependencies.begin(); + it != itend; ++it) + { + std::string itLocalName, itNodeName; + (*it)->ExtractNodeAndLocalNames(itLocalName, itNodeName); + os << "\"" << itNodeName << "\" -> \"" << LeaderNodeName + << "\"" << std::endl + << " [ headlabel = \"" << LeaderLocalName + << "\" , taillabel = \"" << itLocalName << "\" ]" << std::endl; + } + } + return os; } - return os; -} -template <class Time> -std::ostream& TimeDependency<Time>::displayDependencies(std::ostream& os, const int depth, std::string space, - std::string next1, std::string next2) const { - leader.SignalBase<Time>::displayDependencies(os, depth, space, next1, next2) << " ("; - switch (dependencyType) { - case ALWAYS_READY: - os << "A"; - break; - case BOOL_DEPENDENT: - os << "ready=" << ((leader.getReady()) ? "TRUE" : "FALSE"); - break; - case TIME_DEPENDENT: - os << "t=" << leader.getTime() << " (/" << periodTime << ") "; - break; - }; - os << ")"; //<<std::endl; + template <class Time> + std::ostream& TimeDependency<Time>:: + displayDependencies + (std::ostream& os, const int depth, std::string space, + std::string next1, std::string next2) const { - const typename Dependencies::const_iterator itend = dependencies.end(); - for (typename Dependencies::const_iterator it = dependencies.begin(); it != itend; ++it) - if (depth != 0) { - os << std::endl; - std::string ajout = "|"; - std::string ajout2 = "|"; - typename Dependencies::const_iterator it2 = it; - it2++; - if (it2 == dependencies.end()) { - ajout = "`"; - ajout2 = " "; - } - (*it)->displayDependencies(os, depth - 1, space + next2 + " ", ajout, ajout2); - } else { - os << std::endl << space << " `-- ..."; + leader.SignalBase<Time>::displayDependencies(os, depth, space, next1, next2) + << " ("; + switch (dependencyType) + { + case ALWAYS_READY: + os << "A"; break; - } + case BOOL_DEPENDENT: + os << "ready=" << ((leader.getReady()) ? "TRUE" : "FALSE"); + break; + case TIME_DEPENDENT: + os << "t=" << leader.getTime() << " (/" << periodTime << ") "; + break; + }; + os << ")"; //<<std::endl; + { + const typename Dependencies::const_iterator itend = dependencies.end(); + for (typename Dependencies::const_iterator it = dependencies.begin(); + it != itend; ++it) + if (depth != 0) + { + os << std::endl; + std::string ajout = "|"; + std::string ajout2 = "|"; + typename Dependencies::const_iterator it2 = it; + it2++; + if (it2 == dependencies.end()) + { + ajout = "`"; + ajout2 = " "; + } + (*it)->displayDependencies + (os, depth - 1, space + next2 + " ", ajout, ajout2); + } + else + { + os << std::endl << space << " `-- ..."; + break; + } + } + return os; } - return os; -} } // end of namespace dynamicgraph diff --git a/include/dynamic-graph/tracer-real-time.h b/include/dynamic-graph/tracer-real-time.h index af3e353..6dd48ff 100644 --- a/include/dynamic-graph/tracer-real-time.h +++ b/include/dynamic-graph/tracer-real-time.h @@ -11,60 +11,66 @@ #include <dynamic-graph/tracer.h> #include <dynamic-graph/config-tracer-real-time.hh> -namespace dynamicgraph { -/// \ingroup plugin -/// -/// \brief Stream for the tracer real-time. -class DG_TRACERREALTIME_DLLAPI OutStringStream : public std::ostringstream { - public: - char* buffer; - std::streamsize index; - std::streamsize bufferSize; - bool full; - std::string givenname; - - public: - OutStringStream(); - ~OutStringStream(); - - void resize(const std::streamsize& size); - bool addData(const char* data, const std::streamoff& size); - void dump(std::ostream& os); - void empty(); -}; - -/// \ingroup plugin -/// -/// \brief Main class of the tracer real-time plug-in. -class DG_TRACERREALTIME_DLLAPI TracerRealTime : public Tracer { - DYNAMIC_GRAPH_ENTITY_DECL(); - - public: - TracerRealTime(const std::string& n); - virtual ~TracerRealTime() {} - - virtual void closeFiles(); - virtual void trace(); - - void display(std::ostream& os) const; - DG_TRACERREALTIME_DLLAPI friend std::ostream& operator<<(std::ostream& os, const TracerRealTime& t); - - protected: - virtual void openFile(const SignalBase<int>& sig, const std::string& filename); - - virtual void recordSignal(std::ostream& os, const SignalBase<int>& sig); - void emptyBuffers(); - - void setBufferSize(const int& SIZE) { bufferSize = SIZE; } - - const int& getBufferSize() { return bufferSize; } - - typedef std::list<std::ofstream*> HardFileList; - static const int BUFFER_SIZE_DEFAULT = 1048576; // 1Mo - - int bufferSize; - HardFileList hardFiles; -}; +namespace dynamicgraph +{ + /// \ingroup plugin + /// + /// \brief Stream for the tracer real-time. + class DG_TRACERREALTIME_DLLAPI OutStringStream : public std::ostringstream + { + public: + char* buffer; + std::streamsize index; + std::streamsize bufferSize; + bool full; + std::string givenname; + + public: + OutStringStream(); + ~OutStringStream(); + + void resize(const std::streamsize& size); + bool addData(const char* data, const std::streamoff& size); + void dump(std::ostream& os); + void empty(); + }; + + /// \ingroup plugin + /// + /// \brief Main class of the tracer real-time plug-in. + class DG_TRACERREALTIME_DLLAPI TracerRealTime : public Tracer + { + DYNAMIC_GRAPH_ENTITY_DECL(); + + public: + TracerRealTime(const std::string& n); + virtual ~TracerRealTime() {} + + virtual void closeFiles(); + virtual void trace(); + + void display(std::ostream& os) const; + DG_TRACERREALTIME_DLLAPI friend std::ostream& operator<< + (std::ostream& os, const TracerRealTime& t); + + protected: + virtual void openFile + (const SignalBase<int>& sig, + const std::string& filename); + + virtual void recordSignal(std::ostream& os, const SignalBase<int>& sig); + void emptyBuffers(); + + void setBufferSize(const int& SIZE) { bufferSize = SIZE; } + + const int& getBufferSize() { return bufferSize; } + + typedef std::list<std::ofstream*> HardFileList; + static const int BUFFER_SIZE_DEFAULT = 1048576; // 1Mo + + int bufferSize; + HardFileList hardFiles; + }; } // end of namespace dynamicgraph #endif //! DYNAMIC_GRAPH_TRACER_REAL_TIME_H diff --git a/include/dynamic-graph/tracer.h b/include/dynamic-graph/tracer.h index d4016c3..4eda968 100644 --- a/include/dynamic-graph/tracer.h +++ b/include/dynamic-graph/tracer.h @@ -17,79 +17,92 @@ #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 () ). +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; }; - 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 diff --git a/include/dynamic-graph/value.h b/include/dynamic-graph/value.h index caf35f9..f15d5a6 100644 --- a/include/dynamic-graph/value.h +++ b/include/dynamic-graph/value.h @@ -13,92 +13,108 @@ #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; +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_; + }; - private: - const Value* value_; -}; + 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; -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; - 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_; -}; - -/* ---- 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 + /* ---- 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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31bf3ad..a4fedf4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,8 +60,8 @@ INSTALL(TARGETS ${LIBRARY_NAME} ### Plugins #################################### SET(plugins_list - traces/tracer - traces/tracer-real-time + traces/tracer + traces/tracer-real-time ) SET(tracer-real-time_dependency tracer) diff --git a/src/command/command.cpp b/src/command/command.cpp index 6f6cb0e..9c09152 100644 --- a/src/command/command.cpp +++ b/src/command/command.cpp @@ -14,22 +14,28 @@ 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) +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_; } +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"); + 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 " + ss << "argument " << iParam << " is of wrong type: " + << Value::typeName(paramTypes[iParam]) << " expected, got " << Value::typeName(values[iParam].type()); throw ExceptionAbstract(ExceptionAbstract::TOOLS, ss.str()); } @@ -38,7 +44,8 @@ void Command::setParameterValues(const std::vector<Value>& values) { 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(); } diff --git a/src/command/value.cpp b/src/command/value.cpp index 3407622..869242d 100644 --- a/src/command/value.cpp +++ b/src/command/value.cpp @@ -7,259 +7,290 @@ #include "dynamic-graph/value.h" #include "dynamic-graph/exception-abstract.h" -namespace dynamicgraph { -namespace command { +namespace dynamicgraph +{ + namespace command + { -static void* copyValue(const Value& value); + static void* copyValue(const Value& value); -EitherType::EitherType(const Value& value) : value_(new Value(value)) {} + EitherType::EitherType(const Value& value) : value_(new Value(value)) {} + + EitherType::~EitherType() + { + delete value_; + 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(); } -EitherType::~EitherType() { - delete value_; - value_ = NULL; -} + 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:; + } + } -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(); } + Value::~Value() { deleteValue(); } -EitherType::operator Eigen::Matrix4d() const { return value_->matrix4dValue(); } + 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)) {} -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(const Value& value) : + type_(value.type_), value_(copyValue(value)) {} -Value::~Value() { deleteValue(); } + 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(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() : type_(NONE), value_(NULL) {} -Value::Value(const Value& value) : type_(value.type_), value_(copyValue(value)) {} + 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; + } -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; -} + const EitherType Value::value() const { return EitherType(*this); } -Value::Value() : type_(NONE), value_(NULL) {} + Value::Type Value::type() const { return type_; } -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::boolValue() const { + if (type_ == BOOL) return *((const bool*)value_); + throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an bool"); + } -const EitherType Value::value() const { return EitherType(*this); } + unsigned Value::unsignedValue() const { + if (type_ == UNSIGNED) return *((const unsigned*)value_); + throw ExceptionAbstract + (ExceptionAbstract::TOOLS, + "value is not an unsigned int"); + } -Value::Type Value::type() const { return type_; } + int Value::intValue() const { + if (type_ == INT) return *((const int*)value_); + throw ExceptionAbstract + (ExceptionAbstract::TOOLS, "value is not an int int"); + } -bool Value::boolValue() const { - if (type_ == BOOL) return *((const bool*)value_); - throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an bool"); -} + float Value::floatValue() const { + float result; + if (FLOAT != type_) + throw ExceptionAbstract + (ExceptionAbstract::TOOLS, "value is not a float"); + result = *((const float*)value_); + return result; + } -unsigned Value::unsignedValue() const { - if (type_ == UNSIGNED) return *((const unsigned*)value_); - throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an unsigned int"); -} + double Value::doubleValue() const { + double result; + if (DOUBLE != type_) + throw ExceptionAbstract + (ExceptionAbstract::TOOLS, "value is not a double"); + result = *((const double*)value_); + return result; + } -int Value::intValue() const { - if (type_ == INT) return *((const int*)value_); - throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an int int"); -} + std::string Value::stringValue() const { + if (type_ == STRING) return *((const std::string*)value_); + throw ExceptionAbstract + (ExceptionAbstract::TOOLS, "value is not an string"); + } -float Value::floatValue() const { - float result; - if (FLOAT != type_) throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a float"); - result = *((const float*)value_); - return result; -} + Vector Value::vectorValue() const { + if (type_ == VECTOR) return *((const Vector*)value_); + throw ExceptionAbstract + (ExceptionAbstract::TOOLS, "value is not an vector"); + } -double Value::doubleValue() const { - double result; - if (DOUBLE != type_) throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not a double"); - result = *((const double*)value_); - return result; -} + Eigen::MatrixXd Value::matrixXdValue() const { + if (type_ == MATRIX) return *((const Eigen::MatrixXd*)value_); + throw ExceptionAbstract + (ExceptionAbstract::TOOLS, "value is not a Eigen matrixXd"); + } -std::string Value::stringValue() const { - if (type_ == STRING) return *((const std::string*)value_); - throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an string"); -} + Eigen::Matrix4d Value::matrix4dValue() const { + if (type_ == MATRIX4D) return *((const Eigen::Matrix4d*)value_); + throw ExceptionAbstract + (ExceptionAbstract::TOOLS, "value is not a Eigen matrix4d"); + } -Vector Value::vectorValue() const { - if (type_ == VECTOR) return *((const Vector*)value_); - throw ExceptionAbstract(ExceptionAbstract::TOOLS, "value is not an vector"); -} + 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"); + } + } -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: + 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; + } return os; - } - return os; -} + } -template <> -const Value::Type ValueHelper<bool>::TypeID = Value::BOOL; -template <> -const Value::Type ValueHelper<unsigned>::TypeID = Value::UNSIGNED; -template <> -const Value::Type ValueHelper<int>::TypeID = Value::INT; -template <> -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<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 command } // namespace dynamicgraph diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index d00085a..1edfec9 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -14,22 +14,26 @@ using namespace dynamicgraph; #ifdef WIN32 -const char *DebugTrace::DEBUG_FILENAME_DEFAULT = "c:/tmp/dynamic-graph-traces.txt"; +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"; +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); +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); +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 ); +std::ofstream dg_debugfile; class dgDebug_init { public: - dgDebug_init() { dg_debugfile.setstate(std::ios::failbit); /* dg_debugfile.close (); */ } + dgDebug_init() { dg_debugfile.setstate(std::ios::failbit); } }; dgDebug_init dgDebug_initialisator; @@ -44,7 +48,6 @@ 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; } void DebugTrace::closeFile(const char *) { @@ -54,5 +57,3 @@ void DebugTrace::closeFile(const char *) { dg_debugfile.setstate(std::ios::failbit); } -// DebugTrace dgDebugFLOW(std::cout); -// DebugTrace dgERRORFLOW(std::cerr); diff --git a/src/debug/logger.cpp b/src/debug/logger.cpp index 0289f4e..c0979bf 100644 --- a/src/debug/logger.cpp +++ b/src/debug/logger.cpp @@ -20,70 +20,85 @@ #include <dynamic-graph/real-time-logger.h> -namespace dynamicgraph { - -using namespace std; - -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 - std::ostringstream oss; - oss << file << line; - std::string id(oss.str()); - map<string, double>::iterator it = m_stream_msg_counters.find(id); - if (it == m_stream_msg_counters.end()) { - // if counter doesn't exist then add one - m_stream_msg_counters.insert(make_pair(id, 0.0)); - it = m_stream_msg_counters.find(id); - } - - // if counter is greater than 0 then decrement it and do not print - if (it->second > 0.0) { - it->second -= m_timeSample; - if (it->second <= 0.0) - it->second = m_streamPrintPeriod; - else - return; - } else // otherwise reset counter and print - it->second = m_streamPrintPeriod; +namespace dynamicgraph +{ + + using namespace std; + + 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; } - dgRTLOG() << msg.c_str() << "\n"; -} -bool Logger::setTimeSample(double t) { - if (t <= 0.0) return false; - m_timeSample = t; - return true; -} + 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 + std::ostringstream oss; + oss << file << line; + std::string id(oss.str()); + map<string, double>::iterator it = m_stream_msg_counters.find(id); + if (it == m_stream_msg_counters.end()) + { + // if counter doesn't exist then add one + m_stream_msg_counters.insert(make_pair(id, 0.0)); + it = m_stream_msg_counters.find(id); + } + + // if counter is greater than 0 then decrement it and do not print + if (it->second > 0.0) + { + it->second -= m_timeSample; + if (it->second <= 0.0) + it->second = m_streamPrintPeriod; + else + return; + } else // otherwise reset counter and print + it->second = m_streamPrintPeriod; + } + dgRTLOG() << msg.c_str() << "\n"; + } -bool Logger::setStreamPrintPeriod(double s) { - if (s <= 0.0) return false; - m_streamPrintPeriod = s; - return true; -} + 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::getTimeSample() + { return m_timeSample; } -double Logger::getStreamPrintPeriod() { return m_streamPrintPeriod; } + double Logger::getStreamPrintPeriod() + { return m_streamPrintPeriod; } } // namespace dynamicgraph diff --git a/src/debug/real-time-logger.cpp b/src/debug/real-time-logger.cpp index c0940f7..24a662b 100644 --- a/src/debug/real-time-logger.cpp +++ b/src/debug/real-time-logger.cpp @@ -11,124 +11,150 @@ #include <boost/thread/thread.hpp> #include <boost/date_time/posix_time/posix_time.hpp> -namespace dynamicgraph { -RealTimeLogger::RealTimeLogger(const std::size_t& bufferSize) - : buffer_(bufferSize, NULL), frontIdx_(0), backIdx_(0), oss_(NULL), nbDiscarded_(0) { - for (std::size_t i = 0; i < buffer_.size(); ++i) buffer_[i] = new Data; -} - -RealTimeLogger::~RealTimeLogger() { - // Check that we are not spinning... - for (std::size_t i = 0; i < buffer_.size(); ++i) delete buffer_[i]; -} - -bool RealTimeLogger::spinOnce() { - if (empty()) return false; - Data* data = buffer_[frontIdx_]; - frontIdx_ = (frontIdx_ + 1) % buffer_.size(); - std::string str = data->buf.str(); - // It is important to pass str.c_str() and not str - // because the str object may contains a '\0' so - // str.size() may be different from strlen(str.c_str()) - for (std::size_t i = 0; i < outputs_.size(); ++i) outputs_[i]->write(str.c_str()); - return true; -} - -RTLoggerStream RealTimeLogger::front() { - // If no output or if buffer is full, discard message. - if (outputs_.empty() || full()) { - nbDiscarded_++; - return RTLoggerStream(NULL, oss_); +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; } - bool alone = wmutex.try_lock(); - // If someone is writting, discard message. - if (!alone) { - nbDiscarded_++; - return RTLoggerStream(NULL, oss_); + + RealTimeLogger::~RealTimeLogger() + { + // Check that we are not spinning... + for (std::size_t i = 0; i < buffer_.size(); ++i) + delete buffer_[i]; } - 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::~RTLoggerStream() { - os_ << std::ends; - if (logger_ != NULL) logger_->frontReady(); -} - -struct RealTimeLogger::thread { - bool requestShutdown_; - int threadPolicy_; - int threadPriority_; - bool changedThreadParams; - boost::thread t_; - - 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; + 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; } - void setPriority(int priority) { - threadPriority_ = priority; - changedThreadParams = 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_); } - int getThreadPolicy() { return threadPolicy_; } - int getThreadPriority() { return threadPriority_; } + RTLoggerStream::~RTLoggerStream() + { + os_ << std::ends; + if (logger_ != NULL) logger_->frontReady(); + } - 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); + struct RealTimeLogger::thread + { + bool requestShutdown_; + int threadPolicy_; + int threadPriority_; + bool changedThreadParams; + boost::thread t_; - pthread_setschedparam(pthread_self(), threadPolicy, &threadParam); - changedThreadParams = false; + 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 spin(RealTimeLogger* logger) { - // Change the thread's scheduler from real-time to normal - // and reduce its priority + void setPriority(int priority) + { + threadPriority_ = priority; + changedThreadParams = true; + } - 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(); + int getThreadPolicy() { return threadPolicy_; } + int getThreadPriority() { return threadPriority_; } + + void changeThreadParams() + { + int threadPolicy; + struct sched_param threadParam; + if (pthread_getschedparam(pthread_self(), + &threadPolicy, + &threadParam) == 0) + { + threadPolicy = threadPolicy_; + threadParam.sched_priority = threadPriority_; + if (threadParam.sched_priority < sched_get_priority_min(threadPolicy)) + threadParam.sched_priority = sched_get_priority_min(threadPolicy); + + pthread_setschedparam(pthread_self(), threadPolicy, &threadParam); + changedThreadParams = false; + } + } + + void spin(RealTimeLogger* logger) + { + // Change the thread's scheduler from real-time to normal + // and reduce its priority + + while (!requestShutdown_ || !logger->empty()) + { + // If the logger did not write anything, it means the buffer is empty. + // Do a pause + if (!logger->spinOnce()) + boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); + if (changedThreadParams) changeThreadParams(); + } } + }; + + RealTimeLogger* RealTimeLogger::instance_ = NULL; + RealTimeLogger::thread* RealTimeLogger::thread_ = NULL; + + RealTimeLogger& RealTimeLogger::instance() + { + if (instance_ == NULL) + { + instance_ = new RealTimeLogger(1000); + thread_ = new thread(instance_); + } + return *instance_; } -}; - -RealTimeLogger* RealTimeLogger::instance_ = NULL; -RealTimeLogger::thread* RealTimeLogger::thread_ = NULL; -RealTimeLogger& RealTimeLogger::instance() { - if (instance_ == NULL) { - instance_ = new RealTimeLogger(1000); - thread_ = new thread(instance_); + void RealTimeLogger::destroy() + { + if (instance_ == NULL) return; + thread_->requestShutdown_ = true; + thread_->t_.join(); + delete instance_; + delete thread_; } - return *instance_; -} - -void RealTimeLogger::destroy() { - if (instance_ == NULL) return; - thread_->requestShutdown_ = true; - thread_->t_.join(); - delete instance_; - delete thread_; -} } // namespace dynamicgraph diff --git a/src/dgraph/entity.cpp b/src/dgraph/entity.cpp index a13d290..1ee2bbc 100644 --- a/src/dgraph/entity.cpp +++ b/src/dgraph/entity.cpp @@ -22,57 +22,73 @@ 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() { PoolStorage::getInstance()->deregisterEntity(name); } +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(); - } + if (name.length() == 0) + { + stringstream oss; + oss << rand(); + // name = this->getClassName(); + // Cannot call a virtual function from the constructor + name += "::"; + name += oss.str(); + } entityRegistration(); } Entity::~Entity() { dgDEBUG(25) << "# In (" << name << " { " << endl; - for (std::map<const std::string, Command*>::iterator it = commandMap.begin(); it != commandMap.end(); it++) { - delete it->second; - } + for (std::map<const std::string, Command*>::iterator it = + commandMap.begin(); it != commandMap.end(); it++) + { + delete it->second; + } dgDEBUGOUT(25); } /* -------------------------------------------------------------------------- */ /* --- 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 +void Entity::signalRegistration(const SignalArray<int>& signals) +{ + for (unsigned int i = 0; i < signals.getSize(); ++i) { - 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; + 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; } } @@ -83,10 +99,14 @@ void Entity::signalDeregistration(const std::string& 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()); + 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; + dgDEBUG(10) << "Deregister signal <" + << signame << "> for entity <" + << getName() << "> ." << endl; signalMap.erase(signame); } } @@ -96,56 +116,72 @@ std::string Entity::getDocString() const { 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()); \ - } \ +#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) { __DG_ENTITY_GET_SIGNAL__(iterator); } +SignalBase<int>& Entity::getSignal(const string& signame) +{ __DG_ENTITY_GET_SIGNAL__(iterator); } -const SignalBase<int>& Entity::getSignal(const string& signame) const { __DG_ENTITY_GET_SIGNAL__(const_iterator); } +const SignalBase<int>& Entity::getSignal(const string& signame) const +{ __DG_ENTITY_GET_SIGNAL__(const_iterator); } -std::ostream& Entity::displaySignalList(std::ostream& os) const { +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; - } + 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 { +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); - } + for (SignalMap::const_iterator iter = signalMap.begin(); + iterend != iter; ++iter) + { + (*(iter->second)).writeGraph(os); + } return os; } -std::ostream& Entity::writeCompletionList(std::ostream& os) const { +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; - } + for (SignalMap::const_iterator iter = signalMap.begin(); + iterend != iter; ++iter) + { + os << getName() << "." << (*(iter->second)).shortName() << 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; } @@ -157,29 +193,35 @@ Entity::SignalMap Entity::getSignalMap() const { return signalMap; } /* --- PARAMS --------------------------------------------------------------- */ static std::string Entity_COMMAND_LIST = "print\nsignals\nsignalDep"; -const std::string& Entity::getCommandList() const { return Entity_COMMAND_LIST; } +const std::string& Entity::getCommandList() const +{ return Entity_COMMAND_LIST; } /// Add a command to Entity 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."); + "Command " + inName + + " already registered in Entity."); } 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() { return commandMap; } +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 <" + commandName + + "> is not registered in Entity."); } return commandMap[commandName]; } -void Entity::sendMsg(const std::string& msg, MsgType t, const char* file, int line) { +void Entity::sendMsg +(const std::string& msg, MsgType t, const char* file, int line) +{ logger_.sendMsg("[" + name + "]" + msg, t, file, line); } diff --git a/src/dgraph/factory.cpp b/src/dgraph/factory.cpp index 326f137..0e5c75c 100644 --- a/src/dgraph/factory.cpp +++ b/src/dgraph/factory.cpp @@ -10,97 +10,131 @@ using namespace std; using namespace dynamicgraph; -namespace dynamicgraph { -FactoryStorage* FactoryStorage::getInstance() { - if (instance_ == 0) { - instance_ = new FactoryStorage; +namespace dynamicgraph +{ + FactoryStorage* FactoryStorage::getInstance() + { + if (instance_ == 0) + { + instance_ = new FactoryStorage; + } + return instance_; } - return instance_; -} -void FactoryStorage::destroy() { +void FactoryStorage::destroy() +{ delete instance_; instance_ = NULL; } FactoryStorage::FactoryStorage() : entityMap() {} -FactoryStorage::~FactoryStorage() { +FactoryStorage::~FactoryStorage() +{ instance_ = 0; dgDEBUGINOUT(25); } -void FactoryStorage::registerEntity(const std::string& entname, FactoryStorage::EntityConstructor_ptr ent) { +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."); + 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; } - - dgDEBUG(30) << "Register entity <" << entname << "> in the factory." << std::endl; - entityMap[entname] = ent; - } dgDEBUGOUT(25); } -void FactoryStorage::deregisterEntity(const std::string& entname) { +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); - } + 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; +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()); - } + 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 { +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 { +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) { +EntityRegisterer::EntityRegisterer +(const std::string& entityClassName, + FactoryStorage::EntityConstructor_ptr maker) + : entityName(entityClassName) +{ dgDEBUGIN(15); FactoryStorage::getInstance()->registerEntity(entityClassName, maker); dgDEBUGOUT(15); } -EntityRegisterer::~EntityRegisterer() { +EntityRegisterer::~EntityRegisterer() +{ dgDEBUGIN(15); FactoryStorage::getInstance()->deregisterEntity(entityName); dgDEBUGOUT(15); diff --git a/src/dgraph/pool.cpp b/src/dgraph/pool.cpp index 0d19738..b27056f 100644 --- a/src/dgraph/pool.cpp +++ b/src/dgraph/pool.cpp @@ -26,75 +26,99 @@ using namespace dynamicgraph; /* --- CLASS ----------------------------------------------------------- */ /* --------------------------------------------------------------------- */ -PoolStorage* PoolStorage::getInstance() { - if (instance_ == 0) { - instance_ = new PoolStorage; - } +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(); // 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; + 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>.", + 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; + 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) { +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>)", + DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_OBJECT, + "Unknown entity.", " (while calling <%s>)", name.c_str()); } else return *entPtr->second; } -const PoolStorage::Entities& PoolStorage::getEntityMap() const { return entityMap; } +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) { +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; @@ -104,14 +128,19 @@ bool PoolStorage::existEntity(const std::string& name, Entity*& ptr) { } } -void PoolStorage::clearPlugin(const std::string& name) { +void PoolStorage::clearPlugin(const std::string& name) +{ dgDEBUGIN(5); 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); } @@ -123,7 +152,8 @@ void PoolStorage::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); size_t IdxSeparatorFound = aFileName.rfind("/"); @@ -145,40 +175,54 @@ void PoolStorage::writeGraph(const std::string& aFileName) { /* Opening the file and writing the first comment. */ 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 << ":" + 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 << " */" << 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 ] ; " + 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.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) { +static bool objectNameParser +(std::istringstream& cmdparse, + std::string& objName, std::string& funName) +{ const int SIZE = 128; char buffer[SIZE]; cmdparse >> std::ws; @@ -193,10 +237,12 @@ static bool objectNameParser(std::istringstream& cmdparse, std::string& objName, return true; } -SignalBase<int>& PoolStorage::getSignal(std::istringstream& sigpath) { +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"); + DG_THROW ExceptionFactory(ExceptionFactory::UNREFERED_SIGNAL, + "Parse error in signal name"); } Entity& ent = getEntity(objname); diff --git a/src/exception/exception-abstract.cpp b/src/exception/exception-abstract.cpp index 31fe603..3efc207 100644 --- a/src/exception/exception-abstract.cpp +++ b/src/exception/exception-abstract.cpp @@ -6,47 +6,60 @@ #include <dynamic-graph/exception-abstract.h> #include <dynamic-graph/debug.h> -namespace dynamicgraph { -const std::string ExceptionAbstract::EXCEPTION_NAME = "Abstract"; +namespace dynamicgraph +{ + const std::string ExceptionAbstract::EXCEPTION_NAME = "Abstract"; -ExceptionAbstract::ExceptionAbstract(const int& _code, const std::string& _msg) : code(_code), message(_msg) {} + ExceptionAbstract::ExceptionAbstract + (const int& _code, const std::string& _msg) + : code(_code), message(_msg) {} -const char* ExceptionAbstract::getMessage() const { return (this->message).c_str(); } + const char* ExceptionAbstract::getMessage() const + { return (this->message).c_str(); } -const std::string& ExceptionAbstract::getStringMessage() const { return this->message; } + const std::string& ExceptionAbstract::getStringMessage() const + { return this->message; } -int ExceptionAbstract::getCode() const { return this->code; } + int ExceptionAbstract::getCode() const { return this->code; } -ExceptionAbstract::Param& ExceptionAbstract::Param::initCopy(const Param& p) { - if (&p == this) return *this; + 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; -} + 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); -} + 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; + 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; + 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. diff --git a/src/exception/exception-factory.cpp b/src/exception/exception-factory.cpp index 4469f05..78e1b8d 100644 --- a/src/exception/exception-factory.cpp +++ b/src/exception/exception-factory.cpp @@ -20,15 +20,20 @@ using namespace dynamicgraph; const std::string ExceptionFactory::EXCEPTION_NAME = "Factory"; -ExceptionFactory::ExceptionFactory(const ExceptionFactory::ErrorCodeEnum& errcode, const std::string& msg) - : ExceptionAbstract(errcode, msg) { +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); @@ -37,7 +42,8 @@ ExceptionFactory::ExceptionFactory(const ExceptionFactory::ErrorCodeEnum& errcod vsnprintf(buffer, SIZE, format, args); dgDEBUG(15) << "Created " - << " with message <" << msg << "> and buffer <" << buffer << ">. " << std::endl; + << " with message <" << msg << "> and buffer <" + << buffer << ">. " << std::endl; message += buffer; diff --git a/src/exception/exception-signal.cpp b/src/exception/exception-signal.cpp index 1fa5c23..7713fa5 100644 --- a/src/exception/exception-signal.cpp +++ b/src/exception/exception-signal.cpp @@ -19,12 +19,17 @@ 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, - const char* format, ...) - : 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) +{ va_list args; va_start(args, format); diff --git a/src/exception/exception-traces.cpp b/src/exception/exception-traces.cpp index a97d81b..970ae14 100644 --- a/src/exception/exception-traces.cpp +++ b/src/exception/exception-traces.cpp @@ -18,12 +18,17 @@ using namespace dynamicgraph; const std::string ExceptionTraces::EXCEPTION_NAME = "Traces"; -ExceptionTraces::ExceptionTraces(const ExceptionTraces::ErrorCodeEnum& errcode, const std::string& 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); diff --git a/src/mt/process-list.cpp b/src/mt/process-list.cpp index 94dbdad..8b3b7aa 100644 --- a/src/mt/process-list.cpp +++ b/src/mt/process-list.cpp @@ -22,9 +22,12 @@ CPUData::CPUData() 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; +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; @@ -42,12 +45,14 @@ void CPUData::ProcessLine(std::istringstream &aCPULine) { 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; + 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; + 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_); @@ -126,25 +131,29 @@ void System::readProcStat() { 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 (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 (int i = 0; i < (int)cpuNb_; i++) vCPUData_[i].cpu_id_ = i; - } + if (!init_) + { + /// The number of CPU has been detected by going through /proc/stat. + vCPUData_.resize(cpuNb_ + 1); + for (int i = 0; i < (int)cpuNb_; i++) vCPUData_[i].cpu_id_ = i; + } aif.close(); } diff --git a/src/signal/signal-cast-helper.cpp b/src/signal/signal-cast-helper.cpp index 73de6dd..c31c565 100644 --- a/src/signal/signal-cast-helper.cpp +++ b/src/signal/signal-cast-helper.cpp @@ -1,5 +1,8 @@ // -*- c++-mode -*- -// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse, Nicolas Mansard +// Copyright 2010 François Bleibel +// Thomas Moulard, +// Olivier Stasse, +// Nicolas Mansard // #include <boost/date_time/posix_time/posix_time.hpp> @@ -14,68 +17,79 @@ #include <dynamic-graph/exception-signal.h> #include <dynamic-graph/linear-algebra.h> -namespace dynamicgraph { +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). + // 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; + 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(); + 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()); + 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. */ + /* 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); + 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. + /// 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 diff --git a/src/signal/signal-caster.cpp b/src/signal/signal-caster.cpp index abdc732..790ea6e 100644 --- a/src/signal/signal-caster.cpp +++ b/src/signal/signal-caster.cpp @@ -1,5 +1,7 @@ // -*- c++-mode -*- -// Copyright 2010 François Bleibel Thomas Moulard, Olivier Stasse +// Copyright 2010 François Bleibel +// Thomas Moulard, +// Olivier Stasse // #include <dynamic-graph/signal-caster.h> @@ -15,82 +17,104 @@ namespace dynamicgraph { -SignalCaster::SignalCaster() {} - -SignalCaster::~SignalCaster() {} - -void SignalCaster::destroy() { - delete instance_; - instance_ = 0; -} - -void SignalCaster::registerCast(const std::type_info& type, SignalCaster::displayer_type displayer, - SignalCaster::caster_type caster, SignalCaster::tracer_type tracer) { - if (existsCast(type)) { - // If type name has already been registered for same type, do not throw. - if (type_info_[type.name()] != &type) { - std::string typeName(type.name()); - std::ostringstream os; - os << "cast already registered for typename " << typeName << "\n" - << "and types differ: " << &type << " != " << type_info_[type.name()] << ".\n" - << "A possible reason is that the dynamic" - << " library defining this type\n" - << "has been loaded several times, defining different symbols" - << " for the same type."; - throw ExceptionSignal(ExceptionSignal::GENERIC, os.str()); + SignalCaster::SignalCaster() {} + + SignalCaster::~SignalCaster() {} + + void SignalCaster::destroy() + { + delete instance_; + instance_ = 0; + } + + void SignalCaster::registerCast + (const std::type_info& type, + SignalCaster::displayer_type displayer, + SignalCaster::caster_type caster, + SignalCaster::tracer_type tracer) + { + if (existsCast(type)) { + // If type name has already been registered for same type, do not throw. + if (type_info_[type.name()] != &type) { + std::string typeName(type.name()); + std::ostringstream os; + os << "cast already registered for typename " + << typeName << "\n" + << "and types differ: " << &type << " != " + << type_info_[type.name()] << ".\n" + << "A possible reason is that the dynamic" + << " library defining this type\n" + << "has been loaded several times, defining different symbols" + << " for the same type."; + throw ExceptionSignal(ExceptionSignal::GENERIC, os.str()); + } } + functions_[type.name()] = cast_functions_type(displayer, caster, tracer); + type_info_[type.name()] = &type; + } + + void SignalCaster::unregisterCast(const std::type_info& type) + { + size_t n = functions_.erase(type.name()); + if (0 == n) // erase did not find element + // TODO: throw Cast not registered exception + throw ExceptionSignal(ExceptionSignal::GENERIC); } - functions_[type.name()] = cast_functions_type(displayer, caster, tracer); - type_info_[type.name()] = &type; -} - -void SignalCaster::unregisterCast(const std::type_info& type) { - size_t n = functions_.erase(type.name()); - if (0 == n) // erase did not find element - // TODO: throw Cast not registered exception - throw ExceptionSignal(ExceptionSignal::GENERIC); -} - -bool SignalCaster::existsCast(const std::type_info& type) const { - return functions_.find(type.name()) != functions_.end(); -} - -SignalCaster::cast_functions_type& SignalCaster::getCast(const std::string& type_name) { - std::map<std::string, cast_functions_type>::iterator it = functions_.find(type_name); - - if (it == functions_.end()) - // TODO: throw "cast not registered" exception - throw ExceptionSignal(ExceptionSignal::BAD_CAST, "Cast not registered"); - return it->second; -} - -void SignalCaster::disp(const boost::any& object, std::ostream& os) { - getCast(object.type().name()).get<0>()(object, os); -} - -void SignalCaster::trace(const boost::any& object, std::ostream& os) { - getCast(object.type().name()).get<2>()(object, os); -} - -std::vector<std::string> SignalCaster::listTypenames() const { - std::vector<std::string> typeList; - for (std::map<std::string, cast_functions_type>::const_iterator iter = functions_.begin(); iter != functions_.end(); - iter++) - typeList.push_back(iter->first); - return typeList; -} - -boost::any SignalCaster::cast(const std::type_info& type, std::istringstream& iss) { - return getCast(type.name()).get<1>()(iss); -} - -/// Singleton on the library-wide instance of SignalCaster -SignalCaster* SignalCaster::getInstance(void) { - if (instance_ == 0) { - instance_ = new SignalCaster; + + bool SignalCaster::existsCast(const std::type_info& type) const + { + return functions_.find(type.name()) != functions_.end(); + } + + SignalCaster::cast_functions_type& + SignalCaster::getCast + (const std::string& type_name) + { + std::map<std::string, cast_functions_type>::iterator it = + functions_.find(type_name); + + if (it == functions_.end()) + // TODO: throw "cast not registered" exception + throw ExceptionSignal(ExceptionSignal::BAD_CAST, "Cast not registered"); + return it->second; + } + + void SignalCaster::disp(const boost::any& object, std::ostream& os) + { + getCast(object.type().name()).get<0>()(object, os); } - return instance_; -} -SignalCaster* SignalCaster::instance_ = 0; + + void SignalCaster::trace(const boost::any& object, std::ostream& os) + { + getCast(object.type().name()).get<2>()(object, os); + } + + std::vector<std::string> SignalCaster::listTypenames() const + { + std::vector<std::string> typeList; + for (std::map<std::string, cast_functions_type>::const_iterator + iter = functions_.begin(); iter != functions_.end(); + iter++) + typeList.push_back(iter->first); + return typeList; + } + + boost::any + SignalCaster::cast + (const std::type_info& type, std::istringstream& iss) + { + return getCast(type.name()).get<1>()(iss); + } + + /// Singleton on the library-wide instance of SignalCaster + SignalCaster* SignalCaster::getInstance(void) + { + if (instance_ == 0) { + instance_ = new SignalCaster; + } + return instance_; + } + + SignalCaster* SignalCaster::instance_ = 0; } // namespace dynamicgraph diff --git a/src/traces/tracer-real-time.cpp b/src/traces/tracer-real-time.cpp index 505e97c..9a5388e 100644 --- a/src/traces/tracer-real-time.cpp +++ b/src/traces/tracer-real-time.cpp @@ -30,7 +30,9 @@ DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(TracerRealTime, "TracerRealTime"); /* --- DGOUTSTRINGSTREAM ---------------------------------------------- */ /* --------------------------------------------------------------------- */ -OutStringStream::OutStringStream() : std::ostringstream(), buffer(0), index(0), bufferSize(0), full(false) { +OutStringStream::OutStringStream() : + std::ostringstream(), buffer(0), index(0), bufferSize(0), full(false) +{ dgDEBUGINOUT(15); } @@ -84,17 +86,26 @@ void OutStringStream::empty() { /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ -TracerRealTime::TracerRealTime(const std::string& n) : Tracer(n), bufferSize(BUFFER_SIZE_DEFAULT) { +TracerRealTime::TracerRealTime(const std::string& n) : + Tracer(n), + bufferSize(BUFFER_SIZE_DEFAULT) +{ dgDEBUGINOUT(15); /* --- Commands --- */ { using namespace dynamicgraph::command; - std::string doc = docCommandVoid0("Trash the current content of the buffers, without saving it."); - addCommand("empty", makeCommandVoid0(*this, &TracerRealTime::emptyBuffers, doc)); - - addCommand("getBufferSize", makeDirectGetter(*this, &bufferSize, docDirectGetter("bufferSize", "int"))); - addCommand("setBufferSize", makeDirectSetter(*this, &bufferSize, docDirectSetter("bufferSize", "int"))); + std::string doc = docCommandVoid0 + ("Trash the current content of the buffers, without saving it."); + addCommand("empty", makeCommandVoid0 + (*this, &TracerRealTime::emptyBuffers, doc)); + + addCommand("getBufferSize", + makeDirectGetter(*this, &bufferSize, + docDirectGetter("bufferSize", "int"))); + addCommand("setBufferSize", + makeDirectSetter(*this, &bufferSize, + docDirectSetter("bufferSize", "int"))); } // using namespace command dgDEBUGOUT(15); @@ -104,7 +115,10 @@ TracerRealTime::TracerRealTime(const std::string& n) : Tracer(n), bufferSize(BUF /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ -void TracerRealTime::openFile(const SignalBase<int>& sig, const std::string& givenname) { +void TracerRealTime::openFile +(const SignalBase<int>& sig, + const std::string& givenname) +{ dgDEBUGIN(15); string signame; if (givenname.length()) { @@ -167,35 +181,38 @@ void TracerRealTime::trace() { dgDEBUG(35) << "Next" << endl; std::ostream* os = *iter; if (NULL == os) { - DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "The buffer is null", ""); + DG_THROW ExceptionTraces + (ExceptionTraces::NOT_OPEN, "The buffer is null", ""); } // std::stringstream & file = * dynamic_cast< stringstream* >(os); OutStringStream* file = dynamic_cast<OutStringStream*>(os); // segfault if (NULL == file) { - DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "The buffer is not open", ""); + DG_THROW ExceptionTraces + (ExceptionTraces::NOT_OPEN, "The buffer is not open", ""); } std::ofstream& hardFile = **hardIter; if (!hardFile.good()) { - DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "The file is not open", ""); + DG_THROW ExceptionTraces + (ExceptionTraces::NOT_OPEN, "The file is not open", ""); } if ((hardFile.good()) && (NULL != file)) { - // const unsigned int SIZE = 1024*8; - // char buffer[SIZE]; - // streambuf * pbuf = file.rdbuf (); - // pbuf->pubseekpos(0); - // const unsigned int NB_BYTE = pbuf->in_avail (); - // dgDEBUG(35) << "Bytes in buffer: " << NB_BYTE << endl; - // //dgDEBUG(35) << "Copie" <<endl<<file.str ()<< endl; - - // for( unsigned int index=0;index<NB_BYTE;index+=SIZE ) - // { - // pbuf->pubseekpos( index ); - // int nget = pbuf->sgetn( buffer,SIZE ); - // dgDEBUG(35) << "Copie ["<<nget<<"] " <<buffer<<endl; - // hardFile.write( buffer,nget ); - // } + // const unsigned int SIZE = 1024*8; + // char buffer[SIZE]; + // streambuf * pbuf = file.rdbuf (); + // pbuf->pubseekpos(0); + // const unsigned int NB_BYTE = pbuf->in_avail (); + // dgDEBUG(35) << "Bytes in buffer: " << NB_BYTE << endl; + // //dgDEBUG(35) << "Copie" <<endl<<file.str ()<< endl; + + // for( unsigned int index=0;index<NB_BYTE;index+=SIZE ) + // { + // pbuf->pubseekpos( index ); + // int nget = pbuf->sgetn( buffer,SIZE ); + // dgDEBUG(35) << "Copie ["<<nget<<"] " <<buffer<<endl; + // hardFile.write( buffer,nget ); + // } // hardFile << file.str () << flush; // file.seekp(0); @@ -215,16 +232,18 @@ void TracerRealTime::trace() { void TracerRealTime::emptyBuffers() { dgDEBUGIN(15); - for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) { - // std::stringstream & file = * dynamic_cast< stringstream* >(*iter); - try { - OutStringStream& file = *dynamic_cast<OutStringStream*>(*iter); - file.empty(); - // file.str(""); - } catch (...) { - DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "The buffer is not open", ""); + for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) + { + // std::stringstream & file = * dynamic_cast< stringstream* >(*iter); + try { + OutStringStream& file = *dynamic_cast<OutStringStream*>(*iter); + file.empty(); + // file.str(""); + } catch (...) { + DG_THROW ExceptionTraces + (ExceptionTraces::NOT_OPEN, "The buffer is not open", ""); + } } - } dgDEBUGOUT(15); } @@ -235,22 +254,27 @@ void TracerRealTime::emptyBuffers() { // pbuf->file.rdbuf () ->pubsetbuf( fileBuffer,10 ); // } -void TracerRealTime::recordSignal(std::ostream& os, const SignalBase<int>& sig) { +void TracerRealTime::recordSignal +(std::ostream& os, const SignalBase<int>& sig) +{ dgDEBUGIN(15); try { OutStringStream& file = dynamic_cast<OutStringStream&>(os); file.str(""); - dgDEBUG(45) << "Empty file [" << file.tellp() << "] <" << file.str().c_str() << "> " << endl; + dgDEBUG(45) << "Empty file [" << file.tellp() << "] <" + << file.str().c_str() << "> " << endl; Tracer::recordSignal(file, sig); file.addData(file.str().c_str(), file.tellp()); - dgDEBUG(35) << "Write data [" << file.tellp() << "] <" << file.str().c_str() << "> " << endl; + dgDEBUG(35) << "Write data [" << file.tellp() << "] <" + << file.str().c_str() << "> " << endl; } catch (ExceptionAbstract& exc) { throw exc; } catch (...) { - DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "The buffer is not open", ""); + DG_THROW ExceptionTraces + (ExceptionTraces::NOT_OPEN, "The buffer is not open", ""); } dgDEBUGOUT(15); @@ -262,11 +286,13 @@ void TracerRealTime::recordSignal(std::ostream& os, const SignalBase<int>& sig) /* --------------------------------------------------------------------- */ void TracerRealTime::display(std::ostream& os) const { - os << CLASS_NAME << " " << name << " [mode=" << (play ? "play" : "pause") << "] : " << endl + os << CLASS_NAME << " " << name + << " [mode=" << (play ? "play" : "pause") << "] : " << endl << " - Dep list: " << endl; FileList::const_iterator iterFile = files.begin(); - for (SignalList::const_iterator iter = toTraceSignals.begin(); toTraceSignals.end() != iter; ++iter) { + for (SignalList::const_iterator iter = toTraceSignals.begin(); + toTraceSignals.end() != iter; ++iter) { dgDEBUG(35) << "Next" << endl; const OutStringStream* file = dynamic_cast<OutStringStream*>(*iterFile); os << " -> " << (*iter)->getName(); @@ -288,8 +314,10 @@ void TracerRealTime::display(std::ostream& os) const { dec = 10; unit = "Ko"; } - os << "[" << std::setw(1) << std::setprecision(1) << (((double)SIZE + 0.0) / (1 << dec)) << unit << "/" - << std::setprecision(2) << (((double)MSIZE + 0.0) / (1 << dec)) << unit << "]\t"; + os << "[" << std::setw(1) << std::setprecision(1) + << (((double)SIZE + 0.0) / (1 << dec)) << unit << "/" + << std::setprecision(2) + << (((double)MSIZE + 0.0) / (1 << dec)) << unit << "]\t"; if (file->full) os << "(FULL)"; os.precision(PRECISION); } diff --git a/src/traces/tracer.cpp b/src/traces/tracer.cpp index 84deaa9..17d6256 100644 --- a/src/traces/tracer.cpp +++ b/src/traces/tracer.cpp @@ -43,7 +43,9 @@ Tracer::Tracer(const std::string n) names(), play(false), timeStart(0), - triger(boost::bind(&Tracer::recordTrigger, this, _1, _2), sotNOSIGNAL, "Tracer(" + n + ")::triger") { + triger(boost::bind(&Tracer::recordTrigger, this, _1, _2), + sotNOSIGNAL, "Tracer(" + n + ")::triger") +{ signalRegistration(triger); /* --- Commands --- */ @@ -51,11 +53,17 @@ Tracer::Tracer(const std::string n) using namespace dynamicgraph::command; std::string doc; - doc = docCommandVoid2("Add a new signal to trace.", "string (signal name)", "string (filename, empty for default"); - addCommand("add", makeCommandVoid2(*this, &Tracer::addSignalToTraceByName, doc)); + doc = docCommandVoid2("Add a new signal to trace.", + "string (signal name)", + "string (filename, empty for default"); + addCommand("add", + makeCommandVoid2(*this, + &Tracer::addSignalToTraceByName, doc)); - doc = docCommandVoid0("Remove all signals. If necessary, close open files."); - addCommand("clear", makeCommandVoid0(*this, &Tracer::clearSignalToTrace, doc)); + doc = docCommandVoid0 + ("Remove all signals. If necessary, close open files."); + addCommand("clear", makeCommandVoid0 + (*this, &Tracer::clearSignalToTrace, doc)); doc = docCommandVoid3( "Gives the args for file opening, and " @@ -77,8 +85,12 @@ Tracer::Tracer(const std::string n) doc = docCommandVoid0("Stop temporarily the tracing process."); addCommand("stop", makeCommandVoid0(*this, &Tracer::stop, doc)); - addCommand("getTimeStart", makeDirectGetter(*this, &timeStart, docDirectGetter("timeStart", "int"))); - addCommand("setTimeStart", makeDirectSetter(*this, &timeStart, docDirectSetter("timeStart", "int"))); + addCommand("getTimeStart", + makeDirectGetter(*this, &timeStart, + docDirectGetter("timeStart", "int"))); + addCommand("setTimeStart", + makeDirectSetter(*this, &timeStart, + docDirectSetter("timeStart", "int"))); } // using namespace command } @@ -86,7 +98,10 @@ Tracer::Tracer(const std::string n) /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ -void Tracer::addSignalToTrace(const SignalBase<int>& sig, const string& filename) { +void Tracer::addSignalToTrace +(const SignalBase<int>& sig, + const string& filename) +{ dgDEBUGIN(15); toTraceSignals.push_back(&sig); dgDEBUGF(15, "%p", &sig); @@ -96,7 +111,10 @@ void Tracer::addSignalToTrace(const SignalBase<int>& sig, const string& filename dgDEBUGOUT(15); } -void Tracer::addSignalToTraceByName(const string& signame, const string& filename) { +void Tracer::addSignalToTraceByName +(const string& signame, + const string& filename) +{ dgDEBUGIN(15); istringstream iss(signame); SignalBase<int>& sig = PoolStorage::getInstance()->getSignal(iss); @@ -108,7 +126,8 @@ void Tracer::addSignalToTraceByName(const string& signame, const string& filenam * does not modify the file list (it does not close * the files in particular. */ -void Tracer::clearSignalToTrace() { +void Tracer::clearSignalToTrace() +{ closeFiles(); toTraceSignals.clear(); triger.clearDependencies(); @@ -120,7 +139,11 @@ void Tracer::clearSignalToTrace() { // triger.parasite(sig); // } -void Tracer::openFiles(const std::string& rootdir_, const std::string& basename_, const std::string& suffix_) { +void Tracer::openFiles +(const std::string& rootdir_, + const std::string& basename_, + const std::string& suffix_) +{ dgDEBUGIN(15); std::basic_string<char>::size_type n = rootdir_.length(); rootdir = rootdir_; @@ -134,7 +157,8 @@ void Tracer::openFiles(const std::string& rootdir_, const std::string& basename_ SignalList::const_iterator iter = toTraceSignals.begin(); NameList::const_iterator iterName = names.begin(); while (toTraceSignals.end() != iter) { - dgDEBUG(15) << "Open <" << (*iter)->getName() << "> in <" << *iterName << ">." << std::endl; + dgDEBUG(15) << "Open <" << (*iter)->getName() + << "> in <" << *iterName << ">." << std::endl; openFile(**iter, *iterName); ++iter; ++iterName; @@ -144,7 +168,10 @@ void Tracer::openFiles(const std::string& rootdir_, const std::string& basename_ dgDEBUGOUT(15); } -void Tracer::openFile(const SignalBase<int>& sig, const string& givenname) { +void Tracer::openFile +(const SignalBase<int>& sig, + const string& givenname) +{ dgDEBUGIN(15); string signame; if (givenname.length()) { @@ -161,7 +188,8 @@ void Tracer::openFile(const SignalBase<int>& sig, const string& givenname) { dgDEBUGOUT(15); } -void Tracer::closeFiles() { +void Tracer::closeFiles() +{ dgDEBUGIN(15); for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) { @@ -177,7 +205,8 @@ void Tracer::closeFiles() { /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ -void Tracer::record() { +void Tracer::record() +{ if (!play) { dgDEBUGINOUT(15); return; @@ -185,24 +214,30 @@ void Tracer::record() { dgDEBUGIN(15); - if (files.size() != toTraceSignals.size()) { - DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "No files open for tracing", " (file=%d != %d=sig).", - files.size(), toTraceSignals.size()); - } + if (files.size() != toTraceSignals.size()) + { + DG_THROW + ExceptionTraces(ExceptionTraces::NOT_OPEN, + "No files open for tracing", + " (file=%d != %d=sig).", + files.size(), toTraceSignals.size()); + } FileList::iterator iterFile = files.begin(); SignalList::iterator iterSig = toTraceSignals.begin(); - while (toTraceSignals.end() != iterSig) { - dgDEBUG(45) << "Try..." << endl; - recordSignal(**iterFile, **iterSig); - ++iterSig; - ++iterFile; - } + while (toTraceSignals.end() != iterSig) + { + dgDEBUG(45) << "Try..." << endl; + recordSignal(**iterFile, **iterSig); + ++iterSig; + ++iterFile; + } dgDEBUGOUT(15); } -void Tracer::recordSignal(std::ostream& os, const SignalBase<int>& sig) { +void Tracer::recordSignal(std::ostream& os, const SignalBase<int>& sig) +{ dgDEBUGIN(15); try { @@ -220,7 +255,8 @@ void Tracer::recordSignal(std::ostream& os, const SignalBase<int>& sig) { dgDEBUGOUT(15); } -int& Tracer::recordTrigger(int& dummy, const int& time) { +int& Tracer::recordTrigger(int& dummy, const int& time) +{ dgDEBUGIN(15) << " time=" << time << endl; record(); dgDEBUGOUT(15); @@ -233,15 +269,20 @@ void Tracer::trace() {} /* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */ -void Tracer::display(std::ostream& os) const { - os << CLASS_NAME << " " << name << " [mode=" << (play ? "play" : "pause") << "] : " << endl +void Tracer::display(std::ostream& os) const +{ + os << CLASS_NAME << " " << name << " [mode=" + << (play ? "play" : "pause") << "] : " << endl << " - Dep list: " << endl; - for (SignalList::const_iterator iter = toTraceSignals.begin(); toTraceSignals.end() != iter; ++iter) { - os << " -> " << (*iter)->getName() << endl; - } + for (SignalList::const_iterator iter = toTraceSignals.begin(); + toTraceSignals.end() != iter; ++iter) + { + os << " -> " << (*iter)->getName() << endl; + } } -std::ostream& operator<<(std::ostream& os, const Tracer& t) { +std::ostream& operator<<(std::ostream& os, const Tracer& t) +{ t.display(os); return os; } diff --git a/tests/command-test.cpp b/tests/command-test.cpp index 1d224fa..6f795f9 100644 --- a/tests/command-test.cpp +++ b/tests/command-test.cpp @@ -26,57 +26,76 @@ using boost::test_tools::output_test_stream; using namespace dynamicgraph::command; -namespace dynamicgraph { -class CustomEntity : public Entity { - public: - static const std::string CLASS_NAME; - bool test_zero_arg_; - bool test_one_arg_; - bool test_two_args_; - bool test_three_args_; - bool test_four_args_; - - virtual const std::string &getClassName() const { return CLASS_NAME; } - CustomEntity(const std::string n) : Entity(n) { - test_zero_arg_ = false; - test_one_arg_ = false; - test_two_args_ = false; - test_three_args_ = false; - test_four_args_ = false; - - addCommand("0_arg", makeCommandVoid0(*this, &CustomEntity::zero_arg, docCommandVoid0("zero arg"))); - - addCommand("1_arg", makeCommandVoid1(*this, &CustomEntity::one_arg, docCommandVoid1("one arg", "int"))); - - addCommand("2_args", makeCommandVoid2(*this, &CustomEntity::two_args, docCommandVoid2("two args", "int", "int"))); - - addCommand("3_args", - makeCommandVoid3(*this, &CustomEntity::three_args, docCommandVoid3("three args", "int", "int", "int"))); - - addCommand("4_args", makeCommandVoid4(*this, &CustomEntity::four_args, - docCommandVoid4("four args", "int", "int", "int", "int"))); - } - - ~CustomEntity() {} - - void zero_arg() { test_zero_arg_ = true; } - - void one_arg(const int &) { test_one_arg_ = true; } - - void two_args(const int &, const int &) { test_two_args_ = true; } - - void three_args(const int &, const int &, const int &) { test_three_args_ = true; } - - void four_args(const int &, const int &, const int &, const int &) { test_four_args_ = true; } -}; -DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CustomEntity, "CustomEntity"); +namespace dynamicgraph +{ + class CustomEntity : public Entity + { + public: + static const std::string CLASS_NAME; + bool test_zero_arg_; + bool test_one_arg_; + bool test_two_args_; + bool test_three_args_; + bool test_four_args_; + + virtual const std::string &getClassName() const { return CLASS_NAME; } + CustomEntity(const std::string n) : Entity(n) + { + test_zero_arg_ = false; + test_one_arg_ = false; + test_two_args_ = false; + test_three_args_ = false; + test_four_args_ = false; + + addCommand("0_arg", + makeCommandVoid0(*this, &CustomEntity::zero_arg, + docCommandVoid0("zero arg"))); + + addCommand("1_arg", + makeCommandVoid1(*this, &CustomEntity::one_arg, + docCommandVoid1("one arg", "int"))); + + addCommand("2_args", + makeCommandVoid2(*this, &CustomEntity::two_args, + docCommandVoid2("two args", "int", "int"))); + + addCommand("3_args", + makeCommandVoid3(*this, &CustomEntity::three_args, + docCommandVoid3("three args", + "int", "int", "int"))); + + addCommand("4_args", + makeCommandVoid4(*this, &CustomEntity::four_args, + docCommandVoid4("four args", "int", + "int", "int", "int"))); + } + + ~CustomEntity() {} + + void zero_arg() { test_zero_arg_ = true; } + + void one_arg(const int &) { test_one_arg_ = true; } + + void two_args(const int &, const int &) { test_two_args_ = true; } + + void three_args(const int &, const int &, const int &) + { test_three_args_ = true; } + + void four_args(const int &, const int &, const int &, const int &) + { test_four_args_ = true; } + }; + DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CustomEntity, "CustomEntity"); } // namespace dynamicgraph -BOOST_AUTO_TEST_CASE(command_test) { - dynamicgraph::CustomEntity &entity = *(dynamic_cast<dynamicgraph::CustomEntity *>( - dynamicgraph::FactoryStorage::getInstance()->newEntity("CustomEntity", "my-entity"))); +BOOST_AUTO_TEST_CASE(command_test) +{ + dynamicgraph::CustomEntity &entity = + *(dynamic_cast<dynamicgraph::CustomEntity *> + (dynamicgraph::FactoryStorage::getInstance()-> + newEntity("CustomEntity", "my-entity"))); - std::map<const std::string, Command *> aCommandMap = entity.getNewStyleCommandMap(); + std::map<const std::string, Command *> aCommandMap = + entity.getNewStyleCommandMap(); std::map<const std::string, Command *>::iterator it_map; diff --git a/tests/pool.cpp b/tests/pool.cpp index 3b6b46e..190d5da 100644 --- a/tests/pool.cpp +++ b/tests/pool.cpp @@ -17,7 +17,8 @@ using boost::test_tools::output_test_stream; -struct MyEntity : public dynamicgraph::Entity { +struct MyEntity : public dynamicgraph::Entity +{ static const std::string CLASS_NAME; dynamicgraph::SignalPtr<double, int> m_sigdSIN; @@ -26,16 +27,23 @@ struct MyEntity : public dynamicgraph::Entity { MyEntity(const std::string &name) : Entity(name), m_sigdSIN(NULL, "MyEntity(" + name + ")::input(double)::in_double"), - m_sigdTimeDepSOUT(boost::bind(&MyEntity::update, this, _1, _2), m_sigdSIN, - "MyEntity(" + name + ")::input(double)::out_double") { + m_sigdTimeDepSOUT(boost::bind(&MyEntity::update, this, _1, _2), + m_sigdSIN, + "MyEntity(" + name + ")::input(double)::out_double") + { signalRegistration(m_sigdSIN << m_sigdTimeDepSOUT); } - virtual void display(std::ostream &os) const { os << "Hello! My name is " << getName() << " !" << std::endl; } - + virtual void display(std::ostream &os) const + { + os << "Hello! My name is " + << getName() << " !" << std::endl; + } + virtual const std::string &getClassName() const { return CLASS_NAME; } - double &update(double &res, const int &inTime) { + double &update(double &res, const int &inTime) + { const double &aDouble = m_sigdSIN(inTime); res = aDouble; return res; @@ -45,29 +53,39 @@ struct MyEntity : public dynamicgraph::Entity { DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(MyEntity, "MyEntity"); namespace dg = dynamicgraph; -BOOST_AUTO_TEST_CASE(pool_display) { +BOOST_AUTO_TEST_CASE(pool_display) +{ /// Create Entity - dg::Entity *entity = dg::FactoryStorage::getInstance()->newEntity("MyEntity", "MyEntityInst"); + dg::Entity *entity = dg::FactoryStorage::getInstance()-> + newEntity("MyEntity", "MyEntityInst"); /// Test exception catching when registering Entity bool res = false; - try { - dg::Entity *entity2 = dg::FactoryStorage::getInstance()->newEntity("MyEntity", "MyEntityInst"); - - bool res2 = (entity2 == entity); - BOOST_CHECK(res2); - } catch (const dg::ExceptionFactory &aef) { - res = (aef.getCode() == dg::ExceptionFactory::OBJECT_CONFLICT); - } + try + { + dg::Entity *entity2 = dg::FactoryStorage::getInstance()-> + newEntity("MyEntity", "MyEntityInst"); + + bool res2 = (entity2 == entity); + BOOST_CHECK(res2); + } + catch (const dg::ExceptionFactory &aef) + { + res = (aef.getCode() == dg::ExceptionFactory::OBJECT_CONFLICT); + } BOOST_CHECK(res); /// Test exception catching when deregistering Entity res = false; - try { - dg::FactoryStorage::getInstance()->deregisterEntity("MyEntityInstFailure"); - } catch (const dg::ExceptionFactory &aef) { - res = (aef.getCode() == dg::ExceptionFactory::OBJECT_CONFLICT); - } + try + { + dg::FactoryStorage::getInstance()-> + deregisterEntity("MyEntityInstFailure"); + } + catch (const dg::ExceptionFactory &aef) + { + res = (aef.getCode() == dg::ExceptionFactory::OBJECT_CONFLICT); + } BOOST_CHECK(res); /// Search for an entity inside the map @@ -78,27 +96,34 @@ BOOST_AUTO_TEST_CASE(pool_display) { /// Search for an entity inside the map res = false; - try { - dg::PoolStorage::getInstance()->getEntity("MyEntityInstFailure"); - } catch (const dg::ExceptionFactory &aef) { - res = (aef.getCode() == dg::ExceptionFactory::UNREFERED_OBJECT); - } + try + { + dg::PoolStorage::getInstance()->getEntity("MyEntityInstFailure"); + } + catch (const dg::ExceptionFactory &aef) + { + res = (aef.getCode() == dg::ExceptionFactory::UNREFERED_OBJECT); + } BOOST_CHECK(res); /// Testing entityMap - const dg::PoolStorage::Entities &anEntityMap = dg::PoolStorage::getInstance()->getEntityMap(); + const dg::PoolStorage::Entities &anEntityMap = + dg::PoolStorage::getInstance()->getEntityMap(); bool testExistence = anEntityMap.find("MyEntityInst") == anEntityMap.end(); BOOST_CHECK(!testExistence); /// Testing the existence of an entity - testExistence = dg::PoolStorage::getInstance()->existEntity("MyEntityInst", entity); + testExistence = dg::PoolStorage::getInstance()-> + existEntity("MyEntityInst", entity); BOOST_CHECK(testExistence); /// Testing the completion list of pool storage dg::PoolStorage::getInstance()->writeCompletionList(output); - BOOST_CHECK(output.is_equal("MyEntityInst.in_double\nMyEntityInst.out_double\nprint\nsignals\nsignalDep\n")); + BOOST_CHECK(output.is_equal + ("MyEntityInst.in_double\nMyEntityInst.out_double\n" + "print\nsignals\nsignalDep\n")); /// Checking the graph generated by the pool dg::PoolStorage::getInstance()->writeGraph("output.dot"); @@ -112,12 +137,15 @@ BOOST_AUTO_TEST_CASE(pool_display) { std::string str_to_test = "/* This graph has been automatically generated.\n" " 2019 Month: 2 Day: 28 Time: 11:28 */\n" - "digraph \"output\" { graph [ label=\"output\" bgcolor = white rankdir=LR ]\n" - "\t node [ fontcolor = black, color = black, fillcolor = gold1, style=filled, shape=box ] ; \n" + "digraph \"output\" { \t graph [ label=\"output\" " + "bgcolor = white rankdir=LR ]\n" + "\t node [ fontcolor = black, color = black,fillcolor = gold1," + " style=filled, shape=box ] ; \n" "\tsubgraph cluster_Entities { \n" "\t} \n" "\"MyEntityInst\" [ label = \"MyEntityInst\" ,\n" - " fontcolor = black, color = black, fillcolor=cyan, style=filled, shape=box ]\n" + " fontcolor = black, color = black, fillcolor=cyan, style=filled," + " shape=box ]\n" "}\n"; /// Check the two substring (remove the date) - @@ -125,39 +153,49 @@ BOOST_AUTO_TEST_CASE(pool_display) { std::string s_crmk = "*/"; std::size_t find_s_output_wgph = s_output_wgph.find(s_crmk); - std::string sub_s_output_wgph = s_output_wgph.substr(find_s_output_wgph, s_output_wgph.length()); + std::string sub_s_output_wgph = s_output_wgph.substr + (find_s_output_wgph, s_output_wgph.length()); std::size_t find_str_to_test = str_to_test.find(s_crmk); - std::string sub_str_to_test = str_to_test.substr(find_str_to_test, str_to_test.length()); + std::string sub_str_to_test = str_to_test.substr + (find_str_to_test, str_to_test.length()); bool two_sub_string_identical; two_sub_string_identical = sub_str_to_test == sub_s_output_wgph; - + std::cout << sub_str_to_test << std::endl; + std::cout << sub_s_output_wgph << std::endl; + std::cout << sub_str_to_test.compare(sub_s_output_wgph) << std::endl; BOOST_CHECK(two_sub_string_identical); /// Test name of a valid signal. std::istringstream an_iss("MyEntityInst.in_double"); - dg::SignalBase<int> &aSignal = dg::PoolStorage::getInstance()->getSignal(an_iss); + dg::SignalBase<int> &aSignal = + dg::PoolStorage::getInstance()->getSignal(an_iss); std::string aSignalName = aSignal.getName(); - testExistence = aSignalName == "MyEntity(MyEntityInst)::input(double)::in_double"; + testExistence = aSignalName == + "MyEntity(MyEntityInst)::input(double)::in_double"; BOOST_CHECK(testExistence); /// Test name of an unvalid signal. an_iss.str("MyEntityInst.in2double"); - try { - dg::PoolStorage::getInstance()->getSignal(an_iss); - } catch (const dg::ExceptionFactory &aef) { - res = (aef.getCode() == dg::ExceptionFactory::UNREFERED_SIGNAL); - } + try + { + dg::PoolStorage::getInstance()->getSignal(an_iss); + } + catch (const dg::ExceptionFactory &aef) + { + res = (aef.getCode() == dg::ExceptionFactory::UNREFERED_SIGNAL); + } BOOST_CHECK(res); /// Deregister the entity. dg::PoolStorage::getInstance()->deregisterEntity(entity->getName()); /// Testing the existance of an entity - testExistence = dg::PoolStorage::getInstance()->existEntity("MyEntityInst", entity); + testExistence = dg::PoolStorage::getInstance()-> + existEntity("MyEntityInst", entity); BOOST_CHECK(!testExistence); -- GitLab