Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-13 02:31:52

0001 /*----------------------------------------------------------------------
0002   
0003 ----------------------------------------------------------------------*/
0004 
0005 #include "FWCore/Framework/interface/ProducerBase.h"
0006 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0007 #include "FWCore/Framework/interface/SignallingProductRegistryFiller.h"
0008 
0009 #include "FWCore/Framework/interface/ProducesCollector.h"
0010 
0011 #include <sstream>
0012 
0013 namespace edm {
0014   ProducerBase::ProducerBase() : ProductRegistryHelper(), callWhenNewProductsRegistered_() {}
0015   ProducerBase::~ProducerBase() noexcept(false) {}
0016 
0017   std::function<void(ProductDescription const&)> ProducerBase::registrationCallback() const {
0018     return callWhenNewProductsRegistered_;
0019   }
0020 
0021   namespace {
0022     class CallbackWrapper {
0023     public:
0024       CallbackWrapper(ProductRegistryHelper* iProd,
0025                       std::function<void(ProductDescription const&)> iCallback,
0026                       SignallingProductRegistryFiller* iReg,
0027                       const ModuleDescription& iDesc)
0028           : prod_(iProd), callback_(iCallback), reg_(iReg), mdesc_(iDesc), lastSize_(iProd->typeLabelList().size()) {}
0029 
0030       void operator()(ProductDescription const& iDesc) {
0031         callback_(iDesc);
0032         addToRegistry();
0033       }
0034 
0035       void addToRegistry() {
0036         ProducerBase::TypeLabelList const& plist = prod_->typeLabelList();
0037 
0038         if (lastSize_ != plist.size()) {
0039           ProducerBase::TypeLabelList::const_iterator pStart = plist.begin();
0040           advance(pStart, lastSize_);
0041           ProductRegistryHelper::addToRegistry(pStart, plist.end(), mdesc_, *reg_, prod_);
0042           lastSize_ = plist.size();
0043         }
0044       }
0045 
0046     private:
0047       ProductRegistryHelper* prod_;
0048       std::function<void(ProductDescription const&)> callback_;
0049       SignallingProductRegistryFiller* reg_;
0050       ModuleDescription mdesc_;
0051       unsigned int lastSize_;
0052     };
0053   }  // namespace
0054 
0055   void ProducerBase::registerProducts(ProducerBase* producer,
0056                                       SignallingProductRegistryFiller* iReg,
0057                                       ModuleDescription const& md) {
0058     if (typeLabelList().empty() && !registrationCallback()) {
0059       return;
0060     }
0061     //If we have a callback, first tell the callback about all the entries already in the
0062     // product registry, then add any items this producer wants to add to the registry
0063     // and only after that do we register the callback. This is done so the callback does not
0064     // get called for items registered by this producer (avoids circular reference problems)
0065     bool isListener = false;
0066     if (registrationCallback()) {
0067       isListener = true;
0068       iReg->callForEachBranch(registrationCallback());
0069     }
0070     TypeLabelList const& plist = typeLabelList();
0071 
0072     ProductRegistryHelper::addToRegistry(plist.begin(), plist.end(), md, *(iReg), this, isListener);
0073     if (registrationCallback()) {
0074       iReg->watchProductAdditions(CallbackWrapper(producer, registrationCallback(), iReg, md));
0075     }
0076   }
0077 
0078   void ProducerBase::resolvePutIndicies(BranchType iBranchType,
0079                                         ModuleToResolverIndicies const& iIndicies,
0080                                         std::string const& moduleLabel) {
0081     auto const& plist = typeLabelList();
0082     if (putTokenToResolverIndex_.size() != plist.size()) {
0083       putTokenToResolverIndex_.resize(plist.size(), std::numeric_limits<unsigned int>::max());
0084     }
0085     auto range = iIndicies.equal_range(moduleLabel);
0086     putIndicies_[iBranchType].reserve(iIndicies.count(moduleLabel));
0087     for (auto it = range.first; it != range.second; ++it) {
0088       putIndicies_[iBranchType].push_back(std::get<2>(it->second));
0089       unsigned int i = 0;
0090       for (auto const& tl : plist) {
0091         if (convertToBranchType(tl.transition_) == iBranchType and (tl.typeID_ == *std::get<0>(it->second)) and
0092             (tl.productInstanceName_ == std::get<1>(it->second))) {
0093           putTokenToResolverIndex_[i] = std::get<2>(it->second);
0094           //NOTE: The ExternalLHEProducer puts the 'same' product in at
0095           // both beginRun and endRun. Therefore we can get multiple matches.
0096           // When the module is finally fixed, we can use the 'break'
0097           //break;
0098         }
0099         ++i;
0100       }
0101     }
0102   }
0103 
0104   ProducesCollector ProducerBase::producesCollector() { return ProducesCollector{this}; }
0105 
0106 }  // namespace edm