diff --git a/DDAlign/include/DDAlign/GlobalAlignmentCache.h b/DDAlign/include/DDAlign/GlobalAlignmentCache.h index fe4ac1d53491c3630d7f176bc8ed1614cc21a8db..6e8bbcd857ca23760b582ec6cf39bd8be7250655 100644 --- a/DDAlign/include/DDAlign/GlobalAlignmentCache.h +++ b/DDAlign/include/DDAlign/GlobalAlignmentCache.h @@ -14,6 +14,7 @@ #define DD4HEP_ALIGNMENT_GLOBALALIGNMENTCACHE_H // Framework include files +#include "DD4hep/ExtensionEntry.h" #include "DD4hep/GlobalAlignment.h" #include "DDAlign/GlobalAlignmentStack.h" @@ -40,6 +41,7 @@ namespace dd4hep { class GlobalAlignmentCache { friend class dd4hep::Detector; friend class GlobalAlignmentOperator; + friend class dd4hep::detail::DeleteExtension<GlobalAlignmentCache,GlobalAlignmentCache>; public: typedef GlobalAlignmentStack Stack; diff --git a/DDAlign/src/GlobalAlignmentCache.cpp b/DDAlign/src/GlobalAlignmentCache.cpp index bb8249beed102f6e911d2e4ce2bfd0897c58f23e..fd36e210134346794ade8d658a0d7629f069758b 100644 --- a/DDAlign/src/GlobalAlignmentCache.cpp +++ b/DDAlign/src/GlobalAlignmentCache.cpp @@ -75,8 +75,8 @@ GlobalAlignmentCache* GlobalAlignmentCache::install(Detector& description) { GlobalAlignmentCache* cache = description.extension<GlobalAlignmentCache>(false); if ( !cache ) { cache = new GlobalAlignmentCache(description,"world",true); - description.addUserExtension(detail::typeHash64<GlobalAlignmentCache>(), - new detail::SimpleExtension<GlobalAlignmentCache>(cache)); + ExtensionEntry* e = new detail::DeleteExtension<GlobalAlignmentCache,GlobalAlignmentCache>(cache); + description.addUserExtension(detail::typeHash64<GlobalAlignmentCache>(),e); } return cache; } diff --git a/DDCore/include/DD4hep/DetElement.h b/DDCore/include/DD4hep/DetElement.h index cf9b377409f16efa2707041b0f7c05482d278220..4d2514df7609546f07202d6da548b28d678d7bc5 100644 --- a/DDCore/include/DD4hep/DetElement.h +++ b/DDCore/include/DD4hep/DetElement.h @@ -124,7 +124,8 @@ namespace dd4hep { /// 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>(),new detail::DeleteExtension<CONCRETE>(c)); + return (IFACE*) this->addExtension(detail::typeHash64<IFACE>(), + new detail::DeleteExtension<IFACE,CONCRETE>(c)); } /// Access extension element by the type @@ -198,22 +199,25 @@ namespace dd4hep { protected: - template <typename T> struct DetElementExtension : public ExtensionEntry { + template <typename Q, typename T> struct DetElementExtension : public ExtensionEntry { protected: - T* ptr; + T* ptr = 0; + mutable Q* iface = 0; //! public: DetElementExtension() = delete; - DetElementExtension(T* p) : ptr(p) {} + DetElementExtension(T* p) : ptr(p) { iface = dynamic_cast<Q*>(p); } DetElementExtension(const DetElementExtension& copy) = default; DetElementExtension& operator=(const DetElementExtension& copy) = default; virtual ~DetElementExtension() = default; // This one ensures we have the correct signatures - T* copy(DetElement de) const { return new T(*ptr,de); } - virtual void* object() const override { return ptr; } - virtual void* copy(void* det) const override { return copy(DetElement((Object*)det)); } + T* copy(DetElement de) const { return new T(*ptr,de); } virtual void destruct() const override { delete ptr; } + virtual void* object() const override + { return iface ? iface : (iface=dynamic_cast<Q*>(ptr)); } + virtual void* copy(void* det) const override + { return copy(DetElement((Object*)det)); } virtual ExtensionEntry* clone(void* det) const override - { return new DetElementExtension<T>((T*)this->copy(det)); } + { return new DetElementExtension<Q,T>((T*)this->copy(det)); } }; /// Internal call to extend the detector element with an arbitrary structure accessible by the type @@ -285,7 +289,8 @@ namespace dd4hep { /// Extend the detector element with an arbitrary structure accessible by the type template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c) const { CallbackSequence::checkTypes(typeid(IFACE), typeid(CONCRETE), dynamic_cast<IFACE*>(c)); - return (IFACE*) this->addExtension(detail::typeHash64<IFACE>(),new DetElementExtension<CONCRETE>(c)); + return (IFACE*) this->addExtension(detail::typeHash64<IFACE>(), + new DetElementExtension<IFACE,CONCRETE>(c)); } /// Access extension element by the type template <typename IFACE> IFACE* extension() const { diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index 6e5363047f8b35a513a2c0a828a635d1f27fd413..9d5c1fadbcba91a93bae9463358b2e3c6930ab47 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -266,15 +266,18 @@ namespace dd4hep { /// Add an extension object to the detector element (low level member function) virtual void* addUserExtension(unsigned long long int key, ExtensionEntry* entry) = 0; - /// Remove an existing extension object from the Detector instance. If not destroyed, the instance is returned (low level member function) + + /// Remove an existing extension object from the Detector instance. + /** If not destroyed, the instance is returned (low level member function) */ virtual void* removeUserExtension(unsigned long long int key, bool destroy) = 0; + /// Access an existing extension object from the detector element (low level member function) virtual void* userExtension(unsigned long long int key, bool alert=true) const = 0; /// Extend the sensitive detector element with an arbitrary structure accessible by the type - template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c) { + template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c) { return (IFACE*) addUserExtension(detail::typeHash64<IFACE>(), - new detail::DeleteExtension<IFACE>(dynamic_cast<IFACE*>(c))); + new detail::DeleteExtension<IFACE,CONCRETE>(c)); } /// Remove an existing extension object from the Detector instance. If not destroyed, the instance is returned diff --git a/DDCore/include/DD4hep/ExtensionEntry.h b/DDCore/include/DD4hep/ExtensionEntry.h index c227c2af348b338145638121c68538e7a66ce998..9542523bc22f626c075dac0363e5abe682e9a056 100644 --- a/DDCore/include/DD4hep/ExtensionEntry.h +++ b/DDCore/include/DD4hep/ExtensionEntry.h @@ -60,109 +60,128 @@ namespace dd4hep { namespace detail { /// Implementation class for the object extension mechanism. - /** This implementation class supports the object extension mechanism - * for dd4hep. + /** This implementation class supports the object extension mechanism + * for dd4hep. + * + * Note: + * The double-template implementation is necessary to support extensions + * using a virtual inheritance relationship between the interface and the + * concrete implementation of the extension object. * * \author M.Frank * \date 13.08.2013 * \ingroup DD4HEP */ - template <typename T> struct SimpleExtension : public ExtensionEntry { + template <typename Q,typename T> struct SimpleExtension : public ExtensionEntry { protected: - T* ptr; + T* ptr = 0; + mutable Q* iface = 0; //! public: /// Default constructor SimpleExtension() = delete; /// Initializing constructor - SimpleExtension(T* p) : ptr(p) {} + SimpleExtension(T* p) : ptr(p) { iface = dynamic_cast<Q*>(p); } /// Copy constructor SimpleExtension(const SimpleExtension& copy) = default; /// Default destructor virtual ~SimpleExtension() = default; /// Assignment operator SimpleExtension& operator=(const SimpleExtension& copy) = default; - /// Virtual object accessor - virtual void* object() const override { return ptr; } /// Virtual object copy operator virtual void* copy(void*) const override { invalidCall("copy"); return 0; } - /// Virtual object destructor - virtual void destruct() const override { invalidCall("destruct"); return; } + /// Virtual object destructor. Function may still be called without side-effects. + virtual void destruct() const override { } + /// Virtual object accessor + virtual void* object() const override + { return iface ? iface : (iface=dynamic_cast<Q*>(ptr)); } /// Virtual entry clone function virtual ExtensionEntry* clone(void*) const override { invalidCall("clone"); return 0; } }; - + /// Implementation class for the object extension mechanism. - /** This implementation class supports the object extension mechanism - * for dd4hep. It is ensured, that on the object destruction or - * on request the reference to the user object may be destructed. + /** This implementation class supports the object extension mechanism + * for dd4hep. It is ensured, that on the object destruction or + * on request the reference to the user object may be destructed. * - * Note: User object must be taken from the heap using "new". + * Note: User object must be taken from the heap using "new". + * Note: + * The double-template implementation is necessary to support extensions + * using a virtual inheritance relationship between the interface and the + * concrete implementation of the extension object. * * \author M.Frank * \date 13.08.2013 * \ingroup DD4HEP */ - template <typename T> struct DeleteExtension : public ExtensionEntry { + template <typename Q,typename T> struct DeleteExtension : public ExtensionEntry { protected: - T* ptr; + T* ptr = 0; + mutable Q* iface = 0; //! public: /// Default constructor DeleteExtension() = delete; /// Initializing constructor - DeleteExtension(T* p) : ptr(p) {} + DeleteExtension(T* p) : ptr(p) { iface = dynamic_cast<Q*>(p); } /// Copy constructor DeleteExtension(const DeleteExtension& copy) = default; /// Default destructor virtual ~DeleteExtension() = default; /// Assignment operator DeleteExtension& operator=(const DeleteExtension& copy) = default; - /// Virtual object accessor - virtual void* object() const override { return ptr; } /// Virtual object copy operator virtual void* copy(void*) const override { invalidCall("copy"); return 0; } /// Virtual object destructor virtual void destruct() const override { delete ptr; } + /// Virtual object accessor + virtual void* object() const override + { return iface ? iface : (iface=dynamic_cast<Q*>(ptr)); } /// Virtual entry clone function virtual ExtensionEntry* clone(void* arg) const override { return new DeleteExtension((T*)this->copy(arg)); } }; /// Implementation class for the object extension mechanism. - /** This implementation class supports the object extension mechanism - * for dd4hep. It is ensured, that on the object destruction or - * on request the reference to the user object may be destructed. + /** This implementation class supports the object extension mechanism + * for dd4hep. It is ensured, that on the object destruction or + * on request the reference to the user object may be destructed. * - * Note: User object must be taken from the heap using "new". + * Note: User object must be taken from the heap using "new". + * Note: + * The double-template implementation is necessary to support extensions + * using a virtual inheritance relationship between the interface and the + * concrete implementation of the extension object. * * \author M.Frank * \date 13.08.2013 * \ingroup DD4HEP */ - template <typename T> struct CopyDeleteExtension : public ExtensionEntry { + template <typename Q,typename T> struct CopyDeleteExtension : public ExtensionEntry { protected: - T* ptr; + T* ptr = 0; + mutable Q* iface = 0; //! public: /// Default constructor CopyDeleteExtension() = delete; /// Initializing constructor - CopyDeleteExtension(T* p) : ptr(p) {} + CopyDeleteExtension(T* p) : ptr(p) { iface = dynamic_cast<Q*>(p); } /// Copy constructor CopyDeleteExtension(const CopyDeleteExtension& copy) = default; /// Default destructor virtual ~CopyDeleteExtension() = default; /// Assignment operator CopyDeleteExtension& operator=(const CopyDeleteExtension& copy) = default; - /// Virtual object accessor - virtual void* object() const override { return ptr; } /// Virtual object copy operator virtual void* copy(void*) const override { return new T(*ptr); } /// Virtual object destructor virtual void destruct() const override { delete ptr; } + /// Virtual object accessor + virtual void* object() const override + { return iface ? iface : (iface=dynamic_cast<Q*>(ptr)); } /// Virtual entry clone function virtual ExtensionEntry* clone(void* arg) const override { return new CopyDeleteExtension((T*)this->copy(arg)); } }; } // End namespace detail - } // End namespace dd4hep +} // End namespace dd4hep #endif /* DD4HEP_DDCORE_EXTENSIONENTRY_H */ diff --git a/DDCore/src/ExtensionEntry.cpp b/DDCore/src/ExtensionEntry.cpp index 250203c29de558587c2a8c80874c2ed26a9f2709..f22876858715c29e741510b61b87184d8e5c2788 100644 --- a/DDCore/src/ExtensionEntry.cpp +++ b/DDCore/src/ExtensionEntry.cpp @@ -17,6 +17,6 @@ /// Callback on invalid call invokation void dd4hep::ExtensionEntry::invalidCall(const char* tag) const { - except("ExtensionEntry","Invalid call invokation from %s to method %s(...).", + except("ExtensionEntry","Invalid call invocation from %s to method %s(...).", typeName(typeid(*this)).c_str(), tag); } diff --git a/DDCore/src/ObjectExtensions.cpp b/DDCore/src/ObjectExtensions.cpp index bbb9212a2fa32dd45d2761a810674d223e3d97bc..dd288c2f515d68c41c49469d4b17d2d8fa30fcc0 100644 --- a/DDCore/src/ObjectExtensions.cpp +++ b/DDCore/src/ObjectExtensions.cpp @@ -95,7 +95,7 @@ void* ObjectExtensions::removeExtension(unsigned long long int key, bool destroy void* ObjectExtensions::extension(unsigned long long int key) const { const auto j = extensions.find(key); if (j != extensions.end()) { - return (*j).second; + return (*j).second->object(); } except("removeExtension","The object has no extension of type %016llX.",key); return 0; @@ -105,7 +105,7 @@ void* ObjectExtensions::extension(unsigned long long int key) const { void* ObjectExtensions::extension(unsigned long long int key, bool alert) const { const auto j = extensions.find(key); if (j != extensions.end()) { - return (*j).second; + return (*j).second->object(); } else if ( !alert ) return 0; diff --git a/DDG4/include/DDG4/Geant4Context.h b/DDG4/include/DDG4/Geant4Context.h index 030cbaba09670e3ea765dba68f8a2cbc4a0d2de8..2500bc21190536d0711b7bb5d535208c141393a2 100644 --- a/DDG4/include/DDG4/Geant4Context.h +++ b/DDG4/include/DDG4/Geant4Context.h @@ -86,8 +86,8 @@ namespace dd4hep { /// Add user extension object. Ownership is transferred! template <typename T> T* addExtension(T* ptr, bool take_ownership=true) { ExtensionEntry* e = take_ownership - ? (ExtensionEntry*)new detail::DeleteExtension<T>(ptr) - : (ExtensionEntry*)new detail::SimpleExtension<T>(ptr); + ? (ExtensionEntry*)new detail::DeleteExtension<T,T>(ptr) + : (ExtensionEntry*)new detail::SimpleExtension<T,T>(ptr); return (T*)ObjectExtensions::addExtension(detail::typeHash64<T>(),e); } /// Access to type safe extension object. Exception is thrown if the object is invalid @@ -142,8 +142,8 @@ namespace dd4hep { /// Add user extension object. Ownership is transferred and object deleted at the end of the event. template <typename T> T* addExtension(T* ptr, bool take_ownership=true) { ExtensionEntry* e = take_ownership - ? (ExtensionEntry*)new detail::DeleteExtension<T>(ptr) - : (ExtensionEntry*)new detail::SimpleExtension<T>(ptr); + ? (ExtensionEntry*)new detail::DeleteExtension<T,T>(ptr) + : (ExtensionEntry*)new detail::SimpleExtension<T,T>(ptr); return (T*)ObjectExtensions::addExtension(detail::typeHash64<T>(),e); } /// Access to type safe extension object. Exception is thrown if the object is invalid