CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/FWCore/Framework/src/ProducerBase.cc

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------
00002   
00003 ----------------------------------------------------------------------*/
00004 
00005 #include "FWCore/Framework/interface/ProducerBase.h"
00006 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00007 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00008 
00009 #include "FWCore/ServiceRegistry/interface/Service.h"
00010 #include "FWCore/Framework/interface/ConstProductRegistry.h"
00011 
00012 #include <sstream>
00013 
00014 namespace edm {
00015   ProducerBase::ProducerBase() : ProductRegistryHelper(), callWhenNewProductsRegistered_() {}
00016   ProducerBase::~ProducerBase() { }
00017 
00018    std::function<void(BranchDescription const&)> ProducerBase::registrationCallback() const {
00019       return callWhenNewProductsRegistered_;
00020    }
00021 
00022 
00023    namespace {
00024      class CallbackWrapper {
00025        public:  
00026         CallbackWrapper(ProducerBase* iProd,
00027                         std::function<void(BranchDescription const&)> iCallback,
00028                         ProductRegistry* iReg,
00029                         const ModuleDescription& iDesc):
00030         prod_(iProd), callback_(iCallback), reg_(iReg), mdesc_(iDesc),
00031         lastSize_(iProd->typeLabelList().size()) {}
00032         
00033         void operator()(BranchDescription const& iDesc) {
00034            callback_(iDesc);
00035            addToRegistry();
00036         }
00037         
00038         void addToRegistry() {
00039            ProducerBase::TypeLabelList const& plist = prod_->typeLabelList();
00040            
00041            if(lastSize_!=plist.size()){
00042               ProducerBase::TypeLabelList::const_iterator pStart = plist.begin();
00043               advance(pStart, lastSize_);
00044               ProductRegistryHelper::addToRegistry(pStart, plist.end() ,mdesc_, *reg_);
00045               lastSize_ = plist.size();
00046            }
00047         }
00048 
00049       private:
00050         ProducerBase* prod_;
00051         std::function<void(BranchDescription const&)> callback_;
00052         ProductRegistry* reg_;
00053         ModuleDescription mdesc_;
00054         unsigned int lastSize_;
00055          
00056      };
00057   }
00058 
00059 
00060   void ProducerBase::registerProducts(ProducerBase* producer,
00061                                 ProductRegistry* iReg,
00062                                 ModuleDescription const& md)
00063   {
00064     if (typeLabelList().empty() && !registrationCallback()) {
00065       return;
00066     }
00067     //If we have a callback, first tell the callback about all the entries already in the
00068     // product registry, then add any items this producer wants to add to the registry 
00069     // and only after that do we register the callback. This is done so the callback does not
00070     // get called for items registered by this producer (avoids circular reference problems)
00071     bool isListener = false;
00072     if(registrationCallback()) {
00073        isListener=true;
00074        iReg->callForEachBranch(registrationCallback());
00075     }
00076     TypeLabelList const& plist = typeLabelList();
00077 
00078     ProductRegistryHelper::addToRegistry(plist.begin(), plist.end(), md, *(iReg), isListener);
00079     if(registrationCallback()) {
00080        Service<ConstProductRegistry> regService;
00081        regService->watchProductAdditions(CallbackWrapper(producer, registrationCallback(), iReg, md));
00082     }
00083   }
00084 }