CMS 3D CMS Logo

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