35 #include "G4Threading.hh"
36 #include "G4AutoLock.hh"
42 using namespace DD4hep;
43 using namespace DD4hep::Simulation;
45 G4Mutex creation_mutex=G4MUTEX_INITIALIZER;
49 namespace Simulation {
56 throw runtime_error(
format(
"Geant4Handle",
"Attempt to access an invalid object of type:%s!",
typeName(
typeid(TYPE)).c_str()));
78 Geant4Action*
object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second);
79 if (!
object && typ.first == typ.second) {
81 printout(
DEBUG,
"Geant4Handle",
"Object factory for %s not found. Try out %s",
82 typ.second.c_str(), _t.c_str());
83 object = PluginService::Create<Geant4Action*>(_t, ctxt, typ.second);
85 size_t idx = _t.rfind(
':');
86 if (idx != string::npos)
87 _t = string(_t.substr(idx + 1));
88 printout(
DEBUG,
"Geant4Handle",
"Try out object factory for %s",_t.c_str());
89 object = PluginService::Create<Geant4Action*>(_t, ctxt, typ.second);
93 TYPE* ptr =
dynamic_cast<TYPE*
>(object);
97 throw runtime_error(
format(
"Geant4Handle",
"Failed to convert object of type %s to handle of type %s!",
98 typ.first.c_str(),typ.second.c_str()));
100 throw runtime_error(
format(
"Geant4Handle",
"Failed to create object of type %s!", typ.first.c_str()));
103 template <
typename TYPE,
typename CONT>
106 const string& type_name,
107 const string& shared_typ,
113 typedef typename TYPE::shared_type _ST;
115 _ST*
object = (_ST*)_create_object<TYPE>(kernel,s_type);
116 CONT& container = (k.*pmf)();
119 G4AutoLock protection_lock(&creation_mutex); {
120 value = container.get(typ.second);
121 if ( !value ) value = _create_object<TYPE>(k,typ);
122 container.adopt(value);
125 value->info(
"+++ Created shared object for %s of type %s.",
126 typ.second.c_str(),
typeName(
typeid(TYPE)).c_str());
129 TYPE* value = _create_object<TYPE>(k,typ);
133 template <
typename TYPE>
138 template <
typename TYPE>
140 value = _create_object<TYPE>(kernel,
TypeName::split(type_name_char ? type_name_char :
"????"));
165 return pm[property_name];
189 if ( &handle !=
this ) {
191 value = handle.
get();
192 if (value) value->addRef();
198 if ( typ != value ) {
201 if (value) value->addRef();
217 throw runtime_error(
format(
"KernelHandle",
"Cannot access worker context [Invalid Handle]"));
279 const string& detector,
bool ) {
285 Geant4Sensitive*
object = PluginService::Create<Geant4Sensitive*>(typ.first, ctxt, typ.second, &det, &lcdd);
291 catch (
const exception&
e) {
292 printout(
ERROR,
"Geant4Handle<Geant4Sensitive>",
"Exception: %s", e.what());
295 printout(
ERROR,
"Geant4Handle<Geant4Sensitive>",
"Exception: Unknown exception");
297 throw runtime_error(
format(
"Geant4Handle<Geant4Sensitive>",
298 "Failed to create sensitive object of type %s for detector %s!",
299 type_name.c_str(), detector.c_str()));
handled_type * operator->() const
Access to the underlying object.
Geant4Handle & operator=(const Geant4Handle &handle)
Assignment operator.
void checked_assign(TYPE *p)
The property class to assign options to actions.
Geant4Kernel & worker(unsigned long thread_identifier, bool create_if=false)
Access worker instance by it's identifier.
static unsigned long int thread_self()
Access thread identifier.
Geant4StackingActionSequence & stackingAction()
Access stacking action sequence.
bool operator!() const
Validity check.
handled_type * value
Pointer to referenced object.
Helper class to handle strings of the format "type/name".
std::string typeName(const std::type_info &type)
ABI information about type names.
TYPE * _create_share(Geant4Kernel &kernel, CONT &(Geant4ActionContainer::*pmf)(), const string &type_name, const string &shared_typ, bool shared, TYPE *)
static TYPE * checked_value(TYPE *p)
handled_type * value
Pointer to referenced object.
LCDD & lcdd() const
Access to detector description.
static LCDD & getInstance(void)
—Factory method----—
Geant4EventActionSequence & eventAction()
Access run action sequence.
Property & operator[](const std::string &property_name) const
Property accessor.
Handle to Geant4 actions with built-in creation mechanism.
std::string format(const std::string &src, const std::string &fmt,...)
Build formatted string.
virtual DetElement detector(const std::string &name) const =0
Retrieve a field component by it's name from the detector description.
The base class for Geant4 sensitive detector actions implemented by users.
Class, which allows all Geant4Action derivatives to access the DDG4 kernel structures.
KernelHandle worker()
Access to worker thread.
Class, which allows all Geant4Action to be stored.
bool isMultiThreaded() const
Geant4GeneratorActionSequence & generatorAction()
Access generator action sequence.
Geant4Kernel & master() const
Thread's master context.
handled_type * get() const
Access to the underlying object.
Geant4Action * action() const
Access to the underlying object.
handled_type * release()
Release the underlying object.
Geant4Context * workerContext()
Thread's Geant4 execution context.
TYPE * _create_object(Geant4Kernel &kernel, const TypeName &typ)
void destroy()
Destroy referenced object (program termination)
static TypeName split(const std::string &type_name)
Split string pair according to default delimiter ('/')
Handle class describing a detector element.
Geant4TrackingActionSequence & trackingAction()
Access tracking action sequence.
Generic context to extend user, run and event information.
Handle to Geant4 actions with built-in creation mechanism.
~Geant4Handle()
Default destructor.
The main interface to the DD4hep detector description package.
Geant4RunActionSequence & runAction()
Access run action sequence.
void handle(const O *o, const C &c, F pmf)
int printout(PrintLevel severity, const char *src, const char *fmt,...)
Calls the display action with a given severity level.
Geant4Handle()
Default constructor.
KernelHandle()
Default constructor.
static Geant4Kernel & instance(LCDD &lcdd)
Instance accessor.
Manager to ease the handling of groups of properties.
Default base class for all Geant 4 actions and derivates thereof.
Geant4SteppingActionSequence & steppingAction()
Access stepping action sequence.