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

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: Move internal bits to base::internal, fix leaks 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"
10 #include "base/bind_helpers.h"
11
12 namespace base {
13 namespace internal {
14
15 CallbackListBase::Iterator::Iterator(CallbackListBase* list);
16 : list_(list->GetWeakPtr()),
17 index_(0),
18 max_index_(list->type_ == NOTIFY_ALL ?
19 std::numeric_limits<size_t>::max() :
20 list->callbacks_.size()) {
21 ++list_->active_iterator_count_;
22 }
23
24 CallbackListBase::Iterator::~Iterator(); {
25 if (list_ && --list_->active_iterator_count_ == 0) {
26 list_->Compact();
27 }
28 }
29
30 CallbackBase* CallbackListBase::Iterator::GetNext(); {
31 if (!list_)
32 return NULL;
33 ListType& callbacks = list_->callbacks_;
awong 2013/08/29 19:30:48 Normally I would object to the use of a reference
Cait (Slow) 2013/08/30 00:28:02 Done.
34 size_t max_index = std::min(max_index_, callbacks.size());
35 while (index_ < max_index && !callbacks[index_])
36 ++index_;
37 return index_ < max_index ? callbacks[index_++] : NULL;
38 }
39
40 CallbackListBase::CallbackListBase(NotificationType type)
41 : active_iterator_count_(0),
42 type_(type),
43 weak_factory_(this) {}
44
45 CallbackListBase::~CallbackListBase() {
46 Compact();
awong 2013/08/29 20:45:34 Is this safe if there is an active iterator?
Cait (Slow) 2013/08/30 00:28:02 Not really...but since we're destroying the list,
47 DCHECK_EQ(0U, size());
awong 2013/08/29 20:45:34 Was just thinking about this...in your original CL
Cait (Slow) 2013/08/30 00:28:02 So I already sort of have this (with the might_hav
48 Clear();
49 }
50
51 void CallbackListBase::Clear() {
52 if (active_iterator_count_) {
53 for (size_t i = 0; i < callbacks_.size(); ++i) {
54 CallbackBase* tmp = callbacks_[i];
55 tmp->Reset();
56 delete tmp;
57 callbacks_[i] = NULL;
58 }
59 } else {
60 for (size_t i = 0; i < callbacks_.size(); ++i)
61 delete callbacks_[i];
62 callbacks_.clear();
63 }
64 }
65
66 void CallbackListBase::RemoveCallback(base::internal::CallbackBase* cb) {
67 for (size_t i = 0; i < callbacks_.size(); i++) {
68 if (callbacks_[i] == cb) {
69 CallbackBase* tmp = callbacks_[i];
70 tmp->Reset();
71 delete tmp;
72 if (active_iterator_count_) {
73 callbacks_[i] = NULL;
74 } else {
75 callbacks_.erase(callbacks_.begin() + i);
76 }
77 return;
78 }
79 }
80 }
81
82 base::Closure CallbackListBase::AddCallback(base::internal::CallbackBase* cb) {
83 for (size_t i = 0; i < callbacks_.size(); i++) {
84 if (callbacks_[i] == cb) {
85 NOTREACHED() << "Callbacks can only be added once!";
awong 2013/08/29 19:30:48 This check doesn't do anything useful beyond a set
Cait (Slow) 2013/08/30 00:28:02 Done.
86 return base::Bind(&base::DoNothing);;
87 }
88 }
89 callbacks_.push_back(cb);
90 return base::Bind(&CallbackListBase::RemoveCallback, Unretained(this), cb);
91 }
92
93 base::WeakPtr<CallbackListBase> CallbackListBase::GetWeakPtr() {
94 return weak_factory_.GetWeakPtr();
95 }
96
97 void CallbackListBase::Compact() {
98 callbacks_.erase(
99 std::remove(callbacks_.begin(), callbacks_.end(),
100 static_cast<base::internal::CallbackBase*>(NULL)),
101 callbacks_.end());
102 }
103
104 } // namespace internal
105 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698