1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef BASE_OBSERVER_LIST_H__
6 #define BASE_OBSERVER_LIST_H__
11 #include "base/basictypes.h"
12 #include "base/logging.h"
14 ///////////////////////////////////////////////////////////////////////////////
18 // A container for a list of observers. Unlike a normal STL vector or list,
19 // this container can be modified during iteration without invalidating the
20 // iterator. So, it safely handles the case of an observer removing itself
21 // or other observers from the list while observers are being notified.
31 // virtual void OnFoo(MyWidget* w) = 0;
32 // virtual void OnBar(MyWidget* w, int x, int y) = 0;
35 // void AddObserver(Observer* obs) {
36 // observer_list_.AddObserver(obs);
39 // void RemoveObserver(Observer* obs) {
40 // observer_list_.RemoveObserver(obs);
44 // FOR_EACH_OBSERVER(Observer, observer_list_, OnFoo(this));
47 // void NotifyBar(int x, int y) {
48 // FOR_EACH_OBSERVER(Observer, observer_list_, OnBar(this, x, y));
52 // ObserverList<Observer> observer_list_;
55 ///////////////////////////////////////////////////////////////////////////////
57 template <class ObserverType
, bool check_empty
= false>
60 ObserverList() : notify_depth_(0) {}
62 // When check_empty is true, assert that the list is empty on destruction.
65 DCHECK_EQ(observers_
.size(), 0U);
69 // Add an observer to the list.
70 void AddObserver(ObserverType
* obs
) {
71 DCHECK(find(observers_
.begin(), observers_
.end(), obs
) == observers_
.end())
72 << "Observers can only be added once!";
73 observers_
.push_back(obs
);
76 // Remove an observer from the list.
77 void RemoveObserver(ObserverType
* obs
) {
78 typename
ListType::iterator it
=
79 std::find(observers_
.begin(), observers_
.end(), obs
);
80 if (it
!= observers_
.end()) {
90 return observers_
.size();
93 ObserverType
* GetElementAt(int index
) const {
94 return observers_
[index
];
97 // An iterator class that can be used to access the list of observers. See
98 // also the FOREACH_OBSERVER macro defined below.
101 Iterator(const ObserverList
<ObserverType
>& list
) : list_(list
), index_(0) {
102 ++list_
.notify_depth_
;
106 if (--list_
.notify_depth_
== 0)
110 ObserverType
* GetNext() {
111 ListType
& observers
= list_
.observers_
;
112 // Advance if the current element is null
113 while (index_
< observers
.size() && !observers
[index_
])
115 return index_
< observers
.size() ? observers
[index_
++] : NULL
;
119 const ObserverList
<ObserverType
>& list_
;
124 typedef std::vector
<ObserverType
*> ListType
;
126 void Compact() const {
127 typename
ListType::iterator it
= observers_
.begin();
128 while (it
!= observers_
.end()) {
132 it
= observers_
.erase(it
);
137 // These are marked mutable to facilitate having NotifyAll be const.
138 mutable ListType observers_
;
139 mutable int notify_depth_
;
141 friend class ObserverList::Iterator
;
143 DISALLOW_EVIL_CONSTRUCTORS(ObserverList
);
146 #define FOR_EACH_OBSERVER(ObserverType, observer_list, func) \
148 ObserverList<ObserverType>::Iterator it(observer_list); \
150 while ((obs = it.GetNext()) != NULL) \
154 #endif // BASE_OBSERVER_LIST_H__