15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_OBSERVER_LIST_H__ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_OBSERVER_LIST_H__ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OVERVIEW: 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A container for a list of observers. Unlike a normal STL vector or list, 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this container can be modified during iteration without invalidating the 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iterator. So, it safely handles the case of an observer removing itself 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or other observers from the list while observers are being notified. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TYPICAL USAGE: 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class MyWidget { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// public: 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ... 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class Observer { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// public: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// virtual void OnFoo(MyWidget* w) = 0; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// virtual void OnBar(MyWidget* w, int x, int y) = 0; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void AddObserver(Observer* obs) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// observer_list_.AddObserver(obs); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void RemoveObserver(Observer* obs) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// observer_list_.RemoveObserver(obs); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void NotifyFoo() { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FOR_EACH_OBSERVER(Observer, observer_list_, OnFoo(this)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void NotifyBar(int x, int y) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FOR_EACH_OBSERVER(Observer, observer_list_, OnBar(this, x, y)); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// private: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ObserverList<Observer> observer_list_; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename ObserverType> 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ObserverListThreadSafe; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class ObserverType> 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ObserverListBase 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::SupportsWeakPtr<ObserverListBase<ObserverType> > { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enumeration of which observers are notified. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum NotificationType { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Specifies that any observers added during notification are notified. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the default type if non type is provided to the constructor. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIFY_ALL, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Specifies that observers added while sending out notification are not 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notified. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIFY_EXISTING_ONLY 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An iterator class that can be used to access the list of observers. See 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also the FOR_EACH_OBSERVER macro defined below. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Iterator { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Iterator(ObserverListBase<ObserverType>& list); 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ~Iterator(); 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ObserverType* GetNext(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<ObserverListBase<ObserverType> > list_; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index_; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t max_index_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObserverListBase() : notify_depth_(0), type_(NOTIFY_ALL) {} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ObserverListBase(NotificationType type) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : notify_depth_(0), type_(type) {} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add an observer to the list. An observer should not be added to 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same list more than once. 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void AddObserver(ObserverType* obs); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove an observer from the list if it is in the list. 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void RemoveObserver(ObserverType* obs); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool HasObserver(ObserverType* observer) const; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void Clear(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size() const { return observers_.size(); } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void Compact(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ObserverListThreadSafe<ObserverType>; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<ObserverType*> ListType; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListType observers_; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int notify_depth_; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationType type_; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ObserverListBase::Iterator; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ObserverListBase); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class ObserverType> 127116680a4aac90f2aa7413d9095a592090648e557Ben MurdochObserverListBase<ObserverType>::Iterator::Iterator( 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ObserverListBase<ObserverType>& list) 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : list_(list.AsWeakPtr()), 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch index_(0), 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch max_index_(list.type_ == NOTIFY_ALL ? 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::numeric_limits<size_t>::max() : 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch list.observers_.size()) { 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++list_->notify_depth_; 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class ObserverType> 138116680a4aac90f2aa7413d9095a592090648e557Ben MurdochObserverListBase<ObserverType>::Iterator::~Iterator() { 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (list_.get() && --list_->notify_depth_ == 0) 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch list_->Compact(); 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class ObserverType> 144116680a4aac90f2aa7413d9095a592090648e557Ben MurdochObserverType* ObserverListBase<ObserverType>::Iterator::GetNext() { 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!list_.get()) 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ListType& observers = list_->observers_; 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Advance if the current element is null 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t max_index = std::min(max_index_, observers.size()); 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (index_ < max_index && !observers[index_]) 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++index_; 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return index_ < max_index ? observers[index_++] : NULL; 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class ObserverType> 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ObserverListBase<ObserverType>::AddObserver(ObserverType* obs) { 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (std::find(observers_.begin(), observers_.end(), obs) 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch != observers_.end()) { 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTREACHED() << "Observers can only be added once!"; 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch observers_.push_back(obs); 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class ObserverType> 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ObserverListBase<ObserverType>::RemoveObserver(ObserverType* obs) { 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typename ListType::iterator it = 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::find(observers_.begin(), observers_.end(), obs); 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (it != observers_.end()) { 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (notify_depth_) { 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *it = 0; 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch observers_.erase(it); 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class ObserverType> 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ObserverListBase<ObserverType>::HasObserver(ObserverType* observer) const { 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < observers_.size(); ++i) { 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (observers_[i] == observer) 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class ObserverType> 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ObserverListBase<ObserverType>::Clear() { 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (notify_depth_) { 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (typename ListType::iterator it = observers_.begin(); 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it != observers_.end(); ++it) { 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *it = 0; 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch observers_.clear(); 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <class ObserverType> 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ObserverListBase<ObserverType>::Compact() { 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch observers_.erase( 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::remove(observers_.begin(), observers_.end(), 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<ObserverType*>(NULL)), observers_.end()); 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class ObserverType, bool check_empty = false> 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ObserverList : public ObserverListBase<ObserverType> { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef typename ObserverListBase<ObserverType>::NotificationType 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationType; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObserverList() {} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ObserverList(NotificationType type) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ObserverListBase<ObserverType>(type) {} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ObserverList() { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When check_empty is true, assert that the list is empty on destruction. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (check_empty) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObserverListBase<ObserverType>::Compact(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(ObserverListBase<ObserverType>::size(), 0U); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool might_have_observers() const { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ObserverListBase<ObserverType>::size() != 0; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define FOR_EACH_OBSERVER(ObserverType, observer_list, func) \ 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) do { \ 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((observer_list).might_have_observers()) { \ 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ObserverListBase<ObserverType>::Iterator \ 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it_inside_observer_macro(observer_list); \ 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ObserverType* obs; \ 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) while ((obs = it_inside_observer_macro.GetNext()) != NULL) \ 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) obs->func; \ 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } \ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (0) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_OBSERVER_LIST_H__ 241