From 6f0479fa6d498b8ba48c8b7cbcd507534fda610e Mon Sep 17 00:00:00 2001 From: "willchan@chromium.org" Date: Wed, 24 Feb 2010 22:53:51 +0000 Subject: Revert 39942 - Switch NetworkChangeNotifier implementations to use ObserverList. Fix up observer list so we can use FOR_EACH_OBSERVER when check_empty is set. Clean up the ObserverList API a bit, replacing GetElementAt() with HasObserver() and Clear(). BUG=36590 Review URL: http://codereview.chromium.org/652205 TBR=willchan@chromium.org Review URL: http://codereview.chromium.org/661029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39945 0039d316-1c4b-4281-b951-d872f2087c98 --- base/observer_list.h | 137 +++++++++++++++++++-------------------------------- 1 file changed, 52 insertions(+), 85 deletions(-) (limited to 'base/observer_list.h') diff --git a/base/observer_list.h b/base/observer_list.h index 0b4c583..f67df14 100644 --- a/base/observer_list.h +++ b/base/observer_list.h @@ -56,11 +56,8 @@ // /////////////////////////////////////////////////////////////////////////////// -template -class ObserverListThreadSafe; - -template -class ObserverListBase { +template +class ObserverList { public: // Enumeration of which observers are notified. enum NotificationType { @@ -73,11 +70,49 @@ class ObserverListBase { NOTIFY_EXISTING_ONLY }; + ObserverList() : notify_depth_(0), type_(NOTIFY_ALL) {} + ObserverList(NotificationType type) : notify_depth_(0), type_(type) {} + ~ObserverList() { + // When check_empty is true, assert that the list is empty on destruction. + if (check_empty) { + Compact(); + DCHECK_EQ(observers_.size(), 0U); + } + } + + // Add an observer to the list. + void AddObserver(ObserverType* obs) { + DCHECK(find(observers_.begin(), observers_.end(), obs) == observers_.end()) + << "Observers can only be added once!"; + observers_.push_back(obs); + } + + // Remove an observer from the list. + void RemoveObserver(ObserverType* obs) { + typename ListType::iterator it = + std::find(observers_.begin(), observers_.end(), obs); + if (it != observers_.end()) { + if (notify_depth_) { + *it = 0; + } else { + observers_.erase(it); + } + } + } + + size_t size() const { + return observers_.size(); + } + + ObserverType* GetElementAt(int index) const { + return observers_[index]; + } + // An iterator class that can be used to access the list of observers. See - // also the FOR_EACH_OBSERVER macro defined below. + // also the FOREACH_OBSERVER macro defined below. class Iterator { public: - Iterator(ObserverListBase& list) + Iterator(const ObserverList& list) : list_(list), index_(0), max_index_(list.type_ == NOTIFY_ALL ? @@ -101,60 +136,15 @@ class ObserverListBase { } private: - ObserverListBase& list_; + const ObserverList& list_; size_t index_; size_t max_index_; }; - ObserverListBase() : notify_depth_(0), type_(NOTIFY_ALL) {} - explicit ObserverListBase(NotificationType type) - : notify_depth_(0), type_(type) {} - - // Add an observer to the list. - void AddObserver(ObserverType* obs) { - DCHECK(find(observers_.begin(), observers_.end(), obs) == observers_.end()) - << "Observers can only be added once!"; - observers_.push_back(obs); - } - - // Remove an observer from the list. - void RemoveObserver(ObserverType* obs) { - typename ListType::iterator it = - std::find(observers_.begin(), observers_.end(), obs); - if (it != observers_.end()) { - if (notify_depth_) { - *it = 0; - } else { - observers_.erase(it); - } - } - } - - bool HasObserver(ObserverType* observer) const { - for (size_t i = 0; i < observers_.size(); ++i) { - if (observers_[i] == observer) - return true; - } - return false; - } - - void Clear() { - if (notify_depth_) { - for (typename ListType::iterator it = observers_.begin(); - it != observers_.end(); ++it) { - *it = 0; - } - } else { - observers_.clear(); - } - } - - protected: - size_t size() const { - return observers_.size(); - } + private: + typedef std::vector ListType; - void Compact() { + void Compact() const { typename ListType::iterator it = observers_.begin(); while (it != observers_.end()) { if (*it) { @@ -165,42 +155,19 @@ class ObserverListBase { } } - private: - friend class ObserverListThreadSafe; - - typedef std::vector ListType; - - ListType observers_; - int notify_depth_; + // These are marked mutable to facilitate having NotifyAll be const. + mutable ListType observers_; + mutable int notify_depth_; NotificationType type_; - friend class ObserverListBase::Iterator; - - DISALLOW_COPY_AND_ASSIGN(ObserverListBase); -}; - -template -class ObserverList : public ObserverListBase { - public: - typedef typename ObserverListBase::NotificationType - NotificationType; - - ObserverList() {} - explicit ObserverList(NotificationType type) - : ObserverListBase(type) {} + friend class ObserverList::Iterator; - ~ObserverList() { - // When check_empty is true, assert that the list is empty on destruction. - if (check_empty) { - ObserverListBase::Compact(); - DCHECK_EQ(ObserverListBase::size(), 0U); - } - } + DISALLOW_EVIL_CONSTRUCTORS(ObserverList); }; #define FOR_EACH_OBSERVER(ObserverType, observer_list, func) \ do { \ - ObserverListBase::Iterator it(observer_list); \ + ObserverList::Iterator it(observer_list); \ ObserverType* obs; \ while ((obs = it.GetNext()) != NULL) \ obs->func; \ -- cgit v1.1