Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
// -*- C++ -*-
//
// Package:     Core
// Class  :     FWModelChangeManager
//
// Implementation:
//     <Notes on implementation>
//
// Original Author:  Chris Jones
//         Created:  Thu Jan 17 19:13:46 EST 2008
//

// system include files
#include <cassert>
#include <memory>
#include <exception>

// user include files
#include "Fireworks/Core/interface/FWModelChangeManager.h"
#include "Fireworks/Core/interface/FWEventItem.h"
#include "Fireworks/Core/interface/fwLog.h"
#include "FWCore/Utilities/interface/Exception.h"

//
// constants, enums and typedefs
//

//
// static data member definitions
//

//
// constructors and destructor
//
FWModelChangeManager::FWModelChangeManager() : m_depth(0) {}

// FWModelChangeManager::FWModelChangeManager(const FWModelChangeManager& rhs)
// {
//    // do actual copying here;
// }

FWModelChangeManager::~FWModelChangeManager() {}

//
// assignment operators
//
// const FWModelChangeManager& FWModelChangeManager::operator=(const FWModelChangeManager& rhs)
// {
//   //An exception safe implementation is
//   FWModelChangeManager temp(rhs);
//   swap(rhs);
//
//   return *this;
// }

//
// member functions
//
void FWModelChangeManager::beginChanges() { ++m_depth; }

void FWModelChangeManager::changed(const FWModelId& iID) {
  FWChangeSentry sentry(*this);
  assert(iID.item());
  assert(iID.item()->id() < m_changes.size());
  m_changes[iID.item()->id()].insert(iID);
}

void FWModelChangeManager::changed(const FWEventItem* iItem) {
  FWChangeSentry sentry(*this);
  assert(nullptr != iItem);
  m_itemChanges.insert(iItem);
  //remove any pending changes on models owned by this item
  assert(iItem->id() < m_changes.size());
  m_changes[iItem->id()].clear();
}

static void sendChangeSignalsAreDone(FWModelChangeManager* iCM) {
  //since this can cause other changes, we might as well aggregate them
  FWChangeSentry sentry(*iCM);
  iCM->changeSignalsAreDone_();
}

void FWModelChangeManager::endChanges() {
  assert(m_depth != 0);
  //makes sure that 'changeSignalsAreDone is called if changeSignalsAreComing_ is sent
  bool guard(false);
  if (0 == --m_depth) {
    unsigned int index = 0;
    for (std::set<const FWEventItem*>::iterator itChanges = m_itemChanges.begin(); itChanges != m_itemChanges.end();
         ++itChanges, ++index) {
      if (!guard) {
        // std::shared_ptr<FWModelChangeManager> done(this, &sendChangeSignalsAreDone);
        guard = true;
        changeSignalsAreComing_();
      }
      try {
        const FWEventItem* item = (*itChanges);
        item->itemChanged_.emit(item);
      } catch (const cms::Exception& iE) {
        fwLog(fwlog::kError) << (*itChanges)->name() << " had the failure in process FWItemChanged signals\n"
                             << iE.what() << std::endl;
      } catch (const std::bad_alloc& iE) {
        std::cerr << "Ran out of memory while processing " << (*itChanges)->name() << std::endl;
        exit(1);
      } catch (const std::exception& iE) {
        fwLog(fwlog::kError) << (*itChanges)->name() << " had the failure in process FWItemChanged signals (2) \n"
                             << iE.what() << std::endl;
      }
    }
    m_itemChanges.clear();

    for (size_t ci = 0, ce = m_changes.size(), si = 0; ci != ce; ++ci, ++si) {
      FWModelIds& changes = m_changes[ci];
      if (not changes.empty()) {
        if (!guard) {
          // std::shared_ptr<FWModelChangeManager> done(this, &sendChangeSignalsAreDone);
          guard = true;
          changeSignalsAreComing_();
          try {
            const FWEventItem* item = changes.begin()->item();
            item->changed_.emit(changes);
          } catch (const cms::Exception& iE) {
            fwLog(fwlog::kError) << changes.begin()->item()->name()
                                 << " had the failure in process FWModelChangeSignals\n"
                                 << iE.what() << "\n";
          } catch (const std::bad_alloc& iE) {
            // GE: if we run out of memory why do we assume that we will be able to print?
            fwLog(fwlog::kError) << "Ran out of memory while processing " << changes.begin()->item()->name() << "\n";
            exit(1);
          } catch (const std::exception& iE) {
            fwLog(fwlog::kError) << changes.begin()->item()->name()
                                 << " had the failure in process FWModelChangeSignals (2)\n"
                                 << iE.what() << "\n";
          }
        }
      }
      changes.clear();
    }
  }

  if (guard)
    sendChangeSignalsAreDone(this);
}

void FWModelChangeManager::newItemSlot(FWEventItem* iItem) {
  assert(nullptr != iItem);
  assert(iItem->id() == m_changes.size());
  assert(iItem->id() == m_changeSignals.size());
  m_changes.push_back(FWModelIds());
  m_changeSignals.push_back(FWModelChangeSignal());
  m_itemChangeSignals.push_back(FWItemChangeSignal());
  //propagate our signal to the item
  m_changeSignals.back().connect(iItem->changed_);
  m_itemChangeSignals.back().connect(iItem->itemChanged_);
}

/** Whenever all the items are removed from the FWItemsManager
    clean also the associated vectors here.
  */
void FWModelChangeManager::itemsGoingToBeClearedSlot(void) {
  m_changes.clear();
  m_changeSignals.clear();

  m_itemChangeSignals.clear();
  m_itemChanges.clear();
}

//
// const member functions
//

//
// static member functions
//