From d769287d039620571dd7927073174fe2f616dd52 Mon Sep 17 00:00:00 2001
From: florent <florent@laas.fr>
Date: Wed, 29 Dec 2010 09:34:06 +0100
Subject: [PATCH] When registering a type, store pointer to type_info in a map

     * include/dynamic-graph/signal-caster.h,
     * src/signal/signal-caster.cpp: if a typename is registered several times,
     throw only if pointers to type_info differ. When loading python modules,
     for some reason, global variables are constructed several times.
---
 include/dynamic-graph/signal-caster.h |  1 +
 src/signal/signal-caster.cpp          | 19 ++++++++++++++-----
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/include/dynamic-graph/signal-caster.h b/include/dynamic-graph/signal-caster.h
index f0b589a..07b995d 100644
--- a/include/dynamic-graph/signal-caster.h
+++ b/include/dynamic-graph/signal-caster.h
@@ -74,6 +74,7 @@ private:
 	 * using boost::function with 'compatible' syntax
 	 */
 	std::map<std::string, cast_functions_type> functions_;
+	std::map<std::string, const std::type_info*> type_info_;
 };
 
 
diff --git a/src/signal/signal-caster.cpp b/src/signal/signal-caster.cpp
index c098efc..7548715 100644
--- a/src/signal/signal-caster.cpp
+++ b/src/signal/signal-caster.cpp
@@ -43,13 +43,22 @@ SignalCaster::~SignalCaster() {
 void SignalCaster::registerCast(const type_info& type, SignalCaster::displayer_type displayer,
 		SignalCaster::caster_type caster, SignalCaster::tracer_type tracer) {
   if ( existsCast(type) ) {
-    std::string typeName(type.name());
-    std::ostringstream os;
-    os << "cast already registered for type " << typeName << ".";
-    throw ExceptionSignal(ExceptionSignal::GENERIC,
-			  os.str()); //TODO: throw "cast already registered for type" exception
+    // 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) {
-- 
GitLab