Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:28:00

0001 /*----------------------------------------------------------------------
0002   
0003 ----------------------------------------------------------------------*/
0004 
0005 #include "FWCore/Framework/interface/ProducerBase.h"
0006 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0007 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0008 
0009 #include "FWCore/ServiceRegistry/interface/Service.h"
0010 #include "FWCore/Framework/interface/ConstProductRegistry.h"
0011 #include "FWCore/Framework/interface/ProducesCollector.h"
0012 
0013 #include <sstream>
0014 
0015 namespace edm {
0016   ProducerBase::ProducerBase() : ProductRegistryHelper(), callWhenNewProductsRegistered_() {}
0017   ProducerBase::~ProducerBase() noexcept(false) {}
0018 
0019   std::function<void(BranchDescription const&)> ProducerBase::registrationCallback() const {
0020     return callWhenNewProductsRegistered_;
0021   }
0022 
0023   namespace {
0024     class CallbackWrapper {
0025     public:
0026       CallbackWrapper(ProductRegistryHelper* iProd,
0027                       std::function<void(BranchDescription const&)> iCallback,
0028                       ProductRegistry* iReg,
0029                       const ModuleDescription& iDesc)
0030           : prod_(iProd), callback_(iCallback), reg_(iReg), mdesc_(iDesc), lastSize_(iProd->typeLabelList().size()) {}
0031 
0032       void operator()(BranchDescription const& iDesc) {
0033         callback_(iDesc);
0034         addToRegistry();
0035       }
0036 
0037       void addToRegistry() {
0038         ProducerBase::TypeLabelList const& plist = prod_->typeLabelList();
0039 
0040         if (lastSize_ != plist.size()) {
0041           ProducerBase::TypeLabelList::const_iterator pStart = plist.begin();
0042           advance(pStart, lastSize_);
0043           ProductRegistryHelper::addToRegistry(pStart, plist.end(), mdesc_, *reg_, prod_);
0044           lastSize_ = plist.size();
0045         }
0046       }
0047 
0048     private:
0049       ProductRegistryHelper* prod_;
0050       std::function<void(BranchDescription const&)> callback_;
0051       ProductRegistry* reg_;
0052       ModuleDescription mdesc_;
0053       unsigned int lastSize_;
0054     };
0055   }  // namespace
0056 
0057   void ProducerBase::registerProducts(ProducerBase* producer, ProductRegistry* iReg, 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       Service<ConstProductRegistry> regService;
0075       regService->watchProductAdditions(CallbackWrapper(producer, registrationCallback(), iReg, md));
0076     }
0077   }
0078 
0079   void ProducerBase::resolvePutIndicies(BranchType iBranchType,
0080                                         ModuleToResolverIndicies const& iIndicies,
0081                                         std::string const& moduleLabel) {
0082     auto const& plist = typeLabelList();
0083     if (putTokenToResolverIndex_.size() != plist.size()) {
0084       putTokenToResolverIndex_.resize(plist.size(), std::numeric_limits<unsigned int>::max());
0085     }
0086     auto range = iIndicies.equal_range(moduleLabel);
0087     putIndicies_[iBranchType].reserve(iIndicies.count(moduleLabel));
0088     for (auto it = range.first; it != range.second; ++it) {
0089       putIndicies_[iBranchType].push_back(std::get<2>(it->second));
0090       unsigned int i = 0;
0091       for (auto const& tl : plist) {
0092         if (convertToBranchType(tl.transition_) == iBranchType and (tl.typeID_ == *std::get<0>(it->second)) and
0093             (tl.productInstanceName_ == std::get<1>(it->second))) {
0094           putTokenToResolverIndex_[i] = std::get<2>(it->second);
0095           //NOTE: The ExternalLHEProducer puts the 'same' product in at
0096           // both beginRun and endRun. Therefore we can get multiple matches.
0097           // When the module is finally fixed, we can use the 'break'
0098           //break;
0099         }
0100         ++i;
0101       }
0102     }
0103   }
0104 
0105   ProducesCollector ProducerBase::producesCollector() { return ProducesCollector{this}; }
0106 
0107 }  // namespace edm