CMS 3D CMS Logo

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