141 |
141 |
142 /// \brief Default constructor. |
142 /// \brief Default constructor. |
143 /// |
143 /// |
144 /// Default constructor for ObserverBase. |
144 /// Default constructor for ObserverBase. |
145 /// |
145 /// |
146 ObserverBase() : notifier(0) {} |
146 ObserverBase() : _notifier(0) {} |
147 |
147 |
148 /// \brief Constructor which attach the observer into notifier. |
148 /// \brief Constructor which attach the observer into notifier. |
149 /// |
149 /// |
150 /// Constructor which attach the observer into notifier. |
150 /// Constructor which attach the observer into notifier. |
151 ObserverBase(AlterationNotifier& _notifier) { |
151 ObserverBase(AlterationNotifier& notifier) { |
152 attach(_notifier); |
152 attach(notifier); |
153 } |
153 } |
154 |
154 |
155 /// \brief Constructor which attach the obserever to the same notifier. |
155 /// \brief Constructor which attach the obserever to the same notifier. |
156 /// |
156 /// |
157 /// Constructor which attach the obserever to the same notifier as |
157 /// Constructor which attach the obserever to the same notifier as |
158 /// the other observer is attached to. |
158 /// the other observer is attached to. |
159 ObserverBase(const ObserverBase& copy) { |
159 ObserverBase(const ObserverBase& copy) { |
160 if (copy.attached()) { |
160 if (copy.attached()) { |
161 attach(*copy.getNotifier()); |
161 attach(*copy._notifier()); |
162 } |
162 } |
163 } |
163 } |
164 |
164 |
165 /// \brief Destructor |
165 /// \brief Destructor |
166 virtual ~ObserverBase() { |
166 virtual ~ObserverBase() { |
171 |
171 |
172 /// \brief Attaches the observer into an AlterationNotifier. |
172 /// \brief Attaches the observer into an AlterationNotifier. |
173 /// |
173 /// |
174 /// This member attaches the observer into an AlterationNotifier. |
174 /// This member attaches the observer into an AlterationNotifier. |
175 /// |
175 /// |
176 void attach(AlterationNotifier& _notifier) { |
176 void attach(AlterationNotifier& notifier) { |
177 _notifier.attach(*this); |
177 notifier.attach(*this); |
178 } |
178 } |
179 |
179 |
180 /// \brief Detaches the observer into an AlterationNotifier. |
180 /// \brief Detaches the observer into an AlterationNotifier. |
181 /// |
181 /// |
182 /// This member detaches the observer from an AlterationNotifier. |
182 /// This member detaches the observer from an AlterationNotifier. |
183 /// |
183 /// |
184 void detach() { |
184 void detach() { |
185 notifier->detach(*this); |
185 _notifier->detach(*this); |
186 } |
186 } |
187 |
187 |
188 /// \brief Gives back a pointer to the notifier which the map |
188 /// \brief Gives back a pointer to the notifier which the map |
189 /// attached into. |
189 /// attached into. |
190 /// |
190 /// |
191 /// This function gives back a pointer to the notifier which the map |
191 /// This function gives back a pointer to the notifier which the map |
192 /// attached into. |
192 /// attached into. |
193 /// |
193 /// |
194 Notifier* getNotifier() const { return const_cast<Notifier*>(notifier); } |
194 Notifier* notifier() const { return const_cast<Notifier*>(_notifier); } |
195 |
195 |
196 /// Gives back true when the observer is attached into a notifier. |
196 /// Gives back true when the observer is attached into a notifier. |
197 bool attached() const { return notifier != 0; } |
197 bool attached() const { return _notifier != 0; } |
198 |
198 |
199 private: |
199 private: |
200 |
200 |
201 ObserverBase& operator=(const ObserverBase& copy); |
201 ObserverBase& operator=(const ObserverBase& copy); |
202 |
202 |
203 protected: |
203 protected: |
204 |
204 |
205 Notifier* notifier; |
205 Notifier* _notifier; |
206 typename std::list<ObserverBase*>::iterator index; |
206 typename std::list<ObserverBase*>::iterator _index; |
207 |
207 |
208 /// \brief The member function to notificate the observer about an |
208 /// \brief The member function to notificate the observer about an |
209 /// item is added to the container. |
209 /// item is added to the container. |
210 /// |
210 /// |
211 /// The add() member function notificates the observer about an item |
211 /// The add() member function notificates the observer about an item |
291 /// |
291 /// |
292 /// Destructor of the AlterationNotifier. |
292 /// Destructor of the AlterationNotifier. |
293 /// |
293 /// |
294 ~AlterationNotifier() { |
294 ~AlterationNotifier() { |
295 typename Observers::iterator it; |
295 typename Observers::iterator it; |
296 for (it = observers.begin(); it != observers.end(); ++it) { |
296 for (it = _observers.begin(); it != _observers.end(); ++it) { |
297 (*it)->notifier = 0; |
297 (*it)->_notifier = 0; |
298 } |
298 } |
299 } |
299 } |
300 |
300 |
301 /// \brief Sets the container. |
301 /// \brief Sets the container. |
302 /// |
302 /// |
344 } |
344 } |
345 |
345 |
346 protected: |
346 protected: |
347 |
347 |
348 void attach(ObserverBase& observer) { |
348 void attach(ObserverBase& observer) { |
349 observer.index = observers.insert(observers.begin(), &observer); |
349 observer._index = _observers.insert(_observers.begin(), &observer); |
350 observer.notifier = this; |
350 observer._notifier = this; |
351 } |
351 } |
352 |
352 |
353 void detach(ObserverBase& observer) { |
353 void detach(ObserverBase& observer) { |
354 observers.erase(observer.index); |
354 _observers.erase(observer._index); |
355 observer.index = observers.end(); |
355 observer._index = _observers.end(); |
356 observer.notifier = 0; |
356 observer._notifier = 0; |
357 } |
357 } |
358 |
358 |
359 public: |
359 public: |
360 |
360 |
361 /// \brief Notifies all the registed observers about an item added to |
361 /// \brief Notifies all the registed observers about an item added to |
365 /// the container. |
365 /// the container. |
366 /// |
366 /// |
367 void add(const Item& item) { |
367 void add(const Item& item) { |
368 typename Observers::reverse_iterator it; |
368 typename Observers::reverse_iterator it; |
369 try { |
369 try { |
370 for (it = observers.rbegin(); it != observers.rend(); ++it) { |
370 for (it = _observers.rbegin(); it != _observers.rend(); ++it) { |
371 (*it)->add(item); |
371 (*it)->add(item); |
372 } |
372 } |
373 } catch (...) { |
373 } catch (...) { |
374 typename Observers::iterator jt; |
374 typename Observers::iterator jt; |
375 for (jt = it.base(); jt != observers.end(); ++jt) { |
375 for (jt = it.base(); jt != _observers.end(); ++jt) { |
376 (*jt)->erase(item); |
376 (*jt)->erase(item); |
377 } |
377 } |
378 throw; |
378 throw; |
379 } |
379 } |
380 } |
380 } |
386 /// the container. |
386 /// the container. |
387 /// |
387 /// |
388 void add(const std::vector<Item>& items) { |
388 void add(const std::vector<Item>& items) { |
389 typename Observers::reverse_iterator it; |
389 typename Observers::reverse_iterator it; |
390 try { |
390 try { |
391 for (it = observers.rbegin(); it != observers.rend(); ++it) { |
391 for (it = _observers.rbegin(); it != _observers.rend(); ++it) { |
392 (*it)->add(items); |
392 (*it)->add(items); |
393 } |
393 } |
394 } catch (...) { |
394 } catch (...) { |
395 typename Observers::iterator jt; |
395 typename Observers::iterator jt; |
396 for (jt = it.base(); jt != observers.end(); ++jt) { |
396 for (jt = it.base(); jt != _observers.end(); ++jt) { |
397 (*jt)->erase(items); |
397 (*jt)->erase(items); |
398 } |
398 } |
399 throw; |
399 throw; |
400 } |
400 } |
401 } |
401 } |
405 /// |
405 /// |
406 /// It notifies all the registed observers about an item erased from |
406 /// It notifies all the registed observers about an item erased from |
407 /// the container. |
407 /// the container. |
408 /// |
408 /// |
409 void erase(const Item& item) throw() { |
409 void erase(const Item& item) throw() { |
410 typename Observers::iterator it = observers.begin(); |
410 typename Observers::iterator it = _observers.begin(); |
411 while (it != observers.end()) { |
411 while (it != _observers.end()) { |
412 try { |
412 try { |
413 (*it)->erase(item); |
413 (*it)->erase(item); |
414 ++it; |
414 ++it; |
415 } catch (const ImmediateDetach&) { |
415 } catch (const ImmediateDetach&) { |
416 it = observers.erase(it); |
416 it = _observers.erase(it); |
417 (*it)->index = observers.end(); |
417 (*it)->_index = _observers.end(); |
418 (*it)->notifier = 0; |
418 (*it)->_notifier = 0; |
419 } |
419 } |
420 } |
420 } |
421 } |
421 } |
422 |
422 |
423 /// \brief Notifies all the registed observers about more item erased |
423 /// \brief Notifies all the registed observers about more item erased |
425 /// |
425 /// |
426 /// It notifies all the registed observers about more item erased from |
426 /// It notifies all the registed observers about more item erased from |
427 /// the container. |
427 /// the container. |
428 /// |
428 /// |
429 void erase(const std::vector<Item>& items) { |
429 void erase(const std::vector<Item>& items) { |
430 typename Observers::iterator it = observers.begin(); |
430 typename Observers::iterator it = _observers.begin(); |
431 while (it != observers.end()) { |
431 while (it != _observers.end()) { |
432 try { |
432 try { |
433 (*it)->erase(items); |
433 (*it)->erase(items); |
434 ++it; |
434 ++it; |
435 } catch (const ImmediateDetach&) { |
435 } catch (const ImmediateDetach&) { |
436 it = observers.erase(it); |
436 it = _observers.erase(it); |
437 (*it)->index = observers.end(); |
437 (*it)->_index = _observers.end(); |
438 (*it)->notifier = 0; |
438 (*it)->_notifier = 0; |
439 } |
439 } |
440 } |
440 } |
441 } |
441 } |
442 |
442 |
443 /// \brief Notifies all the registed observers about the container is |
443 /// \brief Notifies all the registed observers about the container is |
446 /// Notifies all the registed observers about the container is built |
446 /// Notifies all the registed observers about the container is built |
447 /// from an empty container. |
447 /// from an empty container. |
448 void build() { |
448 void build() { |
449 typename Observers::reverse_iterator it; |
449 typename Observers::reverse_iterator it; |
450 try { |
450 try { |
451 for (it = observers.rbegin(); it != observers.rend(); ++it) { |
451 for (it = _observers.rbegin(); it != _observers.rend(); ++it) { |
452 (*it)->build(); |
452 (*it)->build(); |
453 } |
453 } |
454 } catch (...) { |
454 } catch (...) { |
455 typename Observers::iterator jt; |
455 typename Observers::iterator jt; |
456 for (jt = it.base(); jt != observers.end(); ++jt) { |
456 for (jt = it.base(); jt != _observers.end(); ++jt) { |
457 (*jt)->clear(); |
457 (*jt)->clear(); |
458 } |
458 } |
459 throw; |
459 throw; |
460 } |
460 } |
461 } |
461 } |
464 /// erased. |
464 /// erased. |
465 /// |
465 /// |
466 /// Notifies all the registed observers about all items are erased |
466 /// Notifies all the registed observers about all items are erased |
467 /// from the container. |
467 /// from the container. |
468 void clear() { |
468 void clear() { |
469 typename Observers::iterator it = observers.begin(); |
469 typename Observers::iterator it = _observers.begin(); |
470 while (it != observers.end()) { |
470 while (it != _observers.end()) { |
471 try { |
471 try { |
472 (*it)->clear(); |
472 (*it)->clear(); |
473 ++it; |
473 ++it; |
474 } catch (const ImmediateDetach&) { |
474 } catch (const ImmediateDetach&) { |
475 it = observers.erase(it); |
475 it = _observers.erase(it); |
476 (*it)->index = observers.end(); |
476 (*it)->_index = _observers.end(); |
477 (*it)->notifier = 0; |
477 (*it)->_notifier = 0; |
478 } |
478 } |
479 } |
479 } |
480 } |
480 } |
481 }; |
481 }; |
482 |
482 |