diff --git a/DDAlign/src/GlobalAlignmentCache.cpp b/DDAlign/src/GlobalAlignmentCache.cpp index 9e4061f4246fc37f75cac60aa682c989fe35aaf8..bb8249beed102f6e911d2e4ce2bfd0897c58f23e 100644 --- a/DDAlign/src/GlobalAlignmentCache.cpp +++ b/DDAlign/src/GlobalAlignmentCache.cpp @@ -75,7 +75,8 @@ GlobalAlignmentCache* GlobalAlignmentCache::install(Detector& description) { GlobalAlignmentCache* cache = description.extension<GlobalAlignmentCache>(false); if ( !cache ) { cache = new GlobalAlignmentCache(description,"world",true); - description.addExtension<GlobalAlignmentCache>(cache); + description.addUserExtension(detail::typeHash64<GlobalAlignmentCache>(), + new detail::SimpleExtension<GlobalAlignmentCache>(cache)); } return cache; } diff --git a/DDCore/include/DD4hep/DetElement.h b/DDCore/include/DD4hep/DetElement.h index caf3df31030acee19eb6e7fa6f273f0bca48f3ec..cf9b377409f16efa2707041b0f7c05482d278220 100644 --- a/DDCore/include/DD4hep/DetElement.h +++ b/DDCore/include/DD4hep/DetElement.h @@ -21,6 +21,7 @@ #include "DD4hep/Readout.h" #include "DD4hep/Alignments.h" #include "DD4hep/Segmentations.h" +#include "DD4hep/ObjectExtensions.h" // C/C++ include files #include <map> @@ -41,19 +42,6 @@ namespace dd4hep { * \ingroup DD4HEP_CORE */ class SensitiveDetector: public Handle<SensitiveDetectorObject> { - protected: - - /// Templated destructor function - template <typename T> static void _delete(void* ptr) { - delete (T*) (ptr); - } - - /// Add an extension object to the detector element - void* i_addExtension(void* ptr, const std::type_info& info, void (*destruct)(void*)); - - /// Access an existing extension object from the detector element - void* i_extension(const std::type_info& info) const; - public: /// Default constructor @@ -128,14 +116,20 @@ namespace dd4hep { /// Access to the limit set of the sensitive detector (not mandatory). LimitSet limits() const; + /// Add an extension object to the detector element + 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; + /// Extend the sensitive detector element with an arbitrary structure accessible by the type - template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c) { - return (IFACE*) i_addExtension(dynamic_cast<IFACE*>(c), typeid(IFACE), _delete<IFACE>); + template <typename IFACE, typename CONCRETE> IFACE* addExtension(CONCRETE* c) const { + return (IFACE*) this->addExtension(detail::typeHash64<IFACE>(),new detail::DeleteExtension<CONCRETE>(c)); } /// Access extension element by the type template <typename IFACE> IFACE* extension() const { - return (IFACE*) i_extension(typeid(IFACE)); + return (IFACE*) this->extension(detail::typeHash64<IFACE>()); } }; @@ -179,10 +173,14 @@ namespace dd4hep { virtual int processElement(DetElement detector) = 0; }; - typedef std::map<std::string, DetElement> Children; + typedef std::map<std::string, DetElement> Children; enum CopyParameters { - COPY_NONE = 0, COPY_PLACEMENT = 1 << 0, COPY_PARENT = 1 << 1, COPY_ALIGNMENT = 1 << 2, LAST + COPY_NONE = 0, + COPY_PLACEMENT = 1 << 0, + COPY_PARENT = 1 << 1, + COPY_ALIGNMENT = 1 << 2, + LAST }; enum UpdateParam { @@ -200,21 +198,24 @@ namespace dd4hep { protected: - /// Templated destructor function - template <typename T> static void _delete(void* ptr) { - delete (T*) (ptr); - } - /// Templated copy constructor - template <typename T> static void* _copy(const void* ptr, DetElement elt) { - return new T(*(dynamic_cast<const T*>((T*) ptr)), elt); - } + template <typename T> struct DetElementExtension : public ExtensionEntry { + protected: + T* ptr; + public: + DetElementExtension() = delete; + DetElementExtension(T* p) : ptr(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)); } + virtual void destruct() const override { delete ptr; } + virtual ExtensionEntry* clone(void* det) const override + { return new DetElementExtension<T>((T*)this->copy(det)); } + }; - /// Add an extension object to the detector element - void* i_addExtension(void* ptr, const std::type_info& info, - void* (*copy)(const void*, DetElement), - void (*destruct)(void*)) const; - /// Access an existing extension object from the detector element - void* i_extension(const std::type_info& info) const; /// Internal call to extend the detector element with an arbitrary structure accessible by the type void i_addUpdateCall(unsigned int callback_type, const Callback& callback) const; @@ -275,14 +276,20 @@ namespace dd4hep { /// Clone (Deep copy) the DetElement structure with a new name and new identifier DetElement clone(const std::string& new_name, int new_id) const; + /// Add an extension object to the detector element + 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; + /// 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*) i_addExtension(dynamic_cast<IFACE*>(c), typeid(IFACE), _copy<CONCRETE>, _delete<IFACE>); + return (IFACE*) this->addExtension(detail::typeHash64<IFACE>(),new DetElementExtension<CONCRETE>(c)); } /// Access extension element by the type template <typename IFACE> IFACE* extension() const { - return (IFACE*) i_extension(typeid(IFACE)); + return (IFACE*) this->extension(detail::typeHash64<IFACE>()); } /// Extend the detector element with an arbitrary callback template <typename Q, typename T> diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index cdc32d40f89fc780e593a3d07c9510232af43576..6e5363047f8b35a513a2c0a828a635d1f27fd413 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -23,9 +23,10 @@ #include "DD4hep/Volumes.h" #include "DD4hep/Readout.h" #include "DD4hep/DetElement.h" +#include "DD4hep/NamedObject.h" #include "DD4hep/Segmentations.h" #include "DD4hep/VolumeManager.h" -#include "DD4hep/NamedObject.h" +#include "DD4hep/ExtensionEntry.h" #include "DD4hep/BuildType.h" // C/C++ include files @@ -263,19 +264,27 @@ namespace dd4hep { /// Manipulate geometry using factory converter virtual long apply(const char* factory, int argc, char** argv) = 0; + /// 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) + 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) { - return (IFACE*) addUserExtension(dynamic_cast<IFACE*>(c), typeid(IFACE), _delete<IFACE>); + return (IFACE*) addUserExtension(detail::typeHash64<IFACE>(), + new detail::DeleteExtension<IFACE>(dynamic_cast<IFACE*>(c))); } /// Remove an existing extension object from the Detector instance. If not destroyed, the instance is returned - template <class T> T* removeExtension(bool destroy=true) { - return (T*) removeUserExtension(typeid(T),destroy); + template <class IFACE> IFACE* removeExtension(bool destroy=true) { + return (IFACE*) removeUserExtension(detail::typeHash64<IFACE>(),destroy); } /// Access extension element by the type - template <class T> T* extension(bool alert=true) const { - return (T*) userExtension(typeid(T),alert); + template <class IFACE> IFACE* extension(bool alert=true) const { + return (IFACE*) userExtension(detail::typeHash64<IFACE>(),alert); } ///---Factory method------- @@ -283,18 +292,6 @@ namespace dd4hep { /// Destroy the instance static void destroyInstance(); - protected: - /// Templated destructor function - template <typename T> static void _delete(void* ptr) { - delete (T*) (ptr); - } - /// Add an extension object to the detector element - virtual void* addUserExtension(void* ptr, const std::type_info& info, void (*destruct)(void*)) = 0; - /// Remove an existing extension object from the Detector instance. If not destroyed, the instance is returned - virtual void* removeUserExtension(const std::type_info& info, bool destroy) = 0; - /// Access an existing extension object from the detector element - virtual void* userExtension(const std::type_info& info, bool alert=true) const = 0; - }; /* diff --git a/DDCore/include/DD4hep/ExtensionEntry.h b/DDCore/include/DD4hep/ExtensionEntry.h new file mode 100644 index 0000000000000000000000000000000000000000..c227c2af348b338145638121c68538e7a66ce998 --- /dev/null +++ b/DDCore/include/DD4hep/ExtensionEntry.h @@ -0,0 +1,168 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +// +// NOTE: +// +// This is an internal include file. It should only be included to +// instantiate code. Otherwise the BasicGrammar include file should be +// sufficient for all practical purposes. +// +//========================================================================== +#ifndef DD4HEP_DDCORE_EXTENSIONENTRY_H +#define DD4HEP_DDCORE_EXTENSIONENTRY_H + +#include "DD4hep/Primitives.h" + +// C/C++ include files +#include <typeinfo> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Definition of the extension entry interface class + /** Base class for the object extension mechanism. + * + * \author M.Frank + * \date 13.08.2013 + * \ingroup DD4HEP + */ + class ExtensionEntry { + protected: + /// Default constructor + ExtensionEntry() = default; + /// Copy constructor + ExtensionEntry(const ExtensionEntry& copy) = default; + public: + /// Default destructor + virtual ~ExtensionEntry() = default; + /// Callback on invalid call invokation + void invalidCall(const char* tag) const; + /// Virtual object accessor + virtual void* object() const = 0; + /// Virtual object copy operator + virtual void* copy(void*) const = 0; + /// Virtual object destructor + virtual void destruct() const = 0; + /// Virtual entry clone function + virtual ExtensionEntry* clone(void* arg) const = 0; + }; + + namespace detail { + + /// Implementation class for the object extension mechanism. + /** This implementation class supports the object extension mechanism + * for dd4hep. + * + * \author M.Frank + * \date 13.08.2013 + * \ingroup DD4HEP + */ + template <typename T> struct SimpleExtension : public ExtensionEntry { + protected: + T* ptr; + public: + /// Default constructor + SimpleExtension() = delete; + /// Initializing constructor + SimpleExtension(T* p) : ptr(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 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. + * + * Note: User object must be taken from the heap using "new". + * + * \author M.Frank + * \date 13.08.2013 + * \ingroup DD4HEP + */ + template <typename T> struct DeleteExtension : public ExtensionEntry { + protected: + T* ptr; + public: + /// Default constructor + DeleteExtension() = delete; + /// Initializing constructor + DeleteExtension(T* p) : ptr(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 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. + * + * Note: User object must be taken from the heap using "new". + * + * \author M.Frank + * \date 13.08.2013 + * \ingroup DD4HEP + */ + template <typename T> struct CopyDeleteExtension : public ExtensionEntry { + protected: + T* ptr; + public: + /// Default constructor + CopyDeleteExtension() = delete; + /// Initializing constructor + CopyDeleteExtension(T* p) : ptr(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 entry clone function + virtual ExtensionEntry* clone(void* arg) const override + { return new CopyDeleteExtension((T*)this->copy(arg)); } + }; + } // End namespace detail + } // End namespace dd4hep +#endif /* DD4HEP_DDCORE_EXTENSIONENTRY_H */ diff --git a/DDCore/include/DD4hep/ObjectExtensions.h b/DDCore/include/DD4hep/ObjectExtensions.h index 1f23efb1969fa0f538aa0c97f06ed8addab282ac..37bfa29f1372334fc51e515191d219e1ed13433c 100644 --- a/DDCore/include/DD4hep/ObjectExtensions.h +++ b/DDCore/include/DD4hep/ObjectExtensions.h @@ -13,8 +13,10 @@ #ifndef DD4HEP_DDCORE_OBJECTEXTENSIONS_H #define DD4HEP_DDCORE_OBJECTEXTENSIONS_H +// Framework include files +#include "DD4hep/ExtensionEntry.h" + // C/C++ include files -#include <typeinfo> #include <map> /// Namespace for the AIDA detector description toolkit @@ -30,21 +32,8 @@ namespace dd4hep { */ class ObjectExtensions { public: - /// Defintiion of the extension entry - struct Entry { - void* (*copy)(const void*, void*); - void (*destruct)(void*); - int id; - }; /// The extensions object - std::map<const std::type_info*, void*> extensions; //! - /// Pointer to the extension map - std::map<const std::type_info*, Entry>* extensionMap; //! - - /// Function to be passed as dtor if object should NOT be deleted! - static void _noDelete(void*) {} - /// Templated destructor function - template <typename T> static void _delete(void* ptr) { delete (T*) (ptr); } + std::map<unsigned long long int, ExtensionEntry*> extensions; //! public: /// Default constructor @@ -55,24 +44,22 @@ namespace dd4hep { virtual ~ObjectExtensions(); /// Assignment operator ObjectExtensions& operator=(const ObjectExtensions& copy) = delete; + /// Initialize non-persistent object containers (e.g. after loading from ROOT file) + void initialize(); /// Move extensions to target object void move(ObjectExtensions& copy); /// Clear all extensions void clear(bool destroy=true); /// Copy object extensions from another object. Hosting type must be identical! - void copyFrom(const std::map<const std::type_info*, void*>& ext, void* arg); - /// Add an extension object to the detector element - void* addExtension(void* ptr, const std::type_info& info, - void* (*ctor)(const void*, void* arg), - void (*dtor)(void*)); + void copyFrom(const std::map<unsigned long long int,ExtensionEntry*>& ext, void* arg); /// Add an extension object to the detector element - void* addExtension(void* ptr, const std::type_info& info, void (*dtor)(void*)); + void* addExtension(unsigned long long int key, ExtensionEntry* entry); /// Remove an existing extension object from the instance - void* removeExtension(const std::type_info& info, bool destroy); + void* removeExtension(unsigned long long int key, bool destroy); /// Access an existing extension object from the detector element - void* extension(const std::type_info& info, bool alert) const; + void* extension(unsigned long long int key, bool alert) const; /// Access an existing extension object from the detector element - void* extension(const std::type_info& info) const; + void* extension(unsigned long long int key) const; }; } /* End namespace dd4hep */ diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index d39f57bfa9666e0b99d504960b4451020cec0c3e..a368fc46e9890db6e4251eed3242485e1e2514ad 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -155,6 +155,10 @@ namespace dd4hep { /// We need it so often: one-at-time 64 bit hash function unsigned long long int hash64(const char* key); unsigned long long int hash64(const std::string& key); + template <typename T> unsigned long long int typeHash64() { + static unsigned long long int code = hash64(typeid(T).name()); + return code; + } /// We need it so often: one-at-time 32 bit hash function inline unsigned int hash32(const char* key) { diff --git a/DDCore/include/DD4hep/detail/AlignmentsInterna.h b/DDCore/include/DD4hep/detail/AlignmentsInterna.h index 4611cf9dcf160b6982ca9aef9cb0de98b2c7ebdd..6578773a11dcfdf1b6235b0e5c4919c9ceb0bbc9 100644 --- a/DDCore/include/DD4hep/detail/AlignmentsInterna.h +++ b/DDCore/include/DD4hep/detail/AlignmentsInterna.h @@ -56,7 +56,7 @@ namespace dd4hep { class AlignmentObject : public detail::ConditionObject { public: /// Cached pointer to the bound conditions data, since these may be accessed very frequently - AlignmentData* alignment_data = 0; //! This valiable is internally bound and not ROOT persistent! + AlignmentData* alignment_data = 0; //! This variable is internally bound and not ROOT persistent! public: /// Default constructor. Alignment data wuill be bound to the heap. diff --git a/DDCore/src/DetElement.cpp b/DDCore/src/DetElement.cpp index e21fa261416ef7ea3fd709a376aa5fc697337cfe..f0b67aea5627f0f0d4657200bb850bf2ee09d9fc 100644 --- a/DDCore/src/DetElement.cpp +++ b/DDCore/src/DetElement.cpp @@ -64,16 +64,13 @@ DetElement::DetElement(DetElement det_parent, const string& det_name, int det_id } /// Add an extension object to the detector element -void* DetElement::i_addExtension(void* ext_ptr, const type_info& info, - void* (*ctor)(const void*, DetElement), - void (*dtor)(void*) ) const -{ - return access()->addExtension(ext_ptr, info, (void* (*)(const void*, void*))(ctor), dtor); +void* DetElement::addExtension(unsigned long long int k,ExtensionEntry* e) const { + return access()->addExtension(k,e); } /// Access an existing extension object from the detector element -void* DetElement::i_extension(const type_info& info) const { - return access()->extension(info); +void* DetElement::extension(unsigned long long int k) const { + return access()->extension(k); } /// Internal call to extend the detector element with an arbitrary structure accessible by the type @@ -441,14 +438,12 @@ LimitSet SensitiveDetector::limits() const { } /// Add an extension object to the detector element -void* SensitiveDetector::i_addExtension(void* ext_ptr, - const type_info& info, - void (*dtor)(void*)) +void* SensitiveDetector::addExtension(unsigned long long int k,ExtensionEntry* e) const { - return access()->addExtension(ext_ptr, info, dtor); + return access()->addExtension(k,e); } /// Access an existing extension object from the detector element -void* SensitiveDetector::i_extension(const type_info& info) const { - return access()->extension(info); +void* SensitiveDetector::extension(unsigned long long int k) const { + return access()->extension(k); } diff --git a/DDCore/src/DetectorImp.cpp b/DDCore/src/DetectorImp.cpp index 1c5487fabdcf967eb8ba0ae600971f3448a4de8b..b3474a32a06fb482e82042fceb9f8d3f4c7141f2 100644 --- a/DDCore/src/DetectorImp.cpp +++ b/DDCore/src/DetectorImp.cpp @@ -155,18 +155,18 @@ void DetectorImp::imp_loadVolumeManager() { } /// Add an extension object to the Detector instance -void* DetectorImp::addUserExtension(void* ptr, const type_info& info, void (*destruct)(void*)) { - return m_extensions.addExtension(ptr,info,destruct); +void* DetectorImp::addUserExtension(unsigned long long int key, ExtensionEntry* entry) { + return m_extensions.addExtension(key,entry); } /// Remove an existing extension object from the Detector instance -void* DetectorImp::removeUserExtension(const type_info& info, bool destroy) { - return m_extensions.removeExtension(info,destroy); +void* DetectorImp::removeUserExtension(unsigned long long int key, bool destroy) { + return m_extensions.removeExtension(key,destroy); } /// Access an existing extension object from the Detector instance -void* DetectorImp::userExtension(const type_info& info, bool alert) const { - return m_extensions.extension(info,alert); +void* DetectorImp::userExtension(unsigned long long int key, bool alert) const { + return m_extensions.extension(key,alert); } /// Register new mother volume using the detector name. diff --git a/DDCore/src/DetectorImp.h b/DDCore/src/DetectorImp.h index 9536feb4e37723873e566264966afff59716d2b6..f280ef4092d4b4d5cf1d3e87eac8b88e8a15cedd 100644 --- a/DDCore/src/DetectorImp.h +++ b/DDCore/src/DetectorImp.h @@ -91,13 +91,13 @@ namespace dd4hep { virtual void endDocument(); /// Add an extension object to the Detector instance - virtual void* addUserExtension(void* ptr, const std::type_info& info, void (*destruct)(void*)); + virtual void* addUserExtension(unsigned long long int key, ExtensionEntry* entry); /// Remove an existing extension object from the Detector instance. If not destroyed, the instance is returned - virtual void* removeUserExtension(const std::type_info& info, bool destroy=true); + virtual void* removeUserExtension(unsigned long long int key, bool destroy=true); /// Access an existing extension object from the Detector instance - virtual void* userExtension(const std::type_info& info, bool alert=true) const; + virtual void* userExtension(unsigned long long int key, bool alert=true) const; virtual Handle<NamedObject> getRefChild(const HandleMap& e, const std::string& name, bool throw_if_not = true) const; diff --git a/DDCore/src/ExtensionEntry.cpp b/DDCore/src/ExtensionEntry.cpp new file mode 100644 index 0000000000000000000000000000000000000000..250203c29de558587c2a8c80874c2ed26a9f2709 --- /dev/null +++ b/DDCore/src/ExtensionEntry.cpp @@ -0,0 +1,22 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/ExtensionEntry.h" +#include "DD4hep/Printout.h" + +/// Callback on invalid call invokation +void dd4hep::ExtensionEntry::invalidCall(const char* tag) const { + except("ExtensionEntry","Invalid call invokation from %s to method %s(...).", + typeName(typeid(*this)).c_str(), tag); +} diff --git a/DDCore/src/ObjectExtensions.cpp b/DDCore/src/ObjectExtensions.cpp index f1d111e3e1511670a430abb0dec0dddbed36671a..bbb9212a2fa32dd45d2761a810674d223e3d97bc 100644 --- a/DDCore/src/ObjectExtensions.cpp +++ b/DDCore/src/ObjectExtensions.cpp @@ -15,6 +15,7 @@ #include "DD4hep/ObjectExtensions.h" #include "DD4hep/InstanceCount.h" #include "DD4hep/Primitives.h" +#include "DD4hep/Printout.h" // C/C++ include files #include <stdexcept> @@ -23,17 +24,14 @@ using namespace std; using namespace dd4hep; namespace { - static int s_extensionID = 0; - map<const type_info*, ObjectExtensions::Entry>* - extensionContainer(const type_info& typ) { - static map<const type_info*,map<const type_info*,ObjectExtensions::Entry> > s_map; - return &s_map[&typ]; + std::string obj_type(void* ptr) { + ObjectExtensions* o = (ObjectExtensions*)ptr; + return typeName(typeid(*o)); } } /// Default constructor -ObjectExtensions::ObjectExtensions(const type_info& parent_type) { - extensionMap = extensionContainer(parent_type); +ObjectExtensions::ObjectExtensions(const type_info& /* parent_type */) { InstanceCount::increment(this); } @@ -53,88 +51,64 @@ void ObjectExtensions::move(ObjectExtensions& source) { void ObjectExtensions::clear(bool destroy) { for( const auto& i : extensions ) { if ( i.second ) { - auto j = extensionMap->find(i.first); - if (j != extensionMap->end()) { - Entry& e = (*j).second; - if (destroy && e.destruct) - ( *(e.destruct) ) ( i.second ); - } + if ( destroy ) i.second->destruct(); + delete i.second; } } extensions.clear(); } /// Copy object extensions from another object -void ObjectExtensions::copyFrom(const map<const type_info*, void*>& ext, void* arg) { +void ObjectExtensions::copyFrom(const map<unsigned long long int,ExtensionEntry*>& ext, void* arg) { for( const auto& i : ext ) { - const auto j = extensionMap->find(i.first); - const Entry& e = (*j).second; - extensions[i.first] = ( *(e.copy) )(i.second, arg); + extensions[i.first] = i.second->clone(arg); } } /// Add an extension object to the detector element -void* ObjectExtensions::addExtension(void* ptr, const type_info& info, void (*dtor)(void*)) { - return addExtension(ptr, info, 0, dtor); -} - -/// Add an extension object to the detector element -void* ObjectExtensions::addExtension(void* ptr, const type_info& info, - void* (*ctor)(const void*, void* arg), - void (*dtor)(void*)) -{ - auto j = extensions.find(&info); +void* ObjectExtensions::addExtension(unsigned long long int key, ExtensionEntry* e) { + auto j = extensions.find(key); if (j == extensions.end()) { - auto i = extensionMap->find(&info); - if (i == extensionMap->end()) { - Entry entry; - entry.destruct = dtor; - entry.copy = ctor; - entry.id = ++s_extensionID; - extensionMap->insert(make_pair(&info, entry)); - i = extensionMap->find(&info); - } - return extensions[&info] = ptr; + return extensions[key] = e; } - throw runtime_error("dd4hep: addExtension: Object already has an extension of type:" + typeName(info) + "."); + except("addExtension","Object already has an extension of type: %s.",obj_type(e->object()).c_str()); + return 0; } /// Remove an existing extension object from the instance -void* ObjectExtensions::removeExtension(const type_info& info, bool destroy) { - auto j = extensions.find(&info); - if (j != extensions.end()) { - void *ptr = (*j).second; +void* ObjectExtensions::removeExtension(unsigned long long int key, bool destroy) { + auto j = extensions.find(key); + if ( j != extensions.end() ) { + void* ptr = (*j).second->object(); if ( destroy ) { - const auto i = extensionMap->find(&info); - if (i != extensionMap->end()) { - const Entry& e = (*i).second; - (*e.destruct)((*j).second); - ptr = 0; - } + (*j).second->destruct(); } + delete (*j).second; extensions.erase(j); return ptr; } - throw runtime_error("dd4hep: removeExtension: The object of type " + typeName(info) + " is not present."); + except("removeExtension","The object of type %016llX is not present.",key); + return 0; } /// Access an existing extension object from the detector element -void* ObjectExtensions::extension(const type_info& info) const { - const auto j = extensions.find(&info); +void* ObjectExtensions::extension(unsigned long long int key) const { + const auto j = extensions.find(key); if (j != extensions.end()) { return (*j).second; } - throw runtime_error("dd4hep: extension: Object has no extension of type:" + typeName(info) + "."); + except("removeExtension","The object has no extension of type %016llX.",key); + return 0; } /// Access an existing extension object from the detector element -void* ObjectExtensions::extension(const type_info& info, bool alert) const { - const auto j = extensions.find(&info); +void* ObjectExtensions::extension(unsigned long long int key, bool alert) const { + const auto j = extensions.find(key); if (j != extensions.end()) { return (*j).second; } else if ( !alert ) return 0; - throw runtime_error("dd4hep: extension: Object has no extension of type:" + typeName(info) + "."); + except("removeExtension","The object has no extension of type %016llX.",key); + return 0; } - diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index b982d9cf387fd113fc55b74cb3c2e028d30a7c69..d17a977aa18394d305d477a98e66cf38ecf7dd79 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -931,10 +931,26 @@ static long detectortype_cache(Detector& description, int , char** ) { } DECLARE_APPLY(DD4hepDetectorTypes,detectortype_cache) +/// Basic entry point to print out detector type map +/** + * Factory: TestSurfaces + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ #include "DD4hep/SurfaceInstaller.h" typedef SurfaceInstaller TestSurfacesPlugin; DECLARE_SURFACE_INSTALLER(TestSurfaces,TestSurfacesPlugin) +/// Basic entry point to print out detector type map +/** + * Factory: DD4hepPluginTester + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ #include "DD4hep/PluginTester.h" static long install_plugin_tester(Detector& description, int , char** ) { PluginTester* test = description.extension<PluginTester>(false); diff --git a/DDG4/include/DDG4/Geant4Context.h b/DDG4/include/DDG4/Geant4Context.h index aff3d5f5c3b1f8bb3604c4c6c5aef5da82b4c6e9..030cbaba09670e3ea765dba68f8a2cbc4a0d2de8 100644 --- a/DDG4/include/DDG4/Geant4Context.h +++ b/DDG4/include/DDG4/Geant4Context.h @@ -80,21 +80,19 @@ namespace dd4hep { /// Access the G4Event directly: Explicit G4Run accessor const G4Run& run() const { return *m_run; } /// Add an extension object to the detector element - /** Note: - * To add an extension, which should NOT be deleted, - * set 'dtor' to ObjectExtensions::_noDelete or 0. - */ - void* addExtension(void* ptr, const std::type_info& info, void (*dtor)(void*)) { - return ObjectExtensions::addExtension(ptr,info,dtor); + void* addExtension(unsigned long long int k, ExtensionEntry* e) { + return ObjectExtensions::addExtension(k, e); } /// Add user extension object. Ownership is transferred! template <typename T> T* addExtension(T* ptr, bool take_ownership=true) { - void (*dt)(void*) = ObjectExtensions::_delete<T>; - return (T*)ObjectExtensions::addExtension(ptr,typeid(T),take_ownership ? dt : 0); + ExtensionEntry* e = take_ownership + ? (ExtensionEntry*)new detail::DeleteExtension<T>(ptr) + : (ExtensionEntry*)new detail::SimpleExtension<T>(ptr); + return (T*)ObjectExtensions::addExtension(detail::typeHash64<T>(),e); } /// Access to type safe extension object. Exception is thrown if the object is invalid template <typename T> T* extension(bool alert=true) { - return (T*)ObjectExtensions::extension(typeid(T),alert); + return (T*)ObjectExtensions::extension(detail::typeHash64<T>(),alert); } }; @@ -138,21 +136,19 @@ namespace dd4hep { Geant4Random& random() const { return *m_random; } /// Add an extension object to the detector element - /** Note: - * To add an extension, which should NOT be deleted, - * set 'dtor' to ObjectExtensions::_noDelete or 0. - */ - void* addExtension(void* ptr, const std::type_info& info, void (*dtor)(void*)) { - return ObjectExtensions::addExtension(ptr,info,dtor); + void* addExtension(unsigned long long int k, ExtensionEntry* e) { + return ObjectExtensions::addExtension(k, e); } /// 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) { - void (*dt)(void*) = ObjectExtensions::_delete<T>; - return (T*)ObjectExtensions::addExtension(ptr,typeid(T),take_ownership ? dt : 0); + ExtensionEntry* e = take_ownership + ? (ExtensionEntry*)new detail::DeleteExtension<T>(ptr) + : (ExtensionEntry*)new detail::SimpleExtension<T>(ptr); + return (T*)ObjectExtensions::addExtension(detail::typeHash64<T>(),e); } /// Access to type safe extension object. Exception is thrown if the object is invalid template <typename T> T* extension(bool alert=true) { - return (T*)ObjectExtensions::extension(typeid(T),alert); + return (T*)ObjectExtensions::extension(detail::typeHash64<T>(),alert); } }; diff --git a/DDG4/src/Geant4Context.cpp b/DDG4/src/Geant4Context.cpp index 7ffb0eb54213bee945780cabd2a92d3117008aec..01c444f5bf42324ccb53357bc903daf0dc10ba12 100644 --- a/DDG4/src/Geant4Context.cpp +++ b/DDG4/src/Geant4Context.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation //-------------------------------------------------------------------------- diff --git a/DDG4/src/Geant4ParticleHandler.cpp b/DDG4/src/Geant4ParticleHandler.cpp index 265efd5c105d2a1ba104e27b14f2cad1563ddc10..91474ebcf3a8f3e7a7564d482fa5c8707350b261 100644 --- a/DDG4/src/Geant4ParticleHandler.cpp +++ b/DDG4/src/Geant4ParticleHandler.cpp @@ -173,7 +173,7 @@ void Geant4ParticleHandler::mark(const G4Track* track) { void Geant4ParticleHandler::operator()(G4Event* event) { typedef Geant4MonteCarloTruth _MC; debug("+++ Event:%d Add EVENT extension of type Geant4ParticleHandler.....",event->GetEventID()); - context()->event().addExtension((_MC*)this, typeid(_MC), 0); + context()->event().addExtension((_MC*)this, false); clear(); /// Call the user particle handler if ( m_userHandler ) {