summaryrefslogtreecommitdiffstats
path: root/base/observer_list.h
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-07-29 17:14:53 +0100
committerBen Murdoch <benm@google.com>2010-08-04 14:29:45 +0100
commitc407dc5cd9bdc5668497f21b26b09d988ab439de (patch)
tree7eaf8707c0309516bdb042ad976feedaf72b0bb1 /base/observer_list.h
parent0998b1cdac5733f299c12d88bc31ef9c8035b8fa (diff)
downloadexternal_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.zip
external_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.tar.gz
external_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.tar.bz2
Merge Chromium src@r53293
Change-Id: Ia79acf8670f385cee48c45b0a75371d8e950af34
Diffstat (limited to 'base/observer_list.h')
-rw-r--r--base/observer_list.h137
1 files changed, 84 insertions, 53 deletions
diff --git a/base/observer_list.h b/base/observer_list.h
index f67df14..10c6775 100644
--- a/base/observer_list.h
+++ b/base/observer_list.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -56,8 +56,11 @@
//
///////////////////////////////////////////////////////////////////////////////
-template <class ObserverType, bool check_empty = false>
-class ObserverList {
+template <typename ObserverType>
+class ObserverListThreadSafe;
+
+template <class ObserverType>
+class ObserverListBase {
public:
// Enumeration of which observers are notified.
enum NotificationType {
@@ -70,49 +73,11 @@ class ObserverList {
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 FOREACH_OBSERVER macro defined below.
+ // also the FOR_EACH_OBSERVER macro defined below.
class Iterator {
public:
- Iterator(const ObserverList<ObserverType>& list)
+ Iterator(ObserverListBase<ObserverType>& list)
: list_(list),
index_(0),
max_index_(list.type_ == NOTIFY_ALL ?
@@ -136,15 +101,58 @@ class ObserverList {
}
private:
- const ObserverList<ObserverType>& list_;
+ ObserverListBase<ObserverType>& list_;
size_t index_;
size_t max_index_;
};
- private:
- typedef std::vector<ObserverType*> ListType;
+ 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);
+ }
+ }
+ }
- void Compact() const {
+ 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();
+ }
+ }
+
+ size_t size() const { return observers_.size(); }
+
+ protected:
+ void Compact() {
typename ListType::iterator it = observers_.begin();
while (it != observers_.end()) {
if (*it) {
@@ -155,19 +163,42 @@ class ObserverList {
}
}
- // These are marked mutable to facilitate having NotifyAll be const.
- mutable ListType observers_;
- mutable int notify_depth_;
+ private:
+ friend class ObserverListThreadSafe<ObserverType>;
+
+ typedef std::vector<ObserverType*> ListType;
+
+ ListType observers_;
+ int notify_depth_;
NotificationType type_;
- friend class ObserverList::Iterator;
+ friend class ObserverListBase::Iterator;
+
+ DISALLOW_COPY_AND_ASSIGN(ObserverListBase);
+};
- DISALLOW_EVIL_CONSTRUCTORS(ObserverList);
+template <class ObserverType, bool check_empty = false>
+class ObserverList : public ObserverListBase<ObserverType> {
+ public:
+ typedef typename ObserverListBase<ObserverType>::NotificationType
+ NotificationType;
+
+ ObserverList() {}
+ explicit ObserverList(NotificationType type)
+ : ObserverListBase<ObserverType>(type) {}
+
+ ~ObserverList() {
+ // When check_empty is true, assert that the list is empty on destruction.
+ if (check_empty) {
+ ObserverListBase<ObserverType>::Compact();
+ DCHECK_EQ(ObserverListBase<ObserverType>::size(), 0U);
+ }
+ }
};
#define FOR_EACH_OBSERVER(ObserverType, observer_list, func) \
do { \
- ObserverList<ObserverType>::Iterator it(observer_list); \
+ ObserverListBase<ObserverType>::Iterator it(observer_list); \
ObserverType* obs; \
while ((obs = it.GetNext()) != NULL) \
obs->func; \