• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file was GENERATED by command:
2 //     pump.py callback_list.h.pump
3 // DO NOT EDIT BY HAND!!!
4 
5 
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.
9 
10 #ifndef BASE_CALLBACK_LIST_H_
11 #define BASE_CALLBACK_LIST_H_
12 
13 #include <list>
14 
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"
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 //
37 //   scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
38 //   RegisterCallback(const OnFooCallback& cb) {
39 //     return callback_list_.Add(cb);
40 //   }
41 //
42 //  private:
43 //   void NotifyFoo(const Foo& foo) {
44 //      callback_list_.Notify(foo);
45 //   }
46 //
47 //   base::CallbackList<void(const Foo&)> callback_list_;
48 //
49 //   DISALLOW_COPY_AND_ASSIGN(MyWidget);
50 // };
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 //
70 //   scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
71 //       foo_subscription_;
72 //
73 //   DISALLOW_COPY_AND_ASSIGN(MyWidgetListener);
74 // };
75 
76 namespace base {
77 
78 namespace internal {
79 
80 template <typename CallbackType>
81 class CallbackListBase {
82  public:
83   class Subscription {
84    public:
Subscription(CallbackListBase<CallbackType> * list,typename std::list<CallbackType>::iterator iter)85     Subscription(CallbackListBase<CallbackType>* list,
86                  typename std::list<CallbackType>::iterator iter)
87         : list_(list),
88           iter_(iter) {
89     }
90 
~Subscription()91     ~Subscription() {
92       if (list_->active_iterator_count_) {
93         iter_->Reset();
94       } else {
95         list_->callbacks_.erase(iter_);
96         if (!list_->removal_callback_.is_null())
97           list_->removal_callback_.Run();
98       }
99     }
100 
101    private:
102     CallbackListBase<CallbackType>* list_;
103     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
110   // CallbackList is destroyed.
Add(const CallbackType & cb)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)));
115   }
116 
117   // Sets a callback which will be run when a subscription list is changed.
set_removal_callback(const Closure & callback)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.
empty()124   bool empty() {
125     DCHECK_EQ(0, active_iterator_count_);
126     return callbacks_.empty();
127   }
128 
129  protected:
130   // An iterator class that can be used to access the list of callbacks.
131   class Iterator {
132    public:
Iterator(CallbackListBase<CallbackType> * list)133     explicit Iterator(CallbackListBase<CallbackType>* list)
134         : list_(list),
135           list_iter_(list_->callbacks_.begin()) {
136       ++list_->active_iterator_count_;
137     }
138 
Iterator(const Iterator & iter)139     Iterator(const Iterator& iter)
140         : list_(iter.list_),
141           list_iter_(iter.list_iter_) {
142       ++list_->active_iterator_count_;
143     }
144 
~Iterator()145     ~Iterator() {
146       if (list_ && --list_->active_iterator_count_ == 0) {
147         list_->Compact();
148       }
149     }
150 
GetNext()151     CallbackType* GetNext() {
152       while ((list_iter_ != list_->callbacks_.end()) && list_iter_->is_null())
153         ++list_iter_;
154 
155       CallbackType* cb = NULL;
156       if (list_iter_ != list_->callbacks_.end()) {
157         cb = &(*list_iter_);
158         ++list_iter_;
159       }
160       return cb;
161     }
162 
163    private:
164     CallbackListBase<CallbackType>* list_;
165     typename std::list<CallbackType>::iterator list_iter_;
166   };
167 
CallbackListBase()168   CallbackListBase() : active_iterator_count_(0) {}
169 
~CallbackListBase()170   ~CallbackListBase() {
171     DCHECK_EQ(0, active_iterator_count_);
172     DCHECK_EQ(0U, callbacks_.size());
173   }
174 
175   // Returns an instance of a CallbackListBase::Iterator which can be used
176   // to run callbacks.
GetIterator()177   Iterator GetIterator() {
178     return Iterator(this);
179   }
180 
181   // Compact the list: remove any entries which were NULLed out during
182   // iteration.
Compact()183   void Compact() {
184     typename std::list<CallbackType>::iterator it = callbacks_.begin();
185     bool updated = false;
186     while (it != callbacks_.end()) {
187       if ((*it).is_null()) {
188         updated = true;
189         it = callbacks_.erase(it);
190       } else {
191         ++it;
192       }
193 
194       if (updated && !removal_callback_.is_null())
195         removal_callback_.Run();
196     }
197   }
198 
199  private:
200   std::list<CallbackType> callbacks_;
201   int active_iterator_count_;
202   Closure removal_callback_;
203 
204   DISALLOW_COPY_AND_ASSIGN(CallbackListBase);
205 };
206 
207 }  // namespace internal
208 
209 template <typename Sig> class CallbackList;
210 
211 template <>
212 class CallbackList<void(void)>
213     : public internal::CallbackListBase<Callback<void(void)> > {
214  public:
215   typedef Callback<void(void)> CallbackType;
216 
CallbackList()217   CallbackList() {}
218 
Notify()219   void Notify() {
220     internal::CallbackListBase<CallbackType>::Iterator it =
221         this->GetIterator();
222     CallbackType* cb;
223     while ((cb = it.GetNext()) != NULL) {
224       cb->Run();
225     }
226   }
227 
228  private:
229   DISALLOW_COPY_AND_ASSIGN(CallbackList);
230 };
231 
232 template <typename A1>
233 class CallbackList<void(A1)>
234     : public internal::CallbackListBase<Callback<void(A1)> > {
235  public:
236   typedef Callback<void(A1)> CallbackType;
237 
CallbackList()238   CallbackList() {}
239 
Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1)240   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1) {
241     typename internal::CallbackListBase<CallbackType>::Iterator it =
242         this->GetIterator();
243     CallbackType* cb;
244     while ((cb = it.GetNext()) != NULL) {
245       cb->Run(a1);
246     }
247   }
248 
249  private:
250   DISALLOW_COPY_AND_ASSIGN(CallbackList);
251 };
252 
253 template <typename A1, typename A2>
254 class CallbackList<void(A1, A2)>
255     : public internal::CallbackListBase<Callback<void(A1, A2)> > {
256  public:
257   typedef Callback<void(A1, A2)> CallbackType;
258 
CallbackList()259   CallbackList() {}
260 
Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,typename internal::CallbackParamTraits<A2>::ForwardType a2)261   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
262               typename internal::CallbackParamTraits<A2>::ForwardType a2) {
263     typename internal::CallbackListBase<CallbackType>::Iterator it =
264         this->GetIterator();
265     CallbackType* cb;
266     while ((cb = it.GetNext()) != NULL) {
267       cb->Run(a1, a2);
268     }
269   }
270 
271  private:
272   DISALLOW_COPY_AND_ASSIGN(CallbackList);
273 };
274 
275 template <typename A1, typename A2, typename A3>
276 class CallbackList<void(A1, A2, A3)>
277     : public internal::CallbackListBase<Callback<void(A1, A2, A3)> > {
278  public:
279   typedef Callback<void(A1, A2, A3)> CallbackType;
280 
CallbackList()281   CallbackList() {}
282 
Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,typename internal::CallbackParamTraits<A2>::ForwardType a2,typename internal::CallbackParamTraits<A3>::ForwardType a3)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 =
287         this->GetIterator();
288     CallbackType* cb;
289     while ((cb = it.GetNext()) != NULL) {
290       cb->Run(a1, a2, a3);
291     }
292   }
293 
294  private:
295   DISALLOW_COPY_AND_ASSIGN(CallbackList);
296 };
297 
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)> > {
301  public:
302   typedef Callback<void(A1, A2, A3, A4)> CallbackType;
303 
CallbackList()304   CallbackList() {}
305 
Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,typename internal::CallbackParamTraits<A2>::ForwardType a2,typename internal::CallbackParamTraits<A3>::ForwardType a3,typename internal::CallbackParamTraits<A4>::ForwardType a4)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 =
311         this->GetIterator();
312     CallbackType* cb;
313     while ((cb = it.GetNext()) != NULL) {
314       cb->Run(a1, a2, a3, a4);
315     }
316   }
317 
318  private:
319   DISALLOW_COPY_AND_ASSIGN(CallbackList);
320 };
321 
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)> > {
325  public:
326   typedef Callback<void(A1, A2, A3, A4, A5)> CallbackType;
327 
CallbackList()328   CallbackList() {}
329 
Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,typename internal::CallbackParamTraits<A2>::ForwardType a2,typename internal::CallbackParamTraits<A3>::ForwardType a3,typename internal::CallbackParamTraits<A4>::ForwardType a4,typename internal::CallbackParamTraits<A5>::ForwardType a5)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 =
336         this->GetIterator();
337     CallbackType* cb;
338     while ((cb = it.GetNext()) != NULL) {
339       cb->Run(a1, a2, a3, a4, a5);
340     }
341   }
342 
343  private:
344   DISALLOW_COPY_AND_ASSIGN(CallbackList);
345 };
346 
347 template <typename A1, typename A2, typename A3, typename A4, typename A5,
348     typename A6>
349 class CallbackList<void(A1, A2, A3, A4, A5, A6)>
350     : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5,
351         A6)> > {
352  public:
353   typedef Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType;
354 
CallbackList()355   CallbackList() {}
356 
Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,typename internal::CallbackParamTraits<A2>::ForwardType a2,typename internal::CallbackParamTraits<A3>::ForwardType a3,typename internal::CallbackParamTraits<A4>::ForwardType a4,typename internal::CallbackParamTraits<A5>::ForwardType a5,typename internal::CallbackParamTraits<A6>::ForwardType a6)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 =
364         this->GetIterator();
365     CallbackType* cb;
366     while ((cb = it.GetNext()) != NULL) {
367       cb->Run(a1, a2, a3, a4, a5, a6);
368     }
369   }
370 
371  private:
372   DISALLOW_COPY_AND_ASSIGN(CallbackList);
373 };
374 
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,
379         A7)> > {
380  public:
381   typedef Callback<void(A1, A2, A3, A4, A5, A6, A7)> CallbackType;
382 
CallbackList()383   CallbackList() {}
384 
Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,typename internal::CallbackParamTraits<A2>::ForwardType a2,typename internal::CallbackParamTraits<A3>::ForwardType a3,typename internal::CallbackParamTraits<A4>::ForwardType a4,typename internal::CallbackParamTraits<A5>::ForwardType a5,typename internal::CallbackParamTraits<A6>::ForwardType a6,typename internal::CallbackParamTraits<A7>::ForwardType a7)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 =
393         this->GetIterator();
394     CallbackType* cb;
395     while ((cb = it.GetNext()) != NULL) {
396       cb->Run(a1, a2, a3, a4, a5, a6, a7);
397     }
398   }
399 
400  private:
401   DISALLOW_COPY_AND_ASSIGN(CallbackList);
402 };
403 
404 }  // namespace base
405 
406 #endif  // BASE_CALLBACK_LIST_H_
407