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 76namespace base { 77 78namespace internal { 79 80template <typename CallbackType> 81class 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 209template <typename Sig> class CallbackList; 210 211template <> 212class 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 232template <typename A1> 233class 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 253template <typename A1, typename A2> 254class 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 275template <typename A1, typename A2, typename A3> 276class 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 298template <typename A1, typename A2, typename A3, typename A4> 299class 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 322template <typename A1, typename A2, typename A3, typename A4, typename A5> 323class 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 347template <typename A1, typename A2, typename A3, typename A4, typename A5, 348 typename A6> 349class 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 375template <typename A1, typename A2, typename A3, typename A4, typename A5, 376 typename A6, typename A7> 377class 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