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