|
|
|||
File indexing completed on 2026-08-06 09:38:26
0001 // -*- C++ -*- 0002 // 0003 // InterfacedBase.h is a part of ThePEG - Toolkit for HEP Event Generation 0004 // Copyright (C) 1999-2019 Leif Lonnblad 0005 // 0006 // ThePEG is licenced under version 3 of the GPL, see COPYING for details. 0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details. 0008 // 0009 #ifndef ThePEG_InterfacedBase_H 0010 #define ThePEG_InterfacedBase_H 0011 // This is the declaration of the InterfacedBase class. 0012 0013 #include "ThePEG/Config/ThePEG.h" 0014 #include "ThePEG/Utilities/Named.h" 0015 #include "ThePEG/Utilities/ClassDescription.h" 0016 #include "ThePEG/Utilities/HoldFlag.h" 0017 #include "InterfacedBase.xh" 0018 0019 namespace ThePEG { 0020 0021 /** 0022 * InterfacedBase is the base class of all Interfaced objects to be 0023 * handled by the BaseRepository class. InterfacedBase 0024 * objects can be manipulated through objects of the InterfaceBase 0025 * class dealing with setting parameters, switches and pointers to 0026 * other InterfacedBase objects. 0027 * 0028 * The InterfacedBase has a number of virtual methods to be 0029 * implemented by sub classes for checking the state of the object, 0030 * initializing the object etc. 0031 * 0032 * The InterfacedBase is derived from the PersistentBase class to 0033 * allow for persistent I/O, and from the Named for handling the name 0034 * of the object. The full name of the object is of the form 0035 * <code>/dir/subdir/name</code> analogous to the file name in a Unix 0036 * file system. 0037 * 0038 * It is possible to lock an InterfacedBase object in which case the 0039 * BaseRepository will not do anything that will change the state of 0040 * this object. 0041 * 0042 * @see BaseRepository 0043 * @see InterfaceBase 0044 */ 0045 class InterfacedBase: public PersistentBase, public Named { 0046 0047 /** The BaseRepository is a close friend. */ 0048 friend class BaseRepository; 0049 0050 /** The InterfaceBase is a close friend. */ 0051 friend class InterfaceBase; 0052 0053 /** The EventGenerator is a friend. */ 0054 friend class EventGenerator; 0055 0056 public: 0057 0058 /** 0059 * Enumeration reflecting the state of an InterfacedBase object. 0060 */ 0061 enum InitState { 0062 initializing = -1, /**< The object is currently being 0063 initialized. I.e. either of update(), 0064 init(), initrun() or finish() are being 0065 run. */ 0066 uninitialized = 0, /**< The object has not been initialized. */ 0067 initialized = 1, /**< The object has been initialized. */ 0068 runready = 2 /**< The object is initialized and the 0069 initrun() method has been called. */ 0070 }; 0071 0072 public: 0073 0074 /** 0075 * The virtual (empty) destructor; 0076 */ 0077 virtual ~InterfacedBase(); 0078 0079 /** 0080 * Returns the full name of this object including its path, e.g. 0081 * <code>/directory/subdirectory/name</code>. 0082 */ 0083 string fullName() const { return Named::name(); } 0084 0085 /** 0086 * Returns the name of this object, without the path. 0087 */ 0088 string name() const { 0089 return Named::name().substr(Named::name().rfind('/')+1); 0090 } 0091 0092 /** 0093 * Returns the path to this object including the trailing 0094 * '/'. <code>fullName() = path() + name()</code>. 0095 */ 0096 string path() const { 0097 string::size_type slash = Named::name().rfind('/'); 0098 string ret; 0099 if ( slash != string::npos ) ret = Named::name().substr(0,slash); 0100 return ret; 0101 } 0102 0103 /** 0104 * Returns a comment assigned to this object. 0105 */ 0106 string comment() const { return theComment; } 0107 0108 /** 0109 * Read setup info from a standard istream \a is. May be called by 0110 * the Repository to initialize an object. This function first calls 0111 * the virtual readSetup() function to allow the sub classes the 0112 * part \a is to initialize themselves. What ever is left in \a is 0113 * after that will be assigned to the comment() of the object. 0114 */ 0115 void setup(istream & is) { 0116 readSetup(is); 0117 getline(is, theComment); 0118 } 0119 0120 protected: 0121 0122 /** @name Standard InterfacedBase virtual functions. */ 0123 //@{ 0124 /** 0125 * Read setup info from a standard istream \a is. May be called by 0126 * the Repository to initialize an object. This function is called 0127 * by the non virtual setup() function. A sub-class implementing it 0128 * should first call the base class version before parsing the \a 0129 * is. If the \a is is not empty after readSetup is called the 0130 * remaining string will be assigned to the comment() of the object. 0131 */ 0132 virtual void readSetup(istream & is); 0133 0134 /** 0135 * Check sanity of the object during the setup phase. This function 0136 * is called everytime the object is changed through an interface 0137 * during the setup phase. Also if the setup is changed for an 0138 * object on which this is dependent. Note that the generator() is 0139 * not available when this method is called. 0140 * 0141 * This method may be called by the user interface during the setup phase 0142 * through the update() method after manipulating objects to check 0143 * the sanity of the object. When implemented by a sub class it is 0144 * important that the doupdate() method of the base class is called, 0145 * then if the sanity of this object depend on other objects, the 0146 * update() method of these should be called. Then if touched() is 0147 * true for this object or for the ones on which this depends, it is 0148 * an indication that some things have changed since last time 0149 * doupdate() was called, and the actual checking of the state of 0150 * this object is called for. To avoid circular loops, it is 0151 * important that the doupdate() method is called for the base 0152 * class, while the update() method is called for other objects. 0153 * @throws UpdateException if the setup is such that the object 0154 * would not work properly. 0155 */ 0156 virtual void doupdate() {} 0157 0158 /** 0159 * Initialize this object after the setup phase before saving an 0160 * EventGenerator to disk. Nothing should have changed since the 0161 * last update() call. 0162 * 0163 * This method is called after the setup 0164 * phase through the init() method to indicate that the setup of a 0165 * run is finished. This is typpically done in a setup program 0166 * before this object has been saved to a run file. It must 0167 * therefore be made sure that the state of this object after this 0168 * method has been executed will not be changed if it is written to 0169 * a file and read in again. When implemented by a sub class it is 0170 * important that the doinit() method of the base class is called 0171 * first and then, if the initialization of this object depends on 0172 * other objects, that the init() method of these objects are 0173 * called. Only then should the class-local initialization 0174 * proceed. To avoid circular loops, it is important that the 0175 * doinit() method is called for the base class, while the init() 0176 * method is called for other objects. 0177 * @throws InitException if object could not be initialized properly. 0178 */ 0179 virtual void doinit() {} 0180 0181 /** 0182 * Initialize this object. Called in the run phase just before 0183 * a run begins. 0184 * 0185 * This method is called just before 0186 * running starts through the initrun() method to indicate that the 0187 * actual running is to start. When implemented by a sub class it is 0188 * important that the doinitrun() method of the base class is called 0189 * first and then, if the initialization of this object depends on 0190 * other objects, that the initrun() method of these objects are 0191 * called. Only then should the class-local initialization 0192 * proceed. To avoid circular loops, it is important that the 0193 * doinitrun() method is called for the base class, while the 0194 * initrun() method is called for other objects. 0195 */ 0196 virtual void doinitrun() {} 0197 0198 /** 0199 * Finalize this object. Called in the run phase just after a 0200 * run has ended. Used eg. to write out statistics. 0201 * 0202 * This method is called after the running 0203 * phase through the finish() and can eg. be used to write out 0204 * statistics. When implemented by a sub class it is important that 0205 * the dofinish() method of the base class is called while the 0206 * finish() methd is called for other objects. 0207 */ 0208 virtual void dofinish() {} 0209 0210 /** 0211 * Return a vector of all pointers to Interfaced objects used in this 0212 * object. 0213 * @return a vector of pointers. 0214 */ 0215 virtual IVector getReferences() { return IVector(); } 0216 0217 /** 0218 * Rebind pointer to other Interfaced objects. Called in the setup phase 0219 * after all objects used in an EventGenerator has been cloned so that 0220 * the pointers will refer to the cloned objects afterwards. 0221 * @throws RebindException if no cloned object was found for a given 0222 * pointer. 0223 */ 0224 virtual void rebind(const TranslationMap &) {} 0225 //@} 0226 0227 public: 0228 0229 /** @name Inlined access function. */ 0230 //@{ 0231 /** 0232 * Calls the doupdate() function with recursion prevention. 0233 */ 0234 void update() { 0235 if ( initState ) return; 0236 HoldFlag<InitState> hold(initState, initializing, initialized); 0237 doupdate(); 0238 } 0239 0240 /** 0241 * Calls the doinit() function with recursion prevention. 0242 */ 0243 void init() { 0244 if ( initState ) return; 0245 HoldFlag<InitState> hold(initState, initializing, initialized); 0246 doinit(); 0247 } 0248 0249 /** 0250 * Return true if this object needs to be initialized before all 0251 * other objects (except those for which this function also returns 0252 * true). This default version always returns false, but subclasses 0253 * may override it to return true. 0254 */ 0255 virtual bool preInitialize() const; 0256 0257 /** 0258 * Calls the doinitrun() function with recursion prevention. 0259 */ 0260 void initrun() { 0261 if ( initState == runready || initState == initializing ) return; 0262 HoldFlag<InitState> hold(initState, initializing, runready); 0263 doinitrun(); 0264 } 0265 0266 /** 0267 * Calls the dofinish() function with recursion prevention. 0268 */ 0269 void finish() { 0270 if ( initState == uninitialized || initState == initializing ) return; 0271 HoldFlag<InitState> hold(initState, initializing, uninitialized); 0272 dofinish(); 0273 } 0274 0275 /** 0276 * This function should be called every time something in this 0277 * object has changed in a way that a sanity check with update() is 0278 * needed 0279 */ 0280 void touch() { isTouched = true; } 0281 0282 /** 0283 * Set the state of this object to uninitialized. 0284 */ 0285 void reset() { initState = uninitialized; } 0286 0287 /** 0288 * Calls reset() and unTouch(). 0289 */ 0290 void clear() { 0291 reset(); 0292 untouch(); 0293 } 0294 0295 /** 0296 * Return the state of initialization of this object. 0297 */ 0298 InitState state() const { return initState; } 0299 0300 /** 0301 * Return true if the BaseRepository is not allowed to change the 0302 * state of this object. 0303 */ 0304 bool locked() const { return isLocked; } 0305 0306 /** 0307 * Return true if the state of this object has been changed since 0308 * the last call to update(). 0309 */ 0310 bool touched() const { return isTouched; } 0311 //@} 0312 0313 /** 0314 * Return a full clone of this object possibly doing things to the 0315 * clone to make it sane. 0316 */ 0317 virtual IBPtr fullclone() const { return clone(); } 0318 0319 /** @name Functions used by the persistent I/O system. */ 0320 //@{ 0321 /** 0322 * Function used to write out object persistently. 0323 * @param os the persistent output stream written to. 0324 */ 0325 void persistentOutput(PersistentOStream & os) const; 0326 0327 /** 0328 * Function used to read in object persistently. 0329 * @param is the persistent input stream read from. 0330 * @param version the version number of the object when written. 0331 */ 0332 void persistentInput(PersistentIStream & is, int version); 0333 //@} 0334 0335 /** 0336 * Standard Init function. 0337 */ 0338 static void Init(); 0339 0340 protected: 0341 0342 /** 0343 * Return a simple clone of this object. Should be implemented as 0344 * <code>return new_ptr(*this);</code> by a derived class. 0345 */ 0346 virtual IBPtr clone() const = 0; 0347 0348 /** 0349 * Protected default constructor. 0350 */ 0351 InterfacedBase() 0352 : Named(""), isLocked(false), isTouched(true), 0353 initState(uninitialized) {} 0354 0355 /** 0356 * Protected constructor with the name given as argument. 0357 */ 0358 InterfacedBase(string newName) 0359 : Named(newName), isLocked(false), isTouched(true), 0360 initState(uninitialized) {} 0361 0362 /** 0363 * Protected copy-constructor. 0364 */ 0365 InterfacedBase(const InterfacedBase & i) 0366 : Base(i), Named(i), isLocked(false), isTouched(true), 0367 initState(uninitialized), theComment(i.theComment), 0368 objectDefaults(i.objectDefaults) {} 0369 0370 private: 0371 0372 /** 0373 * Set a new name (full name including path). 0374 */ 0375 void name(string newName) { Named::name(newName); } 0376 0377 /** 0378 * Lock this object. 0379 */ 0380 void lock() { isLocked = true; } 0381 0382 /** 0383 * Unlock this object. 0384 */ 0385 void unlock() { isLocked = false; } 0386 0387 /** 0388 * Clear the isTouched flag. 0389 */ 0390 void untouch() { isTouched = false; } 0391 0392 private: 0393 0394 /** 0395 * Used by the interface to add comments. 0396 */ 0397 string addComment(string); 0398 0399 private: 0400 0401 /** 0402 * True if this object is not to be changed by the user interface. 0403 */ 0404 bool isLocked; 0405 0406 /** 0407 * True if this object has been chaged since the last call to 0408 * update(). 0409 */ 0410 bool isTouched; 0411 0412 /** 0413 * Indicate if this object has been initialized or not, or if it is 0414 * being initialized. 0415 */ 0416 InitState initState; 0417 0418 /** 0419 * A comment assigned to this object. 0420 */ 0421 string theComment; 0422 0423 /** 0424 * A map listing object-specific defaults set for the given interfaces. 0425 */ 0426 map<string,string> objectDefaults; 0427 0428 public: 0429 0430 /** 0431 * Print out debugging information for this object on std::cerr. To 0432 * be called from within a debugger via the debug() function. 0433 */ 0434 virtual void debugme() const; 0435 0436 private: 0437 0438 /** 0439 * Standard Initialization object. 0440 */ 0441 static AbstractClassDescription<InterfacedBase> initInterfacedBase; 0442 0443 /** 0444 * Private and non-existent assignment operator. 0445 */ 0446 InterfacedBase & operator=(const InterfacedBase &) = delete; 0447 0448 protected: 0449 0450 /** 0451 * Functor class to be used to update a range of dependent object. 0452 */ 0453 struct UpdateChecker { 0454 /** Constructor. */ 0455 UpdateChecker(bool & touched) : isTouched(touched) {} 0456 /** Constructor. */ 0457 UpdateChecker(const UpdateChecker & uc) : isTouched(uc.isTouched) {} 0458 /** Call the check function for an object. */ 0459 static void check(tIBPtr, bool &); 0460 /** Function call operator. */ 0461 template <typename ptr> void operator()(const ptr & i) { 0462 check(i, isTouched); 0463 } 0464 /** set to false if any check() call fails. */ 0465 bool & isTouched; 0466 }; 0467 0468 /** 0469 * Functor class to be used to update a range of dependent object in a map. 0470 */ 0471 struct UpdateMapChecker { 0472 /** Constructor. */ 0473 UpdateMapChecker(bool & touched) : isTouched(touched) {} 0474 /** Constructor. */ 0475 UpdateMapChecker(const UpdateMapChecker & uc) : isTouched(uc.isTouched) {} 0476 /** Function call operator. */ 0477 template <typename ref> void operator()(const ref & i) { 0478 UpdateChecker::check(i.second, isTouched); 0479 } 0480 /** Reference to the bool variable to be set. */ 0481 bool & isTouched; 0482 }; 0483 0484 }; 0485 0486 /** @cond TRAITSPECIALIZATIONS */ 0487 0488 /** 0489 * This template specialization informs ThePEG about the 0490 * base class of InterfacedBase. 0491 */ 0492 template <> 0493 struct BaseClassTrait<InterfacedBase,1>: public ClassTraitsType { 0494 /** Typedef of the base class of InterfacedBase. */ 0495 typedef PersistentBase NthBase; 0496 }; 0497 0498 /** 0499 * This template specialization informs ThePEG about the name of the 0500 * InterfacedBase class. 0501 */ 0502 template <> 0503 struct ClassTraits<InterfacedBase>: public ClassTraitsBase<InterfacedBase> { 0504 /** Return the class name. */ 0505 static string className() { return "ThePEG::InterfacedBase"; } 0506 }; 0507 0508 /** @endcond */ 0509 0510 } 0511 0512 #endif /* ThePEG_InterfacedBase_H */
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|