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