CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/Fireworks/Core/src/FWModelChangeManager.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWModelChangeManager
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Thu Jan 17 19:13:46 EST 2008
00011 // $Id: FWModelChangeManager.cc,v 1.15 2010/06/18 10:17:16 yana Exp $
00012 //
00013 
00014 // system include files
00015 #include <boost/shared_ptr.hpp>
00016 #include <exception>
00017 
00018 // user include files
00019 #include "Fireworks/Core/interface/FWModelChangeManager.h"
00020 #include "Fireworks/Core/interface/FWEventItem.h"
00021 #include "Fireworks/Core/interface/fwLog.h"
00022 #include "FWCore/Utilities/interface/Exception.h"
00023 
00024 
00025 //
00026 // constants, enums and typedefs
00027 //
00028 
00029 //
00030 // static data member definitions
00031 //
00032 
00033 //
00034 // constructors and destructor
00035 //
00036 FWModelChangeManager::FWModelChangeManager() :
00037    m_depth(0)
00038 {
00039 }
00040 
00041 // FWModelChangeManager::FWModelChangeManager(const FWModelChangeManager& rhs)
00042 // {
00043 //    // do actual copying here;
00044 // }
00045 
00046 FWModelChangeManager::~FWModelChangeManager()
00047 {
00048 }
00049 
00050 //
00051 // assignment operators
00052 //
00053 // const FWModelChangeManager& FWModelChangeManager::operator=(const FWModelChangeManager& rhs)
00054 // {
00055 //   //An exception safe implementation is
00056 //   FWModelChangeManager temp(rhs);
00057 //   swap(rhs);
00058 //
00059 //   return *this;
00060 // }
00061 
00062 //
00063 // member functions
00064 //
00065 void
00066 FWModelChangeManager::beginChanges()
00067 {
00068    ++m_depth;
00069 }
00070 
00071 void
00072 FWModelChangeManager::changed(const FWModelId& iID)
00073 {
00074    FWChangeSentry sentry(*this);
00075    assert(iID.item());
00076    assert(iID.item()->id() < m_changes.size());
00077    m_changes[iID.item()->id()].insert(iID);
00078 }
00079 
00080 void
00081 FWModelChangeManager::changed(const FWEventItem* iItem)
00082 {
00083    FWChangeSentry sentry(*this);
00084    assert(0!= iItem);
00085    m_itemChanges.insert(iItem);
00086    //remove any pending changes on models owned by this item
00087    assert(iItem->id() <m_changes.size());
00088    m_changes[iItem->id()].clear();
00089 }
00090 
00091 static
00092 void sendChangeSignalsAreDone(FWModelChangeManager* iCM)
00093 {
00094    //since this can cause other changes, we might as well aggregate them
00095    FWChangeSentry sentry(*iCM);
00096    iCM->changeSignalsAreDone_();
00097 }
00098 
00099 void
00100 FWModelChangeManager::endChanges()
00101 {
00102    assert(m_depth !=0);
00103    //makes sure that 'changeSignalsAreDone is called if changeSignalsAreComing_ is sent
00104    bool guard(false);
00105    if(0 == --m_depth) {
00106       unsigned int index = 0;
00107       for(std::set<const FWEventItem*>::iterator itChanges = m_itemChanges.begin();
00108           itChanges != m_itemChanges.end();
00109           ++itChanges,++index) {
00110          if( !guard ) {
00111             // boost::shared_ptr<FWModelChangeManager> done(this, &sendChangeSignalsAreDone);
00112             guard = true;
00113             changeSignalsAreComing_();
00114          }
00115          FWItemChangeSignal& signal = m_itemChangeSignals[(*itChanges)->id()];
00116          //loop over the slots ourself so we can control the behavior in case of a failure
00117          FWItemChangeSignal::slot_list_type slots = signal.slots();
00118          for(FWItemChangeSignal::slot_list_type::iterator itSlot=slots.begin(), itEnd = slots.end();
00119              itSlot != itEnd;
00120              ++itSlot) {
00121             try {
00122                (*itSlot)(*itChanges);
00123             } catch(const cms::Exception& iE) {
00124                fwLog(fwlog::kError) <<(*itChanges)->name()<<" had the failure in process FWItemChanged signals\n"<<iE.what()<<std::endl;
00125             } catch(const std::bad_alloc& iE) {
00126                std::cerr <<"Ran out of memory while processing "<<(*itChanges)->name()<<std::endl;
00127                exit(1);
00128             } catch(const std::exception& iE) {
00129                 fwLog(fwlog::kError) <<(*itChanges)->name()<<" had the failure in process FWItemChanged signals (2) \n"<<iE.what()<<std::endl;
00130             }
00131          }
00132       }
00133       m_itemChanges.clear();
00134 
00135       for (size_t ci = 0, ce = m_changes.size(), si = 0; ci != ce; ++ci, ++si)
00136       {
00137          FWModelIds &changes = m_changes[ci];
00138          FWModelChangeSignal &signal = m_changeSignals[si];
00139 
00140          if (not changes.empty()) 
00141          {
00142             if (!guard) 
00143             {
00144                // boost::shared_ptr<FWModelChangeManager> done(this, &sendChangeSignalsAreDone);
00145                guard = true;
00146                changeSignalsAreComing_();
00147             }
00148             //loop over the slots ourself so we can control the behavior in case of a failure
00149             FWModelChangeSignal::slot_list_type slots = signal.slots();
00150             for(FWModelChangeSignal::slot_list_type::iterator itSlot = slots.begin(), itEnd = slots.end();
00151                 itSlot != itEnd;
00152                 ++itSlot) 
00153             {
00154                try 
00155                {
00156                   (*itSlot)(changes);
00157                } 
00158                catch(const cms::Exception& iE) 
00159                {
00160                   fwLog(fwlog::kError) << changes.begin()->item()->name()<<" had the failure in process FWModelChangeSignals\n" 
00161                                       << iE.what() << "\n";
00162                } 
00163                catch(const std::bad_alloc& iE) 
00164                {
00165                   // GE: if we run out of memory why do we assume that we will be able to print?
00166                   fwLog(fwlog::kError) << "Ran out of memory while processing " << changes.begin()->item()->name() << "\n";
00167                   exit(1);
00168                } 
00169                catch(const std::exception& iE) 
00170                {
00171                   fwLog(fwlog::kError) << changes.begin()->item()->name()
00172                                        << " had the failure in process FWModelChangeSignals (2)\n"
00173                                        << iE.what() << "\n";
00174                }
00175             }
00176             changes.clear();
00177          }
00178       }
00179    }
00180    if (guard) sendChangeSignalsAreDone(this);
00181 }
00182 
00183 void
00184 FWModelChangeManager::newItemSlot(FWEventItem* iItem)
00185 {
00186    assert(0!=iItem);
00187    assert(iItem->id() == m_changes.size());
00188    assert(iItem->id() == m_changeSignals.size());
00189    m_changes.push_back(FWModelIds());
00190    m_changeSignals.push_back(FWModelChangeSignal());
00191    m_itemChangeSignals.push_back(FWItemChangeSignal());
00192    //propagate our signal to the item
00193    m_changeSignals.back().connect(iItem->changed_);
00194    m_itemChangeSignals.back().connect(iItem->itemChanged_);
00195 }
00196 
00200 void
00201 FWModelChangeManager::itemsGoingToBeClearedSlot(void)
00202 {
00203    m_changes.clear();
00204    m_changeSignals.clear();
00205 
00206    m_itemChangeSignals.clear();
00207    m_itemChanges.clear();
00208 }
00209 
00210 //
00211 // const member functions
00212 //
00213 
00214 //
00215 // static member functions
00216 //