From 1e16d19e70bf45e6b3f096aa8c590c11fde5d633 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Mon, 17 Jul 2017 14:19:16 +0200
Subject: [PATCH] First attempt to make ObjectExtension instances persistent in
 ROOT

---
 DDCore/include/DD4hep/DetElement.h            | 11 ++++++--
 DDCore/src/DetElement.cpp                     |  9 +++++--
 DDCore/src/ObjectExtensions.cpp               | 25 ++++++++++++-------
 DDRec/src/Surface.cpp                         | 15 +++--------
 examples/SimpleDetector/src/AirTube_geo.cpp   |  1 -
 .../SimpleDetector/src/ZPlanarTracker_geo.cpp |  3 +--
 6 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/DDCore/include/DD4hep/DetElement.h b/DDCore/include/DD4hep/DetElement.h
index 4d2514df7..4ac645527 100644
--- a/DDCore/include/DD4hep/DetElement.h
+++ b/DDCore/include/DD4hep/DetElement.h
@@ -122,6 +122,9 @@ namespace dd4hep {
     /// Access an existing extension object from the detector element
     void* extension(unsigned long long int key) const;
 
+    /// Access an existing extension object from the detector element
+    void* extension(unsigned long long int key, bool alert) const;
+
     /// Extend the sensitive detector element with an arbitrary structure accessible by the type
     template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c)  const {
       return (IFACE*) this->addExtension(detail::typeHash64<IFACE>(),
@@ -284,7 +287,7 @@ namespace dd4hep {
     void* addExtension(unsigned long long int key,ExtensionEntry* entry) const;
 
     /// Access an existing extension object from the detector element
-    void* extension(unsigned long long int key) const;
+    void* extension(unsigned long long int key, bool alert) const;
 
     /// Extend the detector element with an arbitrary structure accessible by the type
     template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c) const {
@@ -294,7 +297,11 @@ namespace dd4hep {
     }
     /// Access extension element by the type
     template <typename IFACE> IFACE* extension() const {
-      return (IFACE*) this->extension(detail::typeHash64<IFACE>());
+      return (IFACE*) this->extension(detail::typeHash64<IFACE>(),true);
+    }
+    /// Access extension element by the type
+    template <typename IFACE> IFACE* extension(bool alert) const {
+      return (IFACE*) this->extension(detail::typeHash64<IFACE>(),alert);
     }
     /// Extend the detector element with an arbitrary callback
     template <typename Q, typename T>
diff --git a/DDCore/src/DetElement.cpp b/DDCore/src/DetElement.cpp
index f0b67aea5..a00e9743c 100644
--- a/DDCore/src/DetElement.cpp
+++ b/DDCore/src/DetElement.cpp
@@ -69,8 +69,8 @@ void* DetElement::addExtension(unsigned long long int k,ExtensionEntry* e) const
 }
 
 /// Access an existing extension object from the detector element
-void* DetElement::extension(unsigned long long int k) const {
-  return access()->extension(k);
+void* DetElement::extension(unsigned long long int k, bool alert) const {
+  return access()->extension(k, alert);
 }
 
 /// Internal call to extend the detector element with an arbitrary structure accessible by the type
@@ -447,3 +447,8 @@ void* SensitiveDetector::addExtension(unsigned long long int k,ExtensionEntry* e
 void* SensitiveDetector::extension(unsigned long long int k) const {
   return access()->extension(k);
 }
+
+/// Access an existing extension object from the detector element
+void* SensitiveDetector::extension(unsigned long long int k, bool alert) const {
+  return access()->extension(k, alert);
+}
diff --git a/DDCore/src/ObjectExtensions.cpp b/DDCore/src/ObjectExtensions.cpp
index dd288c2f5..3a5969bf1 100644
--- a/DDCore/src/ObjectExtensions.cpp
+++ b/DDCore/src/ObjectExtensions.cpp
@@ -67,11 +67,18 @@ void ObjectExtensions::copyFrom(const map<unsigned long long int,ExtensionEntry*
 
 /// Add an extension object to the detector element
 void* ObjectExtensions::addExtension(unsigned long long int key, ExtensionEntry* e)  {
-  auto j = extensions.find(key);
-  if (j == extensions.end()) {
-    return extensions[key] = e;
+  if ( e )   {
+    if ( e->object() )  {
+      auto j = extensions.find(key);
+      if (j == extensions.end()) {
+        extensions[key] = e;
+        return e->object();
+      }
+      except("ObjectExtensions::addExtension","Object already has an extension of type: %s.",obj_type(e->object()).c_str());
+    }
+    except("ObjectExtensions::addExtension","Invalid extension object for key %016llX!",key);
   }
-  except("addExtension","Object already has an extension of type: %s.",obj_type(e->object()).c_str());
+  except("ObjectExtensions::addExtension","Invalid extension entry for key %016llX!",key);
   return 0;
 }
 
@@ -87,7 +94,7 @@ void* ObjectExtensions::removeExtension(unsigned long long int key, bool destroy
     extensions.erase(j);
     return ptr;
   }
-  except("removeExtension","The object of type %016llX is not present.",key);
+  except("ObjectExtensions::removeExtension","The object of type %016llX is not present.",key);
   return 0;
 }
 
@@ -97,8 +104,8 @@ void* ObjectExtensions::extension(unsigned long long int key) const {
   if (j != extensions.end()) {
     return (*j).second->object();
   }
-  except("removeExtension","The object has no extension of type %016llX.",key);
-  return 0;
+  string msg = format("ObjectExtensions::extension","The object has no extension of type %016llX.",key);
+  throw runtime_error(msg);
 }
 
 /// Access an existing extension object from the detector element
@@ -109,6 +116,6 @@ void* ObjectExtensions::extension(unsigned long long int key, bool alert) const
   }
   else if ( !alert )
     return 0;
-  except("removeExtension","The object has no extension of type %016llX.",key);
-  return 0;
+  string msg = format("ObjectExtensions::extension","The object has no extension of type %016llX.",key);
+  throw runtime_error(msg);
 }
diff --git a/DDRec/src/Surface.cpp b/DDRec/src/Surface.cpp
index 478624858..b70cea3d2 100644
--- a/DDRec/src/Surface.cpp
+++ b/DDRec/src/Surface.cpp
@@ -509,19 +509,10 @@ namespace dd4hep {
     //================================================================================================================
 
     VolSurfaceList* volSurfaceList( DetElement& det ) {
-
-      
-      VolSurfaceList* list = 0 ;
-
-      try {
-
-        list = det.extension< VolSurfaceList >() ;
-
-      } catch(const std::runtime_error& e){ 
-	
-        list = det.addExtension<VolSurfaceList >(  new VolSurfaceList ) ; 
+      VolSurfaceList* list = det.extension< VolSurfaceList >(false);
+      if ( !list )  {
+        list = det.addExtension<VolSurfaceList >(new VolSurfaceList);
       }
-
       return list ;
     }
 
diff --git a/examples/SimpleDetector/src/AirTube_geo.cpp b/examples/SimpleDetector/src/AirTube_geo.cpp
index b3c431edb..10cd97405 100644
--- a/examples/SimpleDetector/src/AirTube_geo.cpp
+++ b/examples/SimpleDetector/src/AirTube_geo.cpp
@@ -1,4 +1,3 @@
-// $Id: $
 //====================================================================
 //  // Simple tube filled with air 
 //  // used for tracking purposes ...
diff --git a/examples/SimpleDetector/src/ZPlanarTracker_geo.cpp b/examples/SimpleDetector/src/ZPlanarTracker_geo.cpp
index dc4a30488..897617d58 100644
--- a/examples/SimpleDetector/src/ZPlanarTracker_geo.cpp
+++ b/examples/SimpleDetector/src/ZPlanarTracker_geo.cpp
@@ -1,4 +1,3 @@
-// $Id: $
 //====================================================================
 //  Simple tracking detector made from planar sensors that are parallel
 //  to the z-axis. There are two materials per ladder: one sensitive
@@ -204,7 +203,7 @@ static Ref_t create_element(Detector& description, xml_h e, SensitiveDetector se
       DetElement   ladderDE( layerDE ,  laddername , x_det.id() );
       ladderDE.setPlacement( pv ) ;
 
-      volSurfaceList( ladderDE )->push_back( surf ) ;
+      //volSurfaceList( ladderDE )->push_back( surf ) ;
 
     }
     
-- 
GitLab