Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(854)

Side by Side Diff: base/callback_list_internal.cc

Issue 22877038: Add a CallbackRegistry class to base/ to manage callbacks (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Get rid of CallbackListWithDetails, use specialization instead Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/callback_list_internal.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
erikwright (departed) 2013/09/04 19:35:55 The only purpose of bind in this file is for build
10 #include "base/bind_helpers.h"
11
12 namespace base {
13 namespace internal {
14
15 CallbackListImpl::Iterator::Iterator(
16 const base::WeakPtr<CallbackListImpl>& list)
17 : list_(list),
18 index_(0),
19 max_index_(list->type_ == CALLBACKS_NOTIFY_ALL ?
20 std::numeric_limits<size_t>::max() :
21 list->callbacks_.size()) {
22 ++list_->active_iterator_count_;
23 }
24
25 CallbackListImpl::Iterator::~Iterator() {
26 if (list_ && --list_->active_iterator_count_ == 0) {
27 list_->Compact();
28 }
29 }
30
31 CallbackBase* CallbackListImpl::Iterator::GetNext() {
32 if (!list_)
33 return NULL;
34 size_t max_index = std::min(max_index_, list_->callbacks_.size());
35 while (index_ < max_index && !list_->callbacks_[index_])
36 ++index_;
37 return index_ < max_index ? list_->callbacks_[index_++] : NULL;
38 }
39
40 CallbackListImpl::CallbackListImpl(CallbackNotificationType type)
41 : active_iterator_count_(0),
42 type_(type),
43 weak_factory_(this) {}
44
45 CallbackListImpl::~CallbackListImpl() {
46 Clear();
47 }
48
49 void CallbackListImpl::Clear() {
50 if (active_iterator_count_) {
51 for (size_t i = 0; i < callbacks_.size(); ++i) {
52 CallbackBase* tmp = callbacks_[i];
53 tmp->Reset();
erikwright (departed) 2013/09/04 19:35:55 Why is the Reset necessary?
Cait (Slow) 2013/09/04 22:09:25 Done.
54 delete tmp;
55 callbacks_[i] = NULL;
56 }
57 } else {
58 for (size_t i = 0; i < callbacks_.size(); ++i)
59 delete callbacks_[i];
60 callbacks_.clear();
61 }
62 }
63
64 void CallbackListImpl::RemoveCallback(base::internal::CallbackBase* cb) {
65 for (size_t i = 0; i < callbacks_.size(); i++) {
66 if (callbacks_[i] == cb) {
67 CallbackBase* tmp = callbacks_[i];
68 tmp->Reset();
erikwright (departed) 2013/09/04 19:35:55 Again, why is the Reset necessary?
Cait (Slow) 2013/09/04 22:09:25 Done.
69 delete tmp;
70 if (active_iterator_count_) {
71 callbacks_[i] = NULL;
72 } else {
73 callbacks_.erase(callbacks_.begin() + i);
74 }
75 return;
76 }
77 }
78 }
79
80 base::Closure CallbackListImpl::AddCallback(base::internal::CallbackBase* cb) {
81 callbacks_.push_back(cb);
82 return base::Bind(&CallbackListImpl::RemoveCallback, Unretained(this), cb);
83 }
84
85 base::WeakPtr<CallbackListImpl> CallbackListImpl::GetWeakPtr() {
86 return weak_factory_.GetWeakPtr();
87 }
88
89 void CallbackListImpl::Compact() {
90 callbacks_.erase(
91 std::remove(callbacks_.begin(), callbacks_.end(),
92 static_cast<base::internal::CallbackBase*>(NULL)),
93 callbacks_.end());
94 }
95
96 } // namespace internal
97 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698