UserActionFactory.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file UserActionFactory.h
3 /// \brief A class for generating concrete UserAction derived classes
4 /// based on the factory pattern. This code supplies a CPP
5 /// macro which allows the classes to self-register and thus
6 /// no modification of this class is needed in order to expand
7 /// the list of classes it knows about.
8 ///
9 /// Implemented as a singleton holding a map between names and
10 /// pointers-to-functions (that call a class default constructor).
11 /// The functions pointers must return UserAction*.
12 ///
13 /// \version
14 /// \author Robert Hatcher <rhatcher \at fnal.gov>
15 /// Fermi National Accelerator Laboratory
16 ///
17 ////////////////////////////////////////////////////////////////////////
18 #ifndef USERACTIONFACTORY_H
19 #define USERACTIONFACTORY_H
20 
21 #include <string>
22 #include <vector>
23 #include <map>
24 
25 #include "nutools/G4Base/UserAction.h"
26 
27 namespace g4b {
28 
29 // define a type for the pointer to a function that returns a
30 // g4b::UserAction*
31 // i.e. calls the (typically default) ctor for the class.
32 typedef g4b::UserAction* (*UserActionCtorFuncPtr_t)();
33 
35 {
36 public:
37  static UserActionFactory& Instance();
38  // no public ctor for singleton, all user access is through Instance()
39 
41  // instantiate a PhysProc by name
42 
43  bool IsKnownUserAction(const std::string&);
44  // check if the name is in the list of names
45 
46  const std::vector<std::string>& AvailableUserActions() const;
47  // return a list of available names
48 
50  UserActionCtorFuncPtr_t ctorptr, bool* ptr);
51  // register a new UserAction type by passing pointer to creator function
52 
53 private:
55  // the one and only instance
56 
57  std::map<std::string, UserActionCtorFuncPtr_t> fFunctionMap;
58  // mapping between known class names and a registered ctor function
59 
60  std::map<std::string, bool*> fBoolPtrMap;
61 
62  mutable std::vector<std::string> listnames;
63  // copy of list of names, used solely due to AvailableUserActions()
64  // method returning a const reference rather than a vector object.
65  // mutable because AvailableUserActions() is const, but list might
66  // need recreation if new entries have been registered.
67 
68 private:
70  // private ctor, users access class via Instance()
71 
72  virtual ~UserActionFactory();
73 
75  // method private and not implement, declared to prevent copying
76 
77  void operator=(const UserActionFactory&);
78  // method private and not implement, declared to prevent assignment
79 
80  // sub-class Cleaner struct is used to clean up singleton at the end of job.
81  struct Cleaner {
82  void UseMe() { } // Dummy method to quiet compiler
87  } } };
88  friend struct Cleaner;
89 
90 };
91 
92 } // namespace g4b
93 
94 // Define macro to create a function to call the class' ctor
95 // and then registers this function with the factory instance for later use
96 // Users should have in their myPhyList.cc two lines that look like:
97 // #include "UserActionFactory.h"
98 // USERACTIONREG(MyUserActionClass) // no semicolon
99 // where "MyMixerClass" is the name of the class (assuming no special namespace)
100 // If the class is defined in a namespace (or two) use:
101 // #include "UserActionFactory.h"
102 // USERACTIONREG3(myspace,myAltAction,myspace::myAltAction) // no semicolon
103 // USERACTIONREG4(alt,nspace,YAAction,alt::nspace::YAAction) // no semicolon
104 // and either can then be retrieved from the factory using:
105 // UserActionFactory& factory =
106 // UserActionFactory::Instance();
107 // g4::UserAction* p = 0;
108 // p = factory.GetUserAction("MyUserActionClass");
109 // p = factory.GetUserAction("myspace::myAltAction");
110 // p = factory.GetUserAction("alt::nspace::YAAction");
111 //
112 #define USERACTIONREG( _name ) \
113  g4b::UserAction* _name ## _ctor_function () { return new _name; } \
114  static bool _name ## _creator_registered = \
115  g4b::UserActionFactory::Instance().RegisterCreator(# _name, \
116  & _name ## _ctor_function, \
117  & _name ## _creator_registered );
118 
119 #define USERACTIONREG3( _ns, _name, _fqname ) \
120 namespace _ns { \
121  g4b::UserAction* _name ## _ctor_function () { return new _fqname; } \
122  static bool _name ## _creator_registered = \
123  g4b::UserActionFactory::Instance().RegisterCreator(# _fqname, \
124  & _fqname ## _ctor_function, \
125  & _fqname ## _creator_registered );}
126 
127 #define USERACTIONREG4( _nsa, _nsb, _name, _fqname ) \
128 namespace _nsa { \
129  namespace _nsb { \
130  g4b::UserAction* _name ## _ctor_function () { return new _fqname; } \
131  static bool _name ## _creator_registered = \
132  g4b::UserActionFactory::Instance().RegisterCreator(# _fqname, \
133  & _fqname ## _ctor_function, \
134  & _fqname ## _creator_registered );}}
135 #endif
static QCString name
Definition: declinfo.cpp:673
bool IsKnownUserAction(const std::string &)
std::vector< std::string > listnames
std::string string
Definition: nybbler.cc:12
static UserActionFactory & Instance()
std::map< std::string, UserActionCtorFuncPtr_t > fFunctionMap
const std::vector< std::string > & AvailableUserActions() const
std::map< std::string, bool * > fBoolPtrMap
g4b::UserAction *(* UserActionCtorFuncPtr_t)()
void operator=(const UserActionFactory &)
static UserActionFactory * fgTheInstance
basic interface to Geant4 for ART-based software
bool RegisterCreator(std::string name, UserActionCtorFuncPtr_t ctorptr, bool *ptr)
g4b::UserAction * GetUserAction(const std::string &)