OLD | NEW |
1 $$ This is a pump file for generating file templates. Pump is a python | 1 $$ This is a pump file for generating file templates. Pump is a python |
2 $$ script that is part of the Google Test suite of utilities. Description | 2 $$ script that is part of the Google Test suite of utilities. Description |
3 $$ can be found here: | 3 $$ can be found here: |
4 $$ | 4 $$ |
5 $$ http://code.google.com/p/googletest/wiki/PumpManual | 5 $$ http://code.google.com/p/googletest/wiki/PumpManual |
6 $$ | 6 $$ |
7 | 7 |
8 $$ See comment for MAX_ARITY in base/bind.h.pump. | 8 $$ See comment for MAX_ARITY in base/bind.h.pump. |
9 $var MAX_ARITY = 7 | 9 $var MAX_ARITY = 7 |
10 | 10 |
11 // Copyright 2013 The Chromium Authors. All rights reserved. | 11 // Copyright 2013 The Chromium Authors. All rights reserved. |
12 // Use of this source code is governed by a BSD-style license that can be | 12 // Use of this source code is governed by a BSD-style license that can be |
13 // found in the LICENSE file. | 13 // found in the LICENSE file. |
14 | 14 |
15 #ifndef BASE_CALLBACK_REGISTRY_H_ | 15 #ifndef BASE_CALLBACK_LIST_H_ |
16 #define BASE_CALLBACK_REGISTRY_H_ | 16 #define BASE_CALLBACK_LIST_H_ |
17 | 17 |
18 #include <list> | 18 #include <list> |
19 | 19 |
20 #include "base/basictypes.h" | 20 #include "base/basictypes.h" |
21 #include "base/callback.h" | 21 #include "base/callback.h" |
22 #include "base/callback_internal.h" | 22 #include "base/callback_internal.h" |
23 #include "base/compiler_specific.h" | 23 #include "base/compiler_specific.h" |
24 #include "base/logging.h" | 24 #include "base/logging.h" |
25 #include "base/memory/scoped_ptr.h" | 25 #include "base/memory/scoped_ptr.h" |
26 | 26 |
27 // OVERVIEW: | 27 // OVERVIEW: |
28 // | 28 // |
29 // A container for a list of callbacks. Unlike a normal STL vector or list, | 29 // A container for a list of callbacks. Unlike a normal STL vector or list, |
30 // this container can be modified during iteration without invalidating the | 30 // this container can be modified during iteration without invalidating the |
31 // iterator. It safely handles the case of a callback removing itself | 31 // iterator. It safely handles the case of a callback removing itself |
32 // or another callback from the list while callbacks are being run. | 32 // or another callback from the list while callbacks are being run. |
33 // | 33 // |
34 // TYPICAL USAGE: | 34 // TYPICAL USAGE: |
35 // | 35 // |
36 // class MyWidget { | 36 // class MyWidget { |
37 // public: | 37 // public: |
38 // ... | 38 // ... |
39 // | 39 // |
40 // typedef base::Callback<void(const Foo&)> OnFooCallback; | 40 // typedef base::Callback<void(const Foo&)> OnFooCallback; |
41 // | 41 // |
42 // scoped_ptr<base::CallbackRegistry<void(const Foo&)>::Subscription> | 42 // scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription> |
43 // RegisterCallback(const OnFooCallback& cb) { | 43 // RegisterCallback(const OnFooCallback& cb) { |
44 // return callback_registry_.Add(cb); | 44 // return callback_list_.Add(cb); |
45 // } | 45 // } |
46 // | 46 // |
47 // private: | 47 // private: |
48 // void NotifyFoo(const Foo& foo) { | 48 // void NotifyFoo(const Foo& foo) { |
49 // callback_registry_.Notify(foo); | 49 // callback_list_.Notify(foo); |
50 // } | 50 // } |
51 // | 51 // |
52 // base::CallbackRegistry<void(const Foo&)> callback_registry_; | 52 // base::CallbackList<void(const Foo&)> callback_list_; |
53 // }; | 53 // }; |
54 // | 54 // |
55 // | 55 // |
56 // class MyWidgetListener { | 56 // class MyWidgetListener { |
57 // public: | 57 // public: |
58 // MyWidgetListener::MyWidgetListener() { | 58 // MyWidgetListener::MyWidgetListener() { |
59 // foo_subscription_ = MyWidget::GetCurrent()->RegisterCallback( | 59 // foo_subscription_ = MyWidget::GetCurrent()->RegisterCallback( |
60 // base::Bind(&MyWidgetListener::OnFoo, this))); | 60 // base::Bind(&MyWidgetListener::OnFoo, this))); |
61 // } | 61 // } |
62 // | 62 // |
63 // MyWidgetListener::~MyWidgetListener() { | 63 // MyWidgetListener::~MyWidgetListener() { |
64 // // Subscription gets deleted automatically and will deregister | 64 // // Subscription gets deleted automatically and will deregister |
65 // // the callback in the process. | 65 // // the callback in the process. |
66 // } | 66 // } |
67 // | 67 // |
68 // private: | 68 // private: |
69 // void OnFoo(const Foo& foo) { | 69 // void OnFoo(const Foo& foo) { |
70 // // Do something. | 70 // // Do something. |
71 // } | 71 // } |
72 // | 72 // |
73 // scoped_ptr<base::CallbackRegistry<Foo>::Subscription> foo_subscription_; | 73 // scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription> |
| 74 // foo_subscription_; |
74 // }; | 75 // }; |
75 | 76 |
76 namespace base { | 77 namespace base { |
77 | 78 |
78 namespace internal { | 79 namespace internal { |
79 | 80 |
80 template <typename CallbackType> | 81 template <typename CallbackType> |
81 class CallbackRegistryBase { | 82 class CallbackListBase { |
82 public: | 83 public: |
83 class Subscription { | 84 class Subscription { |
84 public: | 85 public: |
85 Subscription(CallbackRegistryBase<CallbackType>* list, | 86 Subscription(CallbackListBase<CallbackType>* list, |
86 typename std::list<CallbackType>::iterator iter) | 87 typename std::list<CallbackType>::iterator iter) |
87 : list_(list), | 88 : list_(list), |
88 iter_(iter) {} | 89 iter_(iter) {} |
89 | 90 |
90 ~Subscription() { | 91 ~Subscription() { |
91 if (list_->active_iterator_count_) | 92 if (list_->active_iterator_count_) |
92 (*iter_).Reset(); | 93 (*iter_).Reset(); |
93 else | 94 else |
94 list_->callbacks_.erase(iter_); | 95 list_->callbacks_.erase(iter_); |
95 } | 96 } |
96 | 97 |
97 private: | 98 private: |
98 CallbackRegistryBase<CallbackType>* list_; | 99 CallbackListBase<CallbackType>* list_; |
99 typename std::list<CallbackType>::iterator iter_; | 100 typename std::list<CallbackType>::iterator iter_; |
100 | 101 |
101 DISALLOW_COPY_AND_ASSIGN(Subscription); | 102 DISALLOW_COPY_AND_ASSIGN(Subscription); |
102 }; | 103 }; |
103 | 104 |
104 // Add a callback to the list. The callback will remain registered until the | 105 // Add a callback to the list. The callback will remain registered until the |
105 // returned Subscription is destroyed, which must occur before the | 106 // returned Subscription is destroyed, which must occur before the |
106 // CallbackRegistry is destroyed. | 107 // CallbackList is destroyed. |
107 scoped_ptr<Subscription> Add(const CallbackType& cb) { | 108 scoped_ptr<Subscription> Add(const CallbackType& cb) { |
108 DCHECK(!cb.is_null()); | 109 DCHECK(!cb.is_null()); |
109 return scoped_ptr<Subscription>( | 110 return scoped_ptr<Subscription>( |
110 new Subscription(this, callbacks_.insert(callbacks_.end(), cb))); | 111 new Subscription(this, callbacks_.insert(callbacks_.end(), cb))); |
111 } | 112 } |
112 | 113 |
113 protected: | 114 protected: |
114 // An iterator class that can be used to access the list of callbacks. | 115 // An iterator class that can be used to access the list of callbacks. |
115 class Iterator { | 116 class Iterator { |
116 public: | 117 public: |
117 explicit Iterator(CallbackRegistryBase<CallbackType>* list) | 118 explicit Iterator(CallbackListBase<CallbackType>* list) |
118 : list_(list), | 119 : list_(list), |
119 list_iter_(list_->callbacks_.begin()) { | 120 list_iter_(list_->callbacks_.begin()) { |
120 ++list_->active_iterator_count_; | 121 ++list_->active_iterator_count_; |
121 } | 122 } |
122 | 123 |
123 Iterator(const Iterator& iter) | 124 Iterator(const Iterator& iter) |
124 : list_(iter.list_), | 125 : list_(iter.list_), |
125 list_iter_(iter.list_iter_) { | 126 list_iter_(iter.list_iter_) { |
126 ++list_->active_iterator_count_; | 127 ++list_->active_iterator_count_; |
127 } | 128 } |
(...skipping 10 matching lines...) Expand all Loading... |
138 | 139 |
139 CallbackType* cb = NULL; | 140 CallbackType* cb = NULL; |
140 if (list_iter_ != list_->callbacks_.end()) { | 141 if (list_iter_ != list_->callbacks_.end()) { |
141 cb = &(*list_iter_); | 142 cb = &(*list_iter_); |
142 ++list_iter_; | 143 ++list_iter_; |
143 } | 144 } |
144 return cb; | 145 return cb; |
145 } | 146 } |
146 | 147 |
147 private: | 148 private: |
148 CallbackRegistryBase<CallbackType>* list_; | 149 CallbackListBase<CallbackType>* list_; |
149 typename std::list<CallbackType>::iterator list_iter_; | 150 typename std::list<CallbackType>::iterator list_iter_; |
150 }; | 151 }; |
151 | 152 |
152 CallbackRegistryBase() | 153 CallbackListBase() |
153 : active_iterator_count_(0) {} | 154 : active_iterator_count_(0) {} |
154 | 155 |
155 ~CallbackRegistryBase() { | 156 ~CallbackListBase() { |
156 DCHECK_EQ(0, active_iterator_count_); | 157 DCHECK_EQ(0, active_iterator_count_); |
157 DCHECK_EQ(0U, callbacks_.size()); | 158 DCHECK_EQ(0U, callbacks_.size()); |
158 } | 159 } |
159 | 160 |
160 // Returns an instance of a CallbackRegistryBase::Iterator which can be used | 161 // Returns an instance of a CallbackListBase::Iterator which can be used |
161 // to run callbacks. | 162 // to run callbacks. |
162 Iterator GetIterator() { | 163 Iterator GetIterator() { |
163 return Iterator(this); | 164 return Iterator(this); |
164 } | 165 } |
165 | 166 |
166 // Compact the list: remove any entries which were NULLed out during | 167 // Compact the list: remove any entries which were NULLed out during |
167 // iteration. | 168 // iteration. |
168 void Compact() { | 169 void Compact() { |
169 typename std::list<CallbackType>::iterator it = callbacks_.begin(); | 170 typename std::list<CallbackType>::iterator it = callbacks_.begin(); |
170 while (it != callbacks_.end()) { | 171 while (it != callbacks_.end()) { |
171 if ((*it).is_null()) | 172 if ((*it).is_null()) |
172 it = callbacks_.erase(it); | 173 it = callbacks_.erase(it); |
173 else | 174 else |
174 ++it; | 175 ++it; |
175 } | 176 } |
176 } | 177 } |
177 | 178 |
178 private: | 179 private: |
179 std::list<CallbackType> callbacks_; | 180 std::list<CallbackType> callbacks_; |
180 int active_iterator_count_; | 181 int active_iterator_count_; |
181 | 182 |
182 DISALLOW_COPY_AND_ASSIGN(CallbackRegistryBase); | 183 DISALLOW_COPY_AND_ASSIGN(CallbackListBase); |
183 }; | 184 }; |
184 | 185 |
185 } // namespace internal | 186 } // namespace internal |
186 | 187 |
187 template <typename Sig> class CallbackRegistry; | 188 template <typename Sig> class CallbackList; |
188 | 189 |
189 | 190 |
190 $range ARITY 0..MAX_ARITY | 191 $range ARITY 0..MAX_ARITY |
191 $for ARITY [[ | 192 $for ARITY [[ |
192 $range ARG 1..ARITY | 193 $range ARG 1..ARITY |
193 | 194 |
194 $if ARITY == 0 [[ | 195 $if ARITY == 0 [[ |
195 template <> | 196 template <> |
196 class CallbackRegistry<void(void)> | 197 class CallbackList<void(void)> |
197 : public internal::CallbackRegistryBase<Callback<void(void)> > { | 198 : public internal::CallbackListBase<Callback<void(void)> > { |
198 ]] $else [[ | 199 ]] $else [[ |
199 template <$for ARG , [[typename A$(ARG)]]> | 200 template <$for ARG , [[typename A$(ARG)]]> |
200 class CallbackRegistry<void($for ARG , [[A$(ARG)]])> | 201 class CallbackList<void($for ARG , [[A$(ARG)]])> |
201 : public internal::CallbackRegistryBase< | 202 : public internal::CallbackListBase< |
202 Callback<void($for ARG , [[A$(ARG)]])> > { | 203 Callback<void($for ARG , [[A$(ARG)]])> > { |
203 ]] | 204 ]] |
204 | 205 |
205 public: | 206 public: |
206 $if ARITY == 0 [[ | 207 $if ARITY == 0 [[ |
207 | 208 |
208 typedef Callback<void(void)> CallbackType; | 209 typedef Callback<void(void)> CallbackType; |
209 ]] $else [[ | 210 ]] $else [[ |
210 | 211 |
211 typedef Callback<void($for ARG , [[A$(ARG)]])> CallbackType; | 212 typedef Callback<void($for ARG , [[A$(ARG)]])> CallbackType; |
212 ]] | 213 ]] |
213 | 214 |
214 | 215 |
215 CallbackRegistry() {} | 216 CallbackList() {} |
216 | 217 |
217 void Notify($for ARG , | 218 void Notify($for ARG , |
218 [[typename internal::CallbackParamTraits<A$(ARG)>::ForwardType a$(
ARG)]]) { | 219 [[typename internal::CallbackParamTraits<A$(ARG)>::ForwardType a$(
ARG)]]) { |
219 $if ARITY == 0 [[ | 220 $if ARITY == 0 [[ |
220 | 221 |
221 internal::CallbackRegistryBase<CallbackType>::Iterator it = | 222 internal::CallbackListBase<CallbackType>::Iterator it = |
222 this->GetIterator(); | 223 this->GetIterator(); |
223 ]] $else [[ | 224 ]] $else [[ |
224 | 225 |
225 typename internal::CallbackRegistryBase<CallbackType>::Iterator it = | 226 typename internal::CallbackListBase<CallbackType>::Iterator it = |
226 this->GetIterator(); | 227 this->GetIterator(); |
227 ]] | 228 ]] |
228 | 229 |
229 CallbackType* cb; | 230 CallbackType* cb; |
230 while((cb = it.GetNext()) != NULL) { | 231 while((cb = it.GetNext()) != NULL) { |
231 cb->Run($for ARG , [[a$(ARG)]]); | 232 cb->Run($for ARG , [[a$(ARG)]]); |
232 } | 233 } |
233 } | 234 } |
234 | 235 |
235 private: | 236 private: |
236 DISALLOW_COPY_AND_ASSIGN(CallbackRegistry); | 237 DISALLOW_COPY_AND_ASSIGN(CallbackList); |
237 }; | 238 }; |
238 | 239 |
239 | 240 |
240 ]] $$ for ARITY | 241 ]] $$ for ARITY |
241 } // namespace base | 242 } // namespace base |
242 | 243 |
243 #endif // BASE_CALLBACK_REGISTRY_H | 244 #endif // BASE_CALLBACK_LIST_H_ |
OLD | NEW |