Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:07:16

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIKERNEL_IUPDATEMANAGERSVC_H
0012 #define GAUDIKERNEL_IUPDATEMANAGERSVC_H 1
0013 
0014 // Include files
0015 // from STL
0016 #include <string>
0017 #include <typeinfo>
0018 
0019 // from Gaudi
0020 #include "GaudiKernel/IInterface.h"
0021 
0022 // forward declarations
0023 class DataObject;
0024 class ValidDataObject;
0025 class IUpdateManagerSvc;
0026 class IDataProviderSvc;
0027 class IDetDataSvc;
0028 namespace Gaudi {
0029   class Time;
0030 }
0031 
0032 /** @class BaseObjectMemberFunction
0033  *
0034  * Base class of ObjectMemberFunction. It is used to allow to use containers of
0035  * different types of object member functions. \see ObjectMemberFunction for details.
0036  *
0037  * @author Marco Clemencic
0038  */
0039 class BaseObjectMemberFunction {
0040 public:
0041   /// Virtual destructor.
0042   virtual ~BaseObjectMemberFunction() = default;
0043 
0044   virtual StatusCode operator()() const = 0;
0045 
0046   virtual BaseObjectMemberFunction* makeCopy() const = 0;
0047 
0048   virtual const std::type_info& type() const = 0;
0049 
0050   virtual bool match( BaseObjectMemberFunction* ) const = 0;
0051 
0052   virtual DataObject*      castToDataObject() const      = 0;
0053   virtual ValidDataObject* castToValidDataObject() const = 0;
0054   virtual void*            castToVoid() const            = 0;
0055 };
0056 
0057 /** @class ObjectMemberFunction
0058  *
0059  * This class is used by IUpdateManagerSvc to keep pairs made of a member function and a pointer
0060  * to the object for which that member function has to be called.
0061  *
0062  * @author Marco Clemencic
0063  */
0064 template <class CallerClass>
0065 class ObjectMemberFunction final : public BaseObjectMemberFunction {
0066 public:
0067   /// MemberFunctionType is the type for a pointer to a member function of class CallerClass.
0068   typedef StatusCode ( CallerClass::*MemberFunctionType )();
0069 
0070   /// Calls the member function of the object and returns the StatusCode.
0071   /// If the pointer to the member function is nullptr, do nothing and return success.
0072   StatusCode operator()() const override {
0073     return m_memberFunction ? ( m_instance->*m_memberFunction )() : StatusCode::SUCCESS;
0074   }
0075 
0076   /// Clone method to be able to copy an ObjectMemberFunction from the BaseObjectMemberFunction
0077   /// interface.
0078   BaseObjectMemberFunction* makeCopy() const override {
0079     return new ObjectMemberFunction{ m_instance, m_memberFunction };
0080   }
0081 
0082   /// Returns the type_info of the CallerClass
0083   const std::type_info& type() const override { return typeid( CallerClass ); }
0084 
0085   /// Comparison between two BaseObjectMemberFunction instances.
0086   bool match( BaseObjectMemberFunction* bmf ) const override {
0087     if ( bmf == (BaseObjectMemberFunction*)this ) return true;
0088     if ( type() == bmf->type() ) {
0089       ObjectMemberFunction* mf = dynamic_cast<ObjectMemberFunction*>( bmf );
0090       return m_instance == mf->m_instance && m_memberFunction == mf->m_memberFunction;
0091     }
0092     return false;
0093   }
0094 
0095   /// Cast the object to DataObject.
0096   DataObject* castToDataObject() const override { return dynamic_cast<DataObject*>( m_instance ); }
0097 
0098   /// Cast the object to ValidDataObject.
0099   ValidDataObject* castToValidDataObject() const override { return dynamic_cast<ValidDataObject*>( m_instance ); }
0100 
0101   /// Cast the object to void with dynamic_cast.
0102   void* castToVoid() const override { return dynamic_cast<void*>( m_instance ); }
0103 
0104 protected:
0105   /// Standard constructor. Protected so that can be called only by itself or IUpdateManagerSvc.
0106   ObjectMemberFunction( CallerClass* instance, const MemberFunctionType& mf )
0107       : m_instance( instance ), m_memberFunction( mf ) {}
0108 
0109   /// Pointer to the object.
0110   CallerClass* m_instance;
0111 
0112   /// Pointer to the member function.
0113   MemberFunctionType m_memberFunction;
0114 
0115   friend class IUpdateManagerSvc;
0116 };
0117 
0118 /** @class BasePtrSetter
0119  *
0120  * Base class to set the pointer to an object of a class derived from DataObject in a generic way.
0121  *
0122  *  @author Marco CLEMENCIC
0123  *  @date   2005-12-14
0124  */
0125 class BasePtrSetter {
0126 public:
0127   /// Empty virtual destructor.
0128   virtual ~BasePtrSetter() = default;
0129   /// sets the internal pointer to the provided data object (with a dynamic_cast).
0130   virtual void set( DataObject* ) = 0;
0131   /// tells if the internal pointer is nullptr.
0132   virtual bool isNull() = 0;
0133 };
0134 
0135 /** @class IUpdateManagerSvc IUpdateManagerSvc.h GaudiKernel/IUpdateManagerSvc.h
0136  *
0137  *  Interface class to the Update Manager service. Users should only use this interface.
0138  *
0139  *  @author Marco CLEMENCIC
0140  *  @date   2005-03-30
0141  */
0142 class GAUDI_API IUpdateManagerSvc : virtual public IInterface {
0143 private:
0144   /** @class PtrSetter
0145    *
0146    * Templated specialization of BasePtrSetter.
0147    */
0148   template <class ActualType>
0149   class PtrSetter final : public BasePtrSetter {
0150   public:
0151     using dest_type = ActualType;
0152     PtrSetter( dest_type*& dest ) : m_storage( &dest ) { *m_storage = nullptr; }
0153     void set( DataObject* obj ) override { *m_storage = dynamic_cast<dest_type*>( obj ); }
0154     bool isNull() override { return *m_storage == nullptr; }
0155 
0156   private:
0157     /// pointer to the pointer to fill provided by the user.
0158     dest_type** m_storage;
0159   };
0160 
0161 public:
0162   /// InterfaceID
0163   DeclareInterfaceID( IUpdateManagerSvc, 2, 0 );
0164 
0165   /// Give access to the data provider.
0166   virtual IDataProviderSvc* dataProvider() const = 0;
0167 
0168   /// Give access to the detector data service interface (usualy of the data provider itself).
0169   virtual IDetDataSvc* detDataSvc() const = 0;
0170 
0171   /// Register an object (algorithm instance) to the service.
0172   /// The object should provide a method to be called in case of an update of
0173   /// the needed condition. An object can register multiple conditions using the
0174   /// same method: it will be called if at least one of the specified conditions
0175   /// is updated, but only when all of them are up to date.
0176   /// \return StatusCode::SUCCESS if the registration went right.
0177   template <class CallerClass>
0178   inline void registerCondition( CallerClass* instance, const std::string& condition = "",
0179                                  typename ObjectMemberFunction<CallerClass>::MemberFunctionType mf = nullptr ) {
0180     i_registerCondition( condition, new ObjectMemberFunction{ instance, mf } );
0181   }
0182 
0183   template <class CallerClass, class CondType>
0184   inline void registerCondition( CallerClass* instance, const std::string& condition,
0185                                  typename ObjectMemberFunction<CallerClass>::MemberFunctionType mf,
0186                                  CondType*&                                                     condPtrDest ) {
0187     i_registerCondition( condition, new ObjectMemberFunction{ instance, mf }, new PtrSetter{ condPtrDest } );
0188   }
0189 
0190   /// See above. Needed to avoid conflicts with the next one.
0191   template <class CallerClass>
0192   inline void registerCondition( CallerClass* instance, const char* condition,
0193                                  typename ObjectMemberFunction<CallerClass>::MemberFunctionType mf = nullptr ) {
0194     i_registerCondition( std::string( condition ), new ObjectMemberFunction{ instance, mf } );
0195   }
0196 
0197   /// Like the first version of registerCondition, but instead declaring the dependency on a condition of the service
0198   /// privider, it uses an already registered object. It means that a generic object can depend on another generic
0199   /// object that depends on a ValidDataObject. The dependency network is kept consistent by the UpdateManagerSvc.
0200   template <class CallerClass, class ObjectClass>
0201   inline void registerCondition( CallerClass* instance, ObjectClass* obj,
0202                                  typename ObjectMemberFunction<CallerClass>::MemberFunctionType mf = nullptr ) {
0203     i_registerCondition( dynamic_cast<void*>( obj ), new ObjectMemberFunction{ instance, mf } );
0204   }
0205 
0206   /// Generic objects can be unregistered from the UpdateManagerSvc. The dependency network is always consistent, but
0207   /// internal IOVs are not modified. \warning{Removing a node which other nodes depends on can create problems if the
0208   /// methods of this other nodes are called.}
0209   template <class CallerClass>
0210   inline void unregister( CallerClass* instance ) {
0211     i_unregister( dynamic_cast<void*>( instance ) );
0212   }
0213 
0214   /// Invalidate the given object in the dependency network. It means that all the objects depending on that one will
0215   /// be updated before the next event.
0216   template <class CallerClass>
0217   inline void invalidate( CallerClass* instance ) {
0218     i_invalidate( dynamic_cast<void*>( instance ) );
0219   }
0220 
0221   /// Retrieve the interval of validity (in the UpdateManagerSvc) of the given item.
0222   /// @return false if the item was not found.
0223   virtual bool getValidity( const std::string path, Gaudi::Time& since, Gaudi::Time& until,
0224                             bool path_to_db = false ) = 0;
0225 
0226   /// Change the interval of validity of the given item to the specified values, updating parents if needed.
0227   /// The change can only restrict the current IOV, If you want to expand the validity you should act on the transient
0228   /// data store
0229   /// and the change will be reflected at the next update.
0230   virtual void setValidity( const std::string path, const Gaudi::Time& since, const Gaudi::Time& until,
0231                             bool path_to_db = false ) = 0;
0232 
0233   /// Start an update loop using the event time given by the detector data service.
0234   virtual StatusCode newEvent() = 0;
0235   /// Start an update loop using the give event time.
0236   /// NOTE: the given event time is only used to check if updates are needed, the real update is done
0237   /// using the detector data service event time. (may change in future)
0238   virtual StatusCode newEvent( const Gaudi::Time& ) = 0;
0239 
0240   /// Update the given instance. This method should be called by the object after registration to ensure
0241   /// that the needed operations is done immediately and not before the next event.
0242   template <class CallerClass>
0243   inline StatusCode update( CallerClass* instance ) {
0244     return i_update( dynamic_cast<void*>( instance ) );
0245   }
0246 
0247   /// Debug method: it dumps the dependency network through the message service (not very readable, for experts only).
0248   virtual void dump() = 0;
0249 
0250   /// Force the update manager service to wait before entering the newEvent loop.
0251   virtual void acquireLock() = 0;
0252   /// Let the update manager service enter the newEvent loop.
0253   virtual void releaseLock() = 0;
0254 
0255   /// Remove all the items referring to objects present in the transient store.
0256   /// This is needed when the Detector Transient Store is purged, otherwise we
0257   /// will keep pointers to not existing objects.
0258   virtual void purge() = 0;
0259 
0260   /** @class IUpdateManagerSvc::PythonHelper
0261    * Helper class implemented in the python dictionary to allow access from python to
0262    * template member functions.
0263    */
0264   class PythonHelper;
0265 
0266 protected:
0267   // virtual StatusCode i_registerCondition(const std::string &condition, BaseObjectMemberFunction *mf) = 0;
0268   virtual void       i_registerCondition( const std::string& condition, BaseObjectMemberFunction* mf,
0269                                           BasePtrSetter* ptr_dest = nullptr )       = 0;
0270   virtual void       i_registerCondition( void* obj, BaseObjectMemberFunction* mf ) = 0;
0271   virtual StatusCode i_update( void* instance )                                     = 0;
0272   virtual void       i_unregister( void* instance )                                 = 0;
0273   virtual void       i_invalidate( void* instance )                                 = 0;
0274 
0275   friend class PythonHelper;
0276 };
0277 #endif // GAUDIKERNEL_IUPDATEMANAGERSVC_H