OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_OBSERVER_LIST_H__ | 5 #ifndef BASE_OBSERVER_LIST_H__ |
6 #define BASE_OBSERVER_LIST_H__ | 6 #define BASE_OBSERVER_LIST_H__ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <limits> | 10 #include <limits> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/weak_ptr.h" | |
16 | 15 |
17 /////////////////////////////////////////////////////////////////////////////// | 16 /////////////////////////////////////////////////////////////////////////////// |
18 // | 17 // |
19 // OVERVIEW: | 18 // OVERVIEW: |
20 // | 19 // |
21 // A container for a list of observers. Unlike a normal STL vector or list, | 20 // A container for a list of observers. Unlike a normal STL vector or list, |
22 // this container can be modified during iteration without invalidating the | 21 // this container can be modified during iteration without invalidating the |
23 // iterator. So, it safely handles the case of an observer removing itself | 22 // iterator. So, it safely handles the case of an observer removing itself |
24 // or other observers from the list while observers are being notified. | 23 // or other observers from the list while observers are being notified. |
25 // | 24 // |
(...skipping 29 matching lines...) Expand all Loading... |
55 // ObserverList<Observer> observer_list_; | 54 // ObserverList<Observer> observer_list_; |
56 // }; | 55 // }; |
57 // | 56 // |
58 // | 57 // |
59 /////////////////////////////////////////////////////////////////////////////// | 58 /////////////////////////////////////////////////////////////////////////////// |
60 | 59 |
61 template <typename ObserverType> | 60 template <typename ObserverType> |
62 class ObserverListThreadSafe; | 61 class ObserverListThreadSafe; |
63 | 62 |
64 template <class ObserverType> | 63 template <class ObserverType> |
65 class ObserverListBase | 64 class ObserverListBase { |
66 : public base::SupportsWeakPtr<ObserverListBase<ObserverType> > { | |
67 public: | 65 public: |
68 // Enumeration of which observers are notified. | 66 // Enumeration of which observers are notified. |
69 enum NotificationType { | 67 enum NotificationType { |
70 // Specifies that any observers added during notification are notified. | 68 // Specifies that any observers added during notification are notified. |
71 // This is the default type if non type is provided to the constructor. | 69 // This is the default type if non type is provided to the constructor. |
72 NOTIFY_ALL, | 70 NOTIFY_ALL, |
73 | 71 |
74 // Specifies that observers added while sending out notification are not | 72 // Specifies that observers added while sending out notification are not |
75 // notified. | 73 // notified. |
76 NOTIFY_EXISTING_ONLY | 74 NOTIFY_EXISTING_ONLY |
77 }; | 75 }; |
78 | 76 |
79 // An iterator class that can be used to access the list of observers. See | 77 // An iterator class that can be used to access the list of observers. See |
80 // also the FOR_EACH_OBSERVER macro defined below. | 78 // also the FOR_EACH_OBSERVER macro defined below. |
81 class Iterator { | 79 class Iterator { |
82 public: | 80 public: |
83 Iterator(ObserverListBase<ObserverType>& list) | 81 Iterator(ObserverListBase<ObserverType>& list) |
84 : list_(list.AsWeakPtr()), | 82 : list_(list), |
85 index_(0), | 83 index_(0), |
86 max_index_(list.type_ == NOTIFY_ALL ? | 84 max_index_(list.type_ == NOTIFY_ALL ? |
87 std::numeric_limits<size_t>::max() : | 85 std::numeric_limits<size_t>::max() : |
88 list.observers_.size()) { | 86 list.observers_.size()) { |
89 ++list_->notify_depth_; | 87 ++list_.notify_depth_; |
90 } | 88 } |
91 | 89 |
92 ~Iterator() { | 90 ~Iterator() { |
93 if (list_ && --list_->notify_depth_ == 0) | 91 if (--list_.notify_depth_ == 0) |
94 list_->Compact(); | 92 list_.Compact(); |
95 } | 93 } |
96 | 94 |
97 ObserverType* GetNext() { | 95 ObserverType* GetNext() { |
98 if (!list_) | 96 ListType& observers = list_.observers_; |
99 return NULL; | |
100 ListType& observers = list_->observers_; | |
101 // Advance if the current element is null | 97 // Advance if the current element is null |
102 size_t max_index = std::min(max_index_, observers.size()); | 98 size_t max_index = std::min(max_index_, observers.size()); |
103 while (index_ < max_index && !observers[index_]) | 99 while (index_ < max_index && !observers[index_]) |
104 ++index_; | 100 ++index_; |
105 return index_ < max_index ? observers[index_++] : NULL; | 101 return index_ < max_index ? observers[index_++] : NULL; |
106 } | 102 } |
107 | 103 |
108 private: | 104 private: |
109 base::WeakPtr<ObserverListBase<ObserverType> > list_; | 105 ObserverListBase<ObserverType>& list_; |
110 size_t index_; | 106 size_t index_; |
111 size_t max_index_; | 107 size_t max_index_; |
112 }; | 108 }; |
113 | 109 |
114 ObserverListBase() : notify_depth_(0), type_(NOTIFY_ALL) {} | 110 ObserverListBase() : notify_depth_(0), type_(NOTIFY_ALL) {} |
115 explicit ObserverListBase(NotificationType type) | 111 explicit ObserverListBase(NotificationType type) |
116 : notify_depth_(0), type_(type) {} | 112 : notify_depth_(0), type_(type) {} |
117 | 113 |
118 // Add an observer to the list. An observer should not be added to | 114 // Add an observer to the list. An observer should not be added to |
119 // the same list more than once. | 115 // the same list more than once. |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 | 203 |
208 #define FOR_EACH_OBSERVER(ObserverType, observer_list, func) \ | 204 #define FOR_EACH_OBSERVER(ObserverType, observer_list, func) \ |
209 do { \ | 205 do { \ |
210 ObserverListBase<ObserverType>::Iterator it(observer_list); \ | 206 ObserverListBase<ObserverType>::Iterator it(observer_list); \ |
211 ObserverType* obs; \ | 207 ObserverType* obs; \ |
212 while ((obs = it.GetNext()) != NULL) \ | 208 while ((obs = it.GetNext()) != NULL) \ |
213 obs->func; \ | 209 obs->func; \ |
214 } while (0) | 210 } while (0) |
215 | 211 |
216 #endif // BASE_OBSERVER_LIST_H__ | 212 #endif // BASE_OBSERVER_LIST_H__ |
OLD | NEW |