1 // This file was GENERATED by command:
2 // pump.py callback_list.h.pump
3 // DO NOT EDIT BY HAND!!!
6 // Copyright 2013 The Chromium Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file.
10 #ifndef BASE_CALLBACK_LIST_H_
11 #define BASE_CALLBACK_LIST_H_
15 #include "base/basictypes.h"
16 #include "base/callback.h"
17 #include "base/callback_internal.h"
18 #include "base/compiler_specific.h"
19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h"
24 // A container for a list of callbacks. Unlike a normal STL vector or list,
25 // this container can be modified during iteration without invalidating the
26 // iterator. It safely handles the case of a callback removing itself
27 // or another callback from the list while callbacks are being run.
35 // typedef base::Callback<void(const Foo&)> OnFooCallback;
37 // scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
38 // RegisterCallback(const OnFooCallback& cb) {
39 // return callback_list_.Add(cb);
43 // void NotifyFoo(const Foo& foo) {
44 // callback_list_.Notify(foo);
47 // base::CallbackList<void(const Foo&)> callback_list_;
49 // DISALLOW_COPY_AND_ASSIGN(MyWidget);
53 // class MyWidgetListener {
55 // MyWidgetListener::MyWidgetListener() {
56 // foo_subscription_ = MyWidget::GetCurrent()->RegisterCallback(
57 // base::Bind(&MyWidgetListener::OnFoo, this)));
60 // MyWidgetListener::~MyWidgetListener() {
61 // // Subscription gets deleted automatically and will deregister
62 // // the callback in the process.
66 // void OnFoo(const Foo& foo) {
70 // scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
73 // DISALLOW_COPY_AND_ASSIGN(MyWidgetListener);
80 template <typename CallbackType
>
81 class CallbackListBase
{
85 Subscription(CallbackListBase
<CallbackType
>* list
,
86 typename
std::list
<CallbackType
>::iterator iter
)
92 if (list_
->active_iterator_count_
) {
95 list_
->callbacks_
.erase(iter_
);
96 if (!list_
->removal_callback_
.is_null())
97 list_
->removal_callback_
.Run();
102 CallbackListBase
<CallbackType
>* list_
;
103 typename
std::list
<CallbackType
>::iterator iter_
;
105 DISALLOW_COPY_AND_ASSIGN(Subscription
);
108 // Add a callback to the list. The callback will remain registered until the
109 // returned Subscription is destroyed, which must occur before the
110 // CallbackList is destroyed.
111 scoped_ptr
<Subscription
> Add(const CallbackType
& cb
) WARN_UNUSED_RESULT
{
112 DCHECK(!cb
.is_null());
113 return scoped_ptr
<Subscription
>(
114 new Subscription(this, callbacks_
.insert(callbacks_
.end(), cb
)));
117 // Sets a callback which will be run when a subscription list is changed.
118 void set_removal_callback(const Closure
& callback
) {
119 removal_callback_
= callback
;
122 // Returns true if there are no subscriptions. This is only valid to call when
123 // not looping through the list.
125 DCHECK_EQ(0, active_iterator_count_
);
126 return callbacks_
.empty();
130 // An iterator class that can be used to access the list of callbacks.
133 explicit Iterator(CallbackListBase
<CallbackType
>* list
)
135 list_iter_(list_
->callbacks_
.begin()) {
136 ++list_
->active_iterator_count_
;
139 Iterator(const Iterator
& iter
)
141 list_iter_(iter
.list_iter_
) {
142 ++list_
->active_iterator_count_
;
146 if (list_
&& --list_
->active_iterator_count_
== 0) {
151 CallbackType
* GetNext() {
152 while ((list_iter_
!= list_
->callbacks_
.end()) && list_iter_
->is_null())
155 CallbackType
* cb
= NULL
;
156 if (list_iter_
!= list_
->callbacks_
.end()) {
164 CallbackListBase
<CallbackType
>* list_
;
165 typename
std::list
<CallbackType
>::iterator list_iter_
;
168 CallbackListBase() : active_iterator_count_(0) {}
170 ~CallbackListBase() {
171 DCHECK_EQ(0, active_iterator_count_
);
172 DCHECK_EQ(0U, callbacks_
.size());
175 // Returns an instance of a CallbackListBase::Iterator which can be used
177 Iterator
GetIterator() {
178 return Iterator(this);
181 // Compact the list: remove any entries which were NULLed out during
184 typename
std::list
<CallbackType
>::iterator it
= callbacks_
.begin();
185 bool updated
= false;
186 while (it
!= callbacks_
.end()) {
187 if ((*it
).is_null()) {
189 it
= callbacks_
.erase(it
);
194 if (updated
&& !removal_callback_
.is_null())
195 removal_callback_
.Run();
200 std::list
<CallbackType
> callbacks_
;
201 int active_iterator_count_
;
202 Closure removal_callback_
;
204 DISALLOW_COPY_AND_ASSIGN(CallbackListBase
);
207 } // namespace internal
209 template <typename Sig
> class CallbackList
;
212 class CallbackList
<void(void)>
213 : public internal::CallbackListBase
<Callback
<void(void)> > {
215 typedef Callback
<void(void)> CallbackType
;
220 internal::CallbackListBase
<CallbackType
>::Iterator it
=
223 while ((cb
= it
.GetNext()) != NULL
) {
229 DISALLOW_COPY_AND_ASSIGN(CallbackList
);
232 template <typename A1
>
233 class CallbackList
<void(A1
)>
234 : public internal::CallbackListBase
<Callback
<void(A1
)> > {
236 typedef Callback
<void(A1
)> CallbackType
;
240 void Notify(typename
internal::CallbackParamTraits
<A1
>::ForwardType a1
) {
241 typename
internal::CallbackListBase
<CallbackType
>::Iterator it
=
244 while ((cb
= it
.GetNext()) != NULL
) {
250 DISALLOW_COPY_AND_ASSIGN(CallbackList
);
253 template <typename A1
, typename A2
>
254 class CallbackList
<void(A1
, A2
)>
255 : public internal::CallbackListBase
<Callback
<void(A1
, A2
)> > {
257 typedef Callback
<void(A1
, A2
)> CallbackType
;
261 void Notify(typename
internal::CallbackParamTraits
<A1
>::ForwardType a1
,
262 typename
internal::CallbackParamTraits
<A2
>::ForwardType a2
) {
263 typename
internal::CallbackListBase
<CallbackType
>::Iterator it
=
266 while ((cb
= it
.GetNext()) != NULL
) {
272 DISALLOW_COPY_AND_ASSIGN(CallbackList
);
275 template <typename A1
, typename A2
, typename A3
>
276 class CallbackList
<void(A1
, A2
, A3
)>
277 : public internal::CallbackListBase
<Callback
<void(A1
, A2
, A3
)> > {
279 typedef Callback
<void(A1
, A2
, A3
)> CallbackType
;
283 void Notify(typename
internal::CallbackParamTraits
<A1
>::ForwardType a1
,
284 typename
internal::CallbackParamTraits
<A2
>::ForwardType a2
,
285 typename
internal::CallbackParamTraits
<A3
>::ForwardType a3
) {
286 typename
internal::CallbackListBase
<CallbackType
>::Iterator it
=
289 while ((cb
= it
.GetNext()) != NULL
) {
295 DISALLOW_COPY_AND_ASSIGN(CallbackList
);
298 template <typename A1
, typename A2
, typename A3
, typename A4
>
299 class CallbackList
<void(A1
, A2
, A3
, A4
)>
300 : public internal::CallbackListBase
<Callback
<void(A1
, A2
, A3
, A4
)> > {
302 typedef Callback
<void(A1
, A2
, A3
, A4
)> CallbackType
;
306 void Notify(typename
internal::CallbackParamTraits
<A1
>::ForwardType a1
,
307 typename
internal::CallbackParamTraits
<A2
>::ForwardType a2
,
308 typename
internal::CallbackParamTraits
<A3
>::ForwardType a3
,
309 typename
internal::CallbackParamTraits
<A4
>::ForwardType a4
) {
310 typename
internal::CallbackListBase
<CallbackType
>::Iterator it
=
313 while ((cb
= it
.GetNext()) != NULL
) {
314 cb
->Run(a1
, a2
, a3
, a4
);
319 DISALLOW_COPY_AND_ASSIGN(CallbackList
);
322 template <typename A1
, typename A2
, typename A3
, typename A4
, typename A5
>
323 class CallbackList
<void(A1
, A2
, A3
, A4
, A5
)>
324 : public internal::CallbackListBase
<Callback
<void(A1
, A2
, A3
, A4
, A5
)> > {
326 typedef Callback
<void(A1
, A2
, A3
, A4
, A5
)> CallbackType
;
330 void Notify(typename
internal::CallbackParamTraits
<A1
>::ForwardType a1
,
331 typename
internal::CallbackParamTraits
<A2
>::ForwardType a2
,
332 typename
internal::CallbackParamTraits
<A3
>::ForwardType a3
,
333 typename
internal::CallbackParamTraits
<A4
>::ForwardType a4
,
334 typename
internal::CallbackParamTraits
<A5
>::ForwardType a5
) {
335 typename
internal::CallbackListBase
<CallbackType
>::Iterator it
=
338 while ((cb
= it
.GetNext()) != NULL
) {
339 cb
->Run(a1
, a2
, a3
, a4
, a5
);
344 DISALLOW_COPY_AND_ASSIGN(CallbackList
);
347 template <typename A1
, typename A2
, typename A3
, typename A4
, typename A5
,
349 class CallbackList
<void(A1
, A2
, A3
, A4
, A5
, A6
)>
350 : public internal::CallbackListBase
<Callback
<void(A1
, A2
, A3
, A4
, A5
,
353 typedef Callback
<void(A1
, A2
, A3
, A4
, A5
, A6
)> CallbackType
;
357 void Notify(typename
internal::CallbackParamTraits
<A1
>::ForwardType a1
,
358 typename
internal::CallbackParamTraits
<A2
>::ForwardType a2
,
359 typename
internal::CallbackParamTraits
<A3
>::ForwardType a3
,
360 typename
internal::CallbackParamTraits
<A4
>::ForwardType a4
,
361 typename
internal::CallbackParamTraits
<A5
>::ForwardType a5
,
362 typename
internal::CallbackParamTraits
<A6
>::ForwardType a6
) {
363 typename
internal::CallbackListBase
<CallbackType
>::Iterator it
=
366 while ((cb
= it
.GetNext()) != NULL
) {
367 cb
->Run(a1
, a2
, a3
, a4
, a5
, a6
);
372 DISALLOW_COPY_AND_ASSIGN(CallbackList
);
375 template <typename A1
, typename A2
, typename A3
, typename A4
, typename A5
,
376 typename A6
, typename A7
>
377 class CallbackList
<void(A1
, A2
, A3
, A4
, A5
, A6
, A7
)>
378 : public internal::CallbackListBase
<Callback
<void(A1
, A2
, A3
, A4
, A5
, A6
,
381 typedef Callback
<void(A1
, A2
, A3
, A4
, A5
, A6
, A7
)> CallbackType
;
385 void Notify(typename
internal::CallbackParamTraits
<A1
>::ForwardType a1
,
386 typename
internal::CallbackParamTraits
<A2
>::ForwardType a2
,
387 typename
internal::CallbackParamTraits
<A3
>::ForwardType a3
,
388 typename
internal::CallbackParamTraits
<A4
>::ForwardType a4
,
389 typename
internal::CallbackParamTraits
<A5
>::ForwardType a5
,
390 typename
internal::CallbackParamTraits
<A6
>::ForwardType a6
,
391 typename
internal::CallbackParamTraits
<A7
>::ForwardType a7
) {
392 typename
internal::CallbackListBase
<CallbackType
>::Iterator it
=
395 while ((cb
= it
.GetNext()) != NULL
) {
396 cb
->Run(a1
, a2
, a3
, a4
, a5
, a6
, a7
);
401 DISALLOW_COPY_AND_ASSIGN(CallbackList
);
406 #endif // BASE_CALLBACK_LIST_H_