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 } 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 187template <typename Sig> class CallbackList; 188 189template <> 190class 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 210template <typename A1> 211class 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 231template <typename A1, typename A2> 232class 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 253template <typename A1, typename A2, typename A3> 254class 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 276template <typename A1, typename A2, typename A3, typename A4> 277class 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 300template <typename A1, typename A2, typename A3, typename A4, typename A5> 301class 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 325template <typename A1, typename A2, typename A3, typename A4, typename A5, 326 typename A6> 327class 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 353template <typename A1, typename A2, typename A3, typename A4, typename A5, 354 typename A6, typename A7> 355class 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