Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:41

0001 // -*- C++ -*-
0002 //
0003 // Package:     Core
0004 // Class  :     FWModelChangeManager
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Chris Jones
0010 //         Created:  Thu Jan 17 19:13:46 EST 2008
0011 //
0012 
0013 // system include files
0014 #include <cassert>
0015 #include <memory>
0016 #include <exception>
0017 
0018 // user include files
0019 #include "Fireworks/Core/interface/FWModelChangeManager.h"
0020 #include "Fireworks/Core/interface/FWEventItem.h"
0021 #include "Fireworks/Core/interface/fwLog.h"
0022 #include "FWCore/Utilities/interface/Exception.h"
0023 
0024 //
0025 // constants, enums and typedefs
0026 //
0027 
0028 //
0029 // static data member definitions
0030 //
0031 
0032 //
0033 // constructors and destructor
0034 //
0035 FWModelChangeManager::FWModelChangeManager() : m_depth(0) {}
0036 
0037 // FWModelChangeManager::FWModelChangeManager(const FWModelChangeManager& rhs)
0038 // {
0039 //    // do actual copying here;
0040 // }
0041 
0042 FWModelChangeManager::~FWModelChangeManager() {}
0043 
0044 //
0045 // assignment operators
0046 //
0047 // const FWModelChangeManager& FWModelChangeManager::operator=(const FWModelChangeManager& rhs)
0048 // {
0049 //   //An exception safe implementation is
0050 //   FWModelChangeManager temp(rhs);
0051 //   swap(rhs);
0052 //
0053 //   return *this;
0054 // }
0055 
0056 //
0057 // member functions
0058 //
0059 void FWModelChangeManager::beginChanges() { ++m_depth; }
0060 
0061 void FWModelChangeManager::changed(const FWModelId& iID) {
0062   FWChangeSentry sentry(*this);
0063   assert(iID.item());
0064   assert(iID.item()->id() < m_changes.size());
0065   m_changes[iID.item()->id()].insert(iID);
0066 }
0067 
0068 void FWModelChangeManager::changed(const FWEventItem* iItem) {
0069   FWChangeSentry sentry(*this);
0070   assert(nullptr != iItem);
0071   m_itemChanges.insert(iItem);
0072   //remove any pending changes on models owned by this item
0073   assert(iItem->id() < m_changes.size());
0074   m_changes[iItem->id()].clear();
0075 }
0076 
0077 static void sendChangeSignalsAreDone(FWModelChangeManager* iCM) {
0078   //since this can cause other changes, we might as well aggregate them
0079   FWChangeSentry sentry(*iCM);
0080   iCM->changeSignalsAreDone_();
0081 }
0082 
0083 void FWModelChangeManager::endChanges() {
0084   assert(m_depth != 0);
0085   //makes sure that 'changeSignalsAreDone is called if changeSignalsAreComing_ is sent
0086   bool guard(false);
0087   if (0 == --m_depth) {
0088     unsigned int index = 0;
0089     for (std::set<const FWEventItem*>::iterator itChanges = m_itemChanges.begin(); itChanges != m_itemChanges.end();
0090          ++itChanges, ++index) {
0091       if (!guard) {
0092         // std::shared_ptr<FWModelChangeManager> done(this, &sendChangeSignalsAreDone);
0093         guard = true;
0094         changeSignalsAreComing_();
0095       }
0096       try {
0097         const FWEventItem* item = (*itChanges);
0098         item->itemChanged_.emit(item);
0099       } catch (const cms::Exception& iE) {
0100         fwLog(fwlog::kError) << (*itChanges)->name() << " had the failure in process FWItemChanged signals\n"
0101                              << iE.what() << std::endl;
0102       } catch (const std::bad_alloc& iE) {
0103         std::cerr << "Ran out of memory while processing " << (*itChanges)->name() << std::endl;
0104         exit(1);
0105       } catch (const std::exception& iE) {
0106         fwLog(fwlog::kError) << (*itChanges)->name() << " had the failure in process FWItemChanged signals (2) \n"
0107                              << iE.what() << std::endl;
0108       }
0109     }
0110     m_itemChanges.clear();
0111 
0112     for (size_t ci = 0, ce = m_changes.size(), si = 0; ci != ce; ++ci, ++si) {
0113       FWModelIds& changes = m_changes[ci];
0114       if (not changes.empty()) {
0115         if (!guard) {
0116           // std::shared_ptr<FWModelChangeManager> done(this, &sendChangeSignalsAreDone);
0117           guard = true;
0118           changeSignalsAreComing_();
0119           try {
0120             const FWEventItem* item = changes.begin()->item();
0121             item->changed_.emit(changes);
0122           } catch (const cms::Exception& iE) {
0123             fwLog(fwlog::kError) << changes.begin()->item()->name()
0124                                  << " had the failure in process FWModelChangeSignals\n"
0125                                  << iE.what() << "\n";
0126           } catch (const std::bad_alloc& iE) {
0127             // GE: if we run out of memory why do we assume that we will be able to print?
0128             fwLog(fwlog::kError) << "Ran out of memory while processing " << changes.begin()->item()->name() << "\n";
0129             exit(1);
0130           } catch (const std::exception& iE) {
0131             fwLog(fwlog::kError) << changes.begin()->item()->name()
0132                                  << " had the failure in process FWModelChangeSignals (2)\n"
0133                                  << iE.what() << "\n";
0134           }
0135         }
0136       }
0137       changes.clear();
0138     }
0139   }
0140 
0141   if (guard)
0142     sendChangeSignalsAreDone(this);
0143 }
0144 
0145 void FWModelChangeManager::newItemSlot(FWEventItem* iItem) {
0146   assert(nullptr != iItem);
0147   assert(iItem->id() == m_changes.size());
0148   assert(iItem->id() == m_changeSignals.size());
0149   m_changes.push_back(FWModelIds());
0150   m_changeSignals.push_back(FWModelChangeSignal());
0151   m_itemChangeSignals.push_back(FWItemChangeSignal());
0152   //propagate our signal to the item
0153   m_changeSignals.back().connect(iItem->changed_);
0154   m_itemChangeSignals.back().connect(iItem->itemChanged_);
0155 }
0156 
0157 /** Whenever all the items are removed from the FWItemsManager
0158     clean also the associated vectors here.
0159   */
0160 void FWModelChangeManager::itemsGoingToBeClearedSlot(void) {
0161   m_changes.clear();
0162   m_changeSignals.clear();
0163 
0164   m_itemChangeSignals.clear();
0165   m_itemChanges.clear();
0166 }
0167 
0168 //
0169 // const member functions
0170 //
0171 
0172 //
0173 // static member functions
0174 //