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         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.
    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.
    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 
    129  protected:
    130   // An iterator class that can be used to access the list of callbacks.
    131   class Iterator {
    132    public:
    133     explicit Iterator(CallbackListBase<CallbackType>* list)
    134         : 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 
    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 
    168   CallbackListBase() : active_iterator_count_(0) {}
    169 
    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.
    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();
    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 
    217   CallbackList() {}
    218 
    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 
    238   CallbackList() {}
    239 
    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 
    259   CallbackList() {}
    260 
    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 
    281   CallbackList() {}
    282 
    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 
    304   CallbackList() {}
    305 
    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 
    328   CallbackList() {}
    329 
    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 
    355   CallbackList() {}
    356 
    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 
    383   CallbackList() {}
    384 
    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