blob: 5b911fd4867e1bec80ce002c57fd5d58b129247b [file] [log] [blame]
caitkp@google.com2b10b742013-09-25 22:56:23 +09001// This file was GENERATED by command:
caitkp@chromium.org49647322013-09-27 04:20:18 +09002// pump.py callback_list.h.pump
caitkp@google.com2b10b742013-09-25 22:56:23 +09003// DO NOT EDIT BY HAND!!!
4
5
caitkp@chromium.org1268af12013-09-12 00:16:33 +09006// 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.
9
caitkp@chromium.org49647322013-09-27 04:20:18 +090010#ifndef BASE_CALLBACK_LIST_H_
11#define BASE_CALLBACK_LIST_H_
caitkp@chromium.org1268af12013-09-12 00:16:33 +090012
13#include <list>
14
15#include "base/basictypes.h"
16#include "base/callback.h"
caitkp@google.com2b10b742013-09-25 22:56:23 +090017#include "base/callback_internal.h"
caitkp@chromium.org1268af12013-09-12 00:16:33 +090018#include "base/compiler_specific.h"
19#include "base/logging.h"
20#include "base/memory/scoped_ptr.h"
21
22// OVERVIEW:
23//
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.
28//
29// TYPICAL USAGE:
30//
31// class MyWidget {
32// public:
33// ...
34//
35// typedef base::Callback<void(const Foo&)> OnFooCallback;
36//
caitkp@chromium.org49647322013-09-27 04:20:18 +090037// scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
caitkp@google.com2b10b742013-09-25 22:56:23 +090038// RegisterCallback(const OnFooCallback& cb) {
caitkp@chromium.org49647322013-09-27 04:20:18 +090039// return callback_list_.Add(cb);
caitkp@chromium.org1268af12013-09-12 00:16:33 +090040// }
41//
42// private:
43// void NotifyFoo(const Foo& foo) {
caitkp@chromium.org49647322013-09-27 04:20:18 +090044// callback_list_.Notify(foo);
caitkp@chromium.org1268af12013-09-12 00:16:33 +090045// }
46//
caitkp@chromium.org49647322013-09-27 04:20:18 +090047// base::CallbackList<void(const Foo&)> callback_list_;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +090048//
49// DISALLOW_COPY_AND_ASSIGN(MyWidget);
caitkp@chromium.org1268af12013-09-12 00:16:33 +090050// };
51//
52//
53// class MyWidgetListener {
54// public:
55// MyWidgetListener::MyWidgetListener() {
56// foo_subscription_ = MyWidget::GetCurrent()->RegisterCallback(
57// base::Bind(&MyWidgetListener::OnFoo, this)));
58// }
59//
60// MyWidgetListener::~MyWidgetListener() {
61// // Subscription gets deleted automatically and will deregister
62// // the callback in the process.
63// }
64//
65// private:
66// void OnFoo(const Foo& foo) {
67// // Do something.
68// }
69//
caitkp@chromium.org49647322013-09-27 04:20:18 +090070// scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
caitkp@google.com2b10b742013-09-25 22:56:23 +090071// foo_subscription_;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +090072//
73// DISALLOW_COPY_AND_ASSIGN(MyWidgetListener);
caitkp@chromium.org1268af12013-09-12 00:16:33 +090074// };
75
76namespace base {
77
78namespace internal {
79
80template <typename CallbackType>
caitkp@chromium.org49647322013-09-27 04:20:18 +090081class CallbackListBase {
caitkp@chromium.org1268af12013-09-12 00:16:33 +090082 public:
83 class Subscription {
84 public:
caitkp@chromium.org49647322013-09-27 04:20:18 +090085 Subscription(CallbackListBase<CallbackType>* list,
caitkp@chromium.org1268af12013-09-12 00:16:33 +090086 typename std::list<CallbackType>::iterator iter)
87 : list_(list),
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +090088 iter_(iter) {
89 }
caitkp@chromium.org1268af12013-09-12 00:16:33 +090090
91 ~Subscription() {
jam@chromium.org63a01af2014-05-13 01:36:10 +090092 if (list_->active_iterator_count_) {
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +090093 iter_->Reset();
jam@chromium.org63a01af2014-05-13 01:36:10 +090094 } else {
caitkp@chromium.org1268af12013-09-12 00:16:33 +090095 list_->callbacks_.erase(iter_);
jam@chromium.org63a01af2014-05-13 01:36:10 +090096 if (!list_->removal_callback_.is_null())
97 list_->removal_callback_.Run();
98 }
caitkp@chromium.org1268af12013-09-12 00:16:33 +090099 }
100
101 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900102 CallbackListBase<CallbackType>* list_;
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900103 typename std::list<CallbackType>::iterator iter_;
104
105 DISALLOW_COPY_AND_ASSIGN(Subscription);
106 };
107
108 // Add a callback to the list. The callback will remain registered until the
109 // returned Subscription is destroyed, which must occur before the
caitkp@chromium.org49647322013-09-27 04:20:18 +0900110 // CallbackList is destroyed.
bauerb@chromium.org69cfb182013-11-16 00:54:36 +0900111 scoped_ptr<Subscription> Add(const CallbackType& cb) WARN_UNUSED_RESULT {
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900112 DCHECK(!cb.is_null());
113 return scoped_ptr<Subscription>(
114 new Subscription(this, callbacks_.insert(callbacks_.end(), cb)));
115 }
116
jam@chromium.org63a01af2014-05-13 01:36:10 +0900117 // 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;
120 }
121
122 // Returns true if there are no subscriptions. This is only valid to call when
123 // not looping through the list.
124 bool empty() {
125 DCHECK_EQ(0, active_iterator_count_);
126 return callbacks_.empty();
127 }
128
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900129 protected:
130 // An iterator class that can be used to access the list of callbacks.
131 class Iterator {
132 public:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900133 explicit Iterator(CallbackListBase<CallbackType>* list)
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900134 : list_(list),
135 list_iter_(list_->callbacks_.begin()) {
136 ++list_->active_iterator_count_;
137 }
138
139 Iterator(const Iterator& iter)
140 : list_(iter.list_),
141 list_iter_(iter.list_iter_) {
142 ++list_->active_iterator_count_;
143 }
144
145 ~Iterator() {
146 if (list_ && --list_->active_iterator_count_ == 0) {
147 list_->Compact();
148 }
149 }
150
151 CallbackType* GetNext() {
152 while ((list_iter_ != list_->callbacks_.end()) && list_iter_->is_null())
153 ++list_iter_;
154
caitkp@google.com146349f2013-09-12 01:44:56 +0900155 CallbackType* cb = NULL;
156 if (list_iter_ != list_->callbacks_.end()) {
157 cb = &(*list_iter_);
158 ++list_iter_;
159 }
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900160 return cb;
161 }
162
163 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900164 CallbackListBase<CallbackType>* list_;
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900165 typename std::list<CallbackType>::iterator list_iter_;
166 };
167
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900168 CallbackListBase() : active_iterator_count_(0) {}
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900169
caitkp@chromium.org49647322013-09-27 04:20:18 +0900170 ~CallbackListBase() {
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900171 DCHECK_EQ(0, active_iterator_count_);
172 DCHECK_EQ(0U, callbacks_.size());
173 }
174
caitkp@chromium.org49647322013-09-27 04:20:18 +0900175 // Returns an instance of a CallbackListBase::Iterator which can be used
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900176 // to run callbacks.
177 Iterator GetIterator() {
178 return Iterator(this);
179 }
180
181 // Compact the list: remove any entries which were NULLed out during
182 // iteration.
183 void Compact() {
184 typename std::list<CallbackType>::iterator it = callbacks_.begin();
jam@chromium.org63a01af2014-05-13 01:36:10 +0900185 bool updated = false;
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900186 while (it != callbacks_.end()) {
jam@chromium.org63a01af2014-05-13 01:36:10 +0900187 if ((*it).is_null()) {
188 updated = true;
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900189 it = callbacks_.erase(it);
jam@chromium.org63a01af2014-05-13 01:36:10 +0900190 } else {
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900191 ++it;
jam@chromium.org63a01af2014-05-13 01:36:10 +0900192 }
193
194 if (updated && !removal_callback_.is_null())
195 removal_callback_.Run();
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900196 }
197 }
198
199 private:
200 std::list<CallbackType> callbacks_;
201 int active_iterator_count_;
jam@chromium.org63a01af2014-05-13 01:36:10 +0900202 Closure removal_callback_;
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900203
caitkp@chromium.org49647322013-09-27 04:20:18 +0900204 DISALLOW_COPY_AND_ASSIGN(CallbackListBase);
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900205};
206
207} // namespace internal
208
caitkp@chromium.org49647322013-09-27 04:20:18 +0900209template <typename Sig> class CallbackList;
caitkp@google.com2b10b742013-09-25 22:56:23 +0900210
211template <>
caitkp@chromium.org49647322013-09-27 04:20:18 +0900212class CallbackList<void(void)>
213 : public internal::CallbackListBase<Callback<void(void)> > {
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900214 public:
caitkp@google.com2b10b742013-09-25 22:56:23 +0900215 typedef Callback<void(void)> CallbackType;
216
caitkp@chromium.org49647322013-09-27 04:20:18 +0900217 CallbackList() {}
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900218
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900219 void Notify() {
caitkp@chromium.org49647322013-09-27 04:20:18 +0900220 internal::CallbackListBase<CallbackType>::Iterator it =
caitkp@google.com2b10b742013-09-25 22:56:23 +0900221 this->GetIterator();
222 CallbackType* cb;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900223 while ((cb = it.GetNext()) != NULL) {
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900224 cb->Run();
225 }
226 }
227
228 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900229 DISALLOW_COPY_AND_ASSIGN(CallbackList);
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900230};
231
caitkp@google.com2b10b742013-09-25 22:56:23 +0900232template <typename A1>
caitkp@chromium.org49647322013-09-27 04:20:18 +0900233class CallbackList<void(A1)>
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900234 : public internal::CallbackListBase<Callback<void(A1)> > {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900235 public:
236 typedef Callback<void(A1)> CallbackType;
237
caitkp@chromium.org49647322013-09-27 04:20:18 +0900238 CallbackList() {}
caitkp@google.com2b10b742013-09-25 22:56:23 +0900239
240 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1) {
caitkp@chromium.org49647322013-09-27 04:20:18 +0900241 typename internal::CallbackListBase<CallbackType>::Iterator it =
caitkp@google.com2b10b742013-09-25 22:56:23 +0900242 this->GetIterator();
243 CallbackType* cb;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900244 while ((cb = it.GetNext()) != NULL) {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900245 cb->Run(a1);
246 }
247 }
248
249 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900250 DISALLOW_COPY_AND_ASSIGN(CallbackList);
caitkp@google.com2b10b742013-09-25 22:56:23 +0900251};
252
253template <typename A1, typename A2>
caitkp@chromium.org49647322013-09-27 04:20:18 +0900254class CallbackList<void(A1, A2)>
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900255 : public internal::CallbackListBase<Callback<void(A1, A2)> > {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900256 public:
257 typedef Callback<void(A1, A2)> CallbackType;
258
caitkp@chromium.org49647322013-09-27 04:20:18 +0900259 CallbackList() {}
caitkp@google.com2b10b742013-09-25 22:56:23 +0900260
261 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
262 typename internal::CallbackParamTraits<A2>::ForwardType a2) {
caitkp@chromium.org49647322013-09-27 04:20:18 +0900263 typename internal::CallbackListBase<CallbackType>::Iterator it =
caitkp@google.com2b10b742013-09-25 22:56:23 +0900264 this->GetIterator();
265 CallbackType* cb;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900266 while ((cb = it.GetNext()) != NULL) {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900267 cb->Run(a1, a2);
268 }
269 }
270
271 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900272 DISALLOW_COPY_AND_ASSIGN(CallbackList);
caitkp@google.com2b10b742013-09-25 22:56:23 +0900273};
274
275template <typename A1, typename A2, typename A3>
caitkp@chromium.org49647322013-09-27 04:20:18 +0900276class CallbackList<void(A1, A2, A3)>
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900277 : public internal::CallbackListBase<Callback<void(A1, A2, A3)> > {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900278 public:
279 typedef Callback<void(A1, A2, A3)> CallbackType;
280
caitkp@chromium.org49647322013-09-27 04:20:18 +0900281 CallbackList() {}
caitkp@google.com2b10b742013-09-25 22:56:23 +0900282
283 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
284 typename internal::CallbackParamTraits<A2>::ForwardType a2,
285 typename internal::CallbackParamTraits<A3>::ForwardType a3) {
caitkp@chromium.org49647322013-09-27 04:20:18 +0900286 typename internal::CallbackListBase<CallbackType>::Iterator it =
caitkp@google.com2b10b742013-09-25 22:56:23 +0900287 this->GetIterator();
288 CallbackType* cb;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900289 while ((cb = it.GetNext()) != NULL) {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900290 cb->Run(a1, a2, a3);
291 }
292 }
293
294 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900295 DISALLOW_COPY_AND_ASSIGN(CallbackList);
caitkp@google.com2b10b742013-09-25 22:56:23 +0900296};
297
298template <typename A1, typename A2, typename A3, typename A4>
caitkp@chromium.org49647322013-09-27 04:20:18 +0900299class CallbackList<void(A1, A2, A3, A4)>
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900300 : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4)> > {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900301 public:
302 typedef Callback<void(A1, A2, A3, A4)> CallbackType;
303
caitkp@chromium.org49647322013-09-27 04:20:18 +0900304 CallbackList() {}
caitkp@google.com2b10b742013-09-25 22:56:23 +0900305
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) {
caitkp@chromium.org49647322013-09-27 04:20:18 +0900310 typename internal::CallbackListBase<CallbackType>::Iterator it =
caitkp@google.com2b10b742013-09-25 22:56:23 +0900311 this->GetIterator();
312 CallbackType* cb;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900313 while ((cb = it.GetNext()) != NULL) {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900314 cb->Run(a1, a2, a3, a4);
315 }
316 }
317
318 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900319 DISALLOW_COPY_AND_ASSIGN(CallbackList);
caitkp@google.com2b10b742013-09-25 22:56:23 +0900320};
321
322template <typename A1, typename A2, typename A3, typename A4, typename A5>
caitkp@chromium.org49647322013-09-27 04:20:18 +0900323class CallbackList<void(A1, A2, A3, A4, A5)>
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900324 : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5)> > {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900325 public:
326 typedef Callback<void(A1, A2, A3, A4, A5)> CallbackType;
327
caitkp@chromium.org49647322013-09-27 04:20:18 +0900328 CallbackList() {}
caitkp@google.com2b10b742013-09-25 22:56:23 +0900329
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) {
caitkp@chromium.org49647322013-09-27 04:20:18 +0900335 typename internal::CallbackListBase<CallbackType>::Iterator it =
caitkp@google.com2b10b742013-09-25 22:56:23 +0900336 this->GetIterator();
337 CallbackType* cb;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900338 while ((cb = it.GetNext()) != NULL) {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900339 cb->Run(a1, a2, a3, a4, a5);
340 }
341 }
342
343 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900344 DISALLOW_COPY_AND_ASSIGN(CallbackList);
caitkp@google.com2b10b742013-09-25 22:56:23 +0900345};
346
347template <typename A1, typename A2, typename A3, typename A4, typename A5,
348 typename A6>
caitkp@chromium.org49647322013-09-27 04:20:18 +0900349class CallbackList<void(A1, A2, A3, A4, A5, A6)>
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900350 : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5,
351 A6)> > {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900352 public:
353 typedef Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType;
354
caitkp@chromium.org49647322013-09-27 04:20:18 +0900355 CallbackList() {}
caitkp@google.com2b10b742013-09-25 22:56:23 +0900356
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) {
caitkp@chromium.org49647322013-09-27 04:20:18 +0900363 typename internal::CallbackListBase<CallbackType>::Iterator it =
caitkp@google.com2b10b742013-09-25 22:56:23 +0900364 this->GetIterator();
365 CallbackType* cb;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900366 while ((cb = it.GetNext()) != NULL) {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900367 cb->Run(a1, a2, a3, a4, a5, a6);
368 }
369 }
370
371 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900372 DISALLOW_COPY_AND_ASSIGN(CallbackList);
caitkp@google.com2b10b742013-09-25 22:56:23 +0900373};
374
375template <typename A1, typename A2, typename A3, typename A4, typename A5,
376 typename A6, typename A7>
caitkp@chromium.org49647322013-09-27 04:20:18 +0900377class CallbackList<void(A1, A2, A3, A4, A5, A6, A7)>
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900378 : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5, A6,
379 A7)> > {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900380 public:
381 typedef Callback<void(A1, A2, A3, A4, A5, A6, A7)> CallbackType;
382
caitkp@chromium.org49647322013-09-27 04:20:18 +0900383 CallbackList() {}
caitkp@google.com2b10b742013-09-25 22:56:23 +0900384
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) {
caitkp@chromium.org49647322013-09-27 04:20:18 +0900392 typename internal::CallbackListBase<CallbackType>::Iterator it =
caitkp@google.com2b10b742013-09-25 22:56:23 +0900393 this->GetIterator();
394 CallbackType* cb;
caitkp@chromium.org0b4414d2013-10-10 08:28:21 +0900395 while ((cb = it.GetNext()) != NULL) {
caitkp@google.com2b10b742013-09-25 22:56:23 +0900396 cb->Run(a1, a2, a3, a4, a5, a6, a7);
397 }
398 }
399
400 private:
caitkp@chromium.org49647322013-09-27 04:20:18 +0900401 DISALLOW_COPY_AND_ASSIGN(CallbackList);
caitkp@google.com2b10b742013-09-25 22:56:23 +0900402};
403
caitkp@chromium.org1268af12013-09-12 00:16:33 +0900404} // namespace base
405
caitkp@chromium.org49647322013-09-27 04:20:18 +0900406#endif // BASE_CALLBACK_LIST_H_