CMS 3D CMS Logo

FWModelChangeManager.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Core
4 // Class : FWModelChangeManager
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Thu Jan 17 19:13:46 EST 2008
11 //
12 
13 // system include files
14 #include <cassert>
15 #include <memory>
16 #include <exception>
17 
18 // user include files
23 
24 
25 //
26 // constants, enums and typedefs
27 //
28 
29 //
30 // static data member definitions
31 //
32 
33 //
34 // constructors and destructor
35 //
37  m_depth(0)
38 {
39 }
40 
41 // FWModelChangeManager::FWModelChangeManager(const FWModelChangeManager& rhs)
42 // {
43 // // do actual copying here;
44 // }
45 
47 {
48 }
49 
50 //
51 // assignment operators
52 //
53 // const FWModelChangeManager& FWModelChangeManager::operator=(const FWModelChangeManager& rhs)
54 // {
55 // //An exception safe implementation is
56 // FWModelChangeManager temp(rhs);
57 // swap(rhs);
58 //
59 // return *this;
60 // }
61 
62 //
63 // member functions
64 //
65 void
67 {
68  ++m_depth;
69 }
70 
71 void
73 {
74  FWChangeSentry sentry(*this);
75  assert(iID.item());
76  assert(iID.item()->id() < m_changes.size());
77  m_changes[iID.item()->id()].insert(iID);
78 }
79 
80 void
82 {
83  FWChangeSentry sentry(*this);
84  assert(nullptr!= iItem);
85  m_itemChanges.insert(iItem);
86  //remove any pending changes on models owned by this item
87  assert(iItem->id() <m_changes.size());
88  m_changes[iItem->id()].clear();
89 }
90 
91 static
93 {
94  //since this can cause other changes, we might as well aggregate them
95  FWChangeSentry sentry(*iCM);
96  iCM->changeSignalsAreDone_();
97 }
98 
99 void
101 {
102  assert(m_depth !=0);
103  //makes sure that 'changeSignalsAreDone is called if changeSignalsAreComing_ is sent
104  bool guard(false);
105  if(0 == --m_depth) {
106  unsigned int index = 0;
107  for(std::set<const FWEventItem*>::iterator itChanges = m_itemChanges.begin();
108  itChanges != m_itemChanges.end();
109  ++itChanges,++index) {
110  if( !guard ) {
111  // std::shared_ptr<FWModelChangeManager> done(this, &sendChangeSignalsAreDone);
112  guard = true;
114  }
115  FWItemChangeSignal& signal = m_itemChangeSignals[(*itChanges)->id()];
116  //loop over the slots ourself so we can control the behavior in case of a failure
117  FWItemChangeSignal::slot_list_type slots = signal.slots();
118  for(FWItemChangeSignal::slot_list_type::iterator itSlot=slots.begin(), itEnd = slots.end();
119  itSlot != itEnd;
120  ++itSlot) {
121  try {
122  (*itSlot)(*itChanges);
123  } catch(const cms::Exception& iE) {
124  fwLog(fwlog::kError) <<(*itChanges)->name()<<" had the failure in process FWItemChanged signals\n"<<iE.what()<<std::endl;
125  } catch(const std::bad_alloc& iE) {
126  std::cerr <<"Ran out of memory while processing "<<(*itChanges)->name()<<std::endl;
127  exit(1);
128  } catch(const std::exception& iE) {
129  fwLog(fwlog::kError) <<(*itChanges)->name()<<" had the failure in process FWItemChanged signals (2) \n"<<iE.what()<<std::endl;
130  }
131  }
132  }
133  m_itemChanges.clear();
134 
135  for (size_t ci = 0, ce = m_changes.size(), si = 0; ci != ce; ++ci, ++si)
136  {
137  FWModelIds &changes = m_changes[ci];
138  FWModelChangeSignal &signal = m_changeSignals[si];
139 
140  if (not changes.empty())
141  {
142  if (!guard)
143  {
144  // std::shared_ptr<FWModelChangeManager> done(this, &sendChangeSignalsAreDone);
145  guard = true;
147  }
148  //loop over the slots ourself so we can control the behavior in case of a failure
149  FWModelChangeSignal::slot_list_type slots = signal.slots();
150  for(FWModelChangeSignal::slot_list_type::iterator itSlot = slots.begin(), itEnd = slots.end();
151  itSlot != itEnd;
152  ++itSlot)
153  {
154  try
155  {
156  (*itSlot)(changes);
157  }
158  catch(const cms::Exception& iE)
159  {
160  fwLog(fwlog::kError) << changes.begin()->item()->name()<<" had the failure in process FWModelChangeSignals\n"
161  << iE.what() << "\n";
162  }
163  catch(const std::bad_alloc& iE)
164  {
165  // GE: if we run out of memory why do we assume that we will be able to print?
166  fwLog(fwlog::kError) << "Ran out of memory while processing " << changes.begin()->item()->name() << "\n";
167  exit(1);
168  }
169  catch(const std::exception& iE)
170  {
171  fwLog(fwlog::kError) << changes.begin()->item()->name()
172  << " had the failure in process FWModelChangeSignals (2)\n"
173  << iE.what() << "\n";
174  }
175  }
176  changes.clear();
177  }
178  }
179  }
180  if (guard) sendChangeSignalsAreDone(this);
181 }
182 
183 void
185 {
186  assert(nullptr!=iItem);
187  assert(iItem->id() == m_changes.size());
188  assert(iItem->id() == m_changeSignals.size());
189  m_changes.push_back(FWModelIds());
192  //propagate our signal to the item
193  m_changeSignals.back().connect(iItem->changed_);
194  m_itemChangeSignals.back().connect(iItem->itemChanged_);
195 }
196 
200 void
202 {
203  m_changes.clear();
204  m_changeSignals.clear();
205 
206  m_itemChangeSignals.clear();
207  m_itemChanges.clear();
208 }
209 
210 //
211 // const member functions
212 //
213 
214 //
215 // static member functions
216 //
sigc::signal< void, const FWEventItem * > FWItemChangeSignal
sigc::signal< void, const FWModelIds & > FWModelChangeSignal
std::vector< FWModelChangeSignal > m_changeSignals
std::vector< FWModelIds > m_changes
char const * what() const override
Definition: Exception.cc:141
static void sendChangeSignalsAreDone(FWModelChangeManager *iCM)
std::set< const FWEventItem * > m_itemChanges
void newItemSlot(FWEventItem *)
std::set< FWModelId > FWModelIds
FWItemChangeSignal itemChanged_
Definition: FWEventItem.h:202
unsigned int id() const
Definition: FWEventItem.cc:496
sigc::signal< void > changeSignalsAreDone_
void changed(const FWModelId &)
#define fwLog(_level_)
Definition: fwLog.h:50
std::vector< FWItemChangeSignal > m_itemChangeSignals
sigc::signal< void > changeSignalsAreComing_
FWModelChangeSignal changed_
Definition: FWEventItem.h:199
const FWEventItem * item() const
Definition: FWModelId.h:44