Home | History | Annotate | Download | only in base
      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:
     85     Subscription(CallbackListBase<CallbackType>* list,
     86                  typename std::list<CallbackType>::iterator iter)
     87         : list_(list),
     88           iter_(iter) {
     89     }
     90 
     91     ~Subscription() {
     92       if (list_->active_iterator_count_)
     93         iter_->Reset();
     94       else
     95         list_->callbacks_.erase(iter_);
     96     }
     97 
     98    private:
     99     CallbackListBase<CallbackType>* list_;
    100     typename std::list<CallbackType>::iterator iter_;
    101 
    102     DISALLOW_COPY_AND_ASSIGN(Subscription);
    103   };
    104 
    105   // Add a callback to the list. The callback will remain registered until the
    106   // returned Subscription is destroyed, which must occur before the
    107   // CallbackList is destroyed.
    108   scoped_ptr<Subscription> Add(const CallbackType& cb) WARN_UNUSED_RESULT {
    109     DCHECK(!cb.is_null());
    110     return scoped_ptr<Subscription>(
    111         new Subscription(this, callbacks_.insert(callbacks_.end(), cb)));
    112   }
    113 
    114  protected:
    115   // An iterator class that can be used to access the list of callbacks.
    116   class Iterator {
    117    public:
    118     explicit Iterator(CallbackListBase<CallbackType>* list)
    119         : list_(list),
    120           list_iter_(list_->callbacks_.begin()) {
    121       ++list_->active_iterator_count_;
    122     }
    123 
    124     Iterator(const Iterator& iter)
    125         : list_(iter.list_),
    126           list_iter_(iter.list_iter_) {
    127       ++list_->active_iterator_count_;
    128     }
    129 
    130     ~Iterator() {
    131       if (list_ && --list_->active_iterator_count_ == 0) {
    132         list_->Compact();
    133       }
    134     }
    135 
    136     CallbackType* GetNext() {
    137       while ((list_iter_ != list_->callbacks_.end()) && list_iter_->is_null())
    138         ++list_iter_;
    139 
    140       CallbackType* cb = NULL;
    141       if (list_iter_ != list_->callbacks_.end()) {
    142         cb = &(*list_iter_);
    143         ++list_iter_;
    144       }
    145       return cb;
    146     }
    147 
    148    private:
    149     CallbackListBase<CallbackType>* list_;
    150     typename std::list<CallbackType>::iterator list_iter_;
    151   };
    152 
    153   CallbackListBase() : active_iterator_count_(0) {}
    154 
    155   ~CallbackListBase() {
    156     DCHECK_EQ(0, active_iterator_count_);
    157     DCHECK_EQ(0U, callbacks_.size());
    158   }
    159 
    160   // Returns an instance of a CallbackListBase::Iterator which can be used
    161   // to run callbacks.
    162   Iterator GetIterator() {
    163     return Iterator(this);
    164   }
    165 
    166   // Compact the list: remove any entries which were NULLed out during
    167   // iteration.
    168   void Compact() {
    169     typename std::list<CallbackType>::iterator it = callbacks_.begin();
    170     while (it != callbacks_.end()) {
    171       if ((*it).is_null())
    172         it = callbacks_.erase(it);
    173       else
    174         ++it;
    175     }
    176   }
    177 
    178  private:
    179   std::list<CallbackType> callbacks_;
    180   int active_iterator_count_;
    181 
    182   DISALLOW_COPY_AND_ASSIGN(CallbackListBase);
    183 };
    184 
    185 }  // namespace internal
    186 
    187 template <typename Sig> class CallbackList;
    188 
    189 template <>
    190 class CallbackList<void(void)>
    191     : public internal::CallbackListBase<Callback<void(void)> > {
    192  public:
    193   typedef Callback<void(void)> CallbackType;
    194 
    195   CallbackList() {}
    196 
    197   void Notify() {
    198     internal::CallbackListBase<CallbackType>::Iterator it =
    199         this->GetIterator();
    200     CallbackType* cb;
    201     while ((cb = it.GetNext()) != NULL) {
    202       cb->Run();
    203     }
    204   }
    205 
    206  private:
    207   DISALLOW_COPY_AND_ASSIGN(CallbackList);
    208 };
    209 
    210 template <typename A1>
    211 class CallbackList<void(A1)>
    212     : public internal::CallbackListBase<Callback<void(A1)> > {
    213  public:
    214   typedef Callback<void(A1)> CallbackType;
    215 
    216   CallbackList() {}
    217 
    218   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1) {
    219     typename internal::CallbackListBase<CallbackType>::Iterator it =
    220         this->GetIterator();
    221     CallbackType* cb;
    222     while ((cb = it.GetNext()) != NULL) {
    223       cb->Run(a1);
    224     }
    225   }
    226 
    227  private:
    228   DISALLOW_COPY_AND_ASSIGN(CallbackList);
    229 };
    230 
    231 template <typename A1, typename A2>
    232 class CallbackList<void(A1, A2)>
    233     : public internal::CallbackListBase<Callback<void(A1, A2)> > {
    234  public:
    235   typedef Callback<void(A1, A2)> CallbackType;
    236 
    237   CallbackList() {}
    238 
    239   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
    240               typename internal::CallbackParamTraits<A2>::ForwardType a2) {
    241     typename internal::CallbackListBase<CallbackType>::Iterator it =
    242         this->GetIterator();
    243     CallbackType* cb;
    244     while ((cb = it.GetNext()) != NULL) {
    245       cb->Run(a1, a2);
    246     }
    247   }
    248 
    249  private:
    250   DISALLOW_COPY_AND_ASSIGN(CallbackList);
    251 };
    252 
    253 template <typename A1, typename A2, typename A3>
    254 class CallbackList<void(A1, A2, A3)>
    255     : public internal::CallbackListBase<Callback<void(A1, A2, A3)> > {
    256  public:
    257   typedef Callback<void(A1, A2, A3)> CallbackType;
    258 
    259   CallbackList() {}
    260 
    261   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
    262               typename internal::CallbackParamTraits<A2>::ForwardType a2,
    263               typename internal::CallbackParamTraits<A3>::ForwardType a3) {
    264     typename internal::CallbackListBase<CallbackType>::Iterator it =
    265         this->GetIterator();
    266     CallbackType* cb;
    267     while ((cb = it.GetNext()) != NULL) {
    268       cb->Run(a1, a2, a3);
    269     }
    270   }
    271 
    272  private:
    273   DISALLOW_COPY_AND_ASSIGN(CallbackList);
    274 };
    275 
    276 template <typename A1, typename A2, typename A3, typename A4>
    277 class CallbackList<void(A1, A2, A3, A4)>
    278     : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4)> > {
    279  public:
    280   typedef Callback<void(A1, A2, A3, A4)> CallbackType;
    281 
    282   CallbackList() {}
    283 
    284   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
    285               typename internal::CallbackParamTraits<A2>::ForwardType a2,
    286               typename internal::CallbackParamTraits<A3>::ForwardType a3,
    287               typename internal::CallbackParamTraits<A4>::ForwardType a4) {
    288     typename internal::CallbackListBase<CallbackType>::Iterator it =
    289         this->GetIterator();
    290     CallbackType* cb;
    291     while ((cb = it.GetNext()) != NULL) {
    292       cb->Run(a1, a2, a3, a4);
    293     }
    294   }
    295 
    296  private:
    297   DISALLOW_COPY_AND_ASSIGN(CallbackList);
    298 };
    299 
    300 template <typename A1, typename A2, typename A3, typename A4, typename A5>
    301 class CallbackList<void(A1, A2, A3, A4, A5)>
    302     : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5)> > {
    303  public:
    304   typedef Callback<void(A1, A2, A3, A4, A5)> CallbackType;
    305 
    306   CallbackList() {}
    307 
    308   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
    309               typename internal::CallbackParamTraits<A2>::ForwardType a2,
    310               typename internal::CallbackParamTraits<A3>::ForwardType a3,
    311               typename internal::CallbackParamTraits<A4>::ForwardType a4,
    312               typename internal::CallbackParamTraits<A5>::ForwardType a5) {
    313     typename internal::CallbackListBase<CallbackType>::Iterator it =
    314         this->GetIterator();
    315     CallbackType* cb;
    316     while ((cb = it.GetNext()) != NULL) {
    317       cb->Run(a1, a2, a3, a4, a5);
    318     }
    319   }
    320 
    321  private:
    322   DISALLOW_COPY_AND_ASSIGN(CallbackList);
    323 };
    324 
    325 template <typename A1, typename A2, typename A3, typename A4, typename A5,
    326     typename A6>
    327 class CallbackList<void(A1, A2, A3, A4, A5, A6)>
    328     : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5,
    329         A6)> > {
    330  public:
    331   typedef Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType;
    332 
    333   CallbackList() {}
    334 
    335   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
    336               typename internal::CallbackParamTraits<A2>::ForwardType a2,
    337               typename internal::CallbackParamTraits<A3>::ForwardType a3,
    338               typename internal::CallbackParamTraits<A4>::ForwardType a4,
    339               typename internal::CallbackParamTraits<A5>::ForwardType a5,
    340               typename internal::CallbackParamTraits<A6>::ForwardType a6) {
    341     typename internal::CallbackListBase<CallbackType>::Iterator it =
    342         this->GetIterator();
    343     CallbackType* cb;
    344     while ((cb = it.GetNext()) != NULL) {
    345       cb->Run(a1, a2, a3, a4, a5, a6);
    346     }
    347   }
    348 
    349  private:
    350   DISALLOW_COPY_AND_ASSIGN(CallbackList);
    351 };
    352 
    353 template <typename A1, typename A2, typename A3, typename A4, typename A5,
    354     typename A6, typename A7>
    355 class CallbackList<void(A1, A2, A3, A4, A5, A6, A7)>
    356     : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5, A6,
    357         A7)> > {
    358  public:
    359   typedef Callback<void(A1, A2, A3, A4, A5, A6, A7)> CallbackType;
    360 
    361   CallbackList() {}
    362 
    363   void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
    364               typename internal::CallbackParamTraits<A2>::ForwardType a2,
    365               typename internal::CallbackParamTraits<A3>::ForwardType a3,
    366               typename internal::CallbackParamTraits<A4>::ForwardType a4,
    367               typename internal::CallbackParamTraits<A5>::ForwardType a5,
    368               typename internal::CallbackParamTraits<A6>::ForwardType a6,
    369               typename internal::CallbackParamTraits<A7>::ForwardType a7) {
    370     typename internal::CallbackListBase<CallbackType>::Iterator it =
    371         this->GetIterator();
    372     CallbackType* cb;
    373     while ((cb = it.GetNext()) != NULL) {
    374       cb->Run(a1, a2, a3, a4, a5, a6, a7);
    375     }
    376   }
    377 
    378  private:
    379   DISALLOW_COPY_AND_ASSIGN(CallbackList);
    380 };
    381 
    382 }  // namespace base
    383 
    384 #endif  // BASE_CALLBACK_LIST_H_
    385