OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // CancelableCallback is a wrapper around base::Callback that allows | 5 // CancelableCallback is a wrapper around base::Callback that allows |
6 // cancellation of a callback. CancelableCallback takes a reference on the | 6 // cancellation of a callback. CancelableCallback takes a reference on the |
7 // wrapped callback until this object is destroyed or Reset()/Cancel() are | 7 // wrapped callback until this object is destroyed or Reset()/Cancel() are |
8 // called. | 8 // called. |
9 // | 9 // |
10 // NOTE: | 10 // NOTE: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "base/callback_internal.h" | 48 #include "base/callback_internal.h" |
49 #include "base/compiler_specific.h" | 49 #include "base/compiler_specific.h" |
50 #include "base/logging.h" | 50 #include "base/logging.h" |
51 #include "base/memory/weak_ptr.h" | 51 #include "base/memory/weak_ptr.h" |
52 | 52 |
53 namespace base { | 53 namespace base { |
54 | 54 |
55 template <typename Sig> | 55 template <typename Sig> |
56 class CancelableCallback; | 56 class CancelableCallback; |
57 | 57 |
58 template <> | 58 template <typename... A> |
59 class CancelableCallback<void(void)> { | 59 class CancelableCallback<void(A...)> { |
60 public: | 60 public: |
61 CancelableCallback() : weak_factory_(this) {} | 61 CancelableCallback() : weak_factory_(this) {} |
62 | 62 |
63 // |callback| must not be null. | 63 // |callback| must not be null. |
64 explicit CancelableCallback(const base::Callback<void(void)>& callback) | 64 explicit CancelableCallback(const base::Callback<void(A...)>& callback) |
65 : weak_factory_(this), | 65 : weak_factory_(this), |
66 callback_(callback) { | 66 callback_(callback) { |
67 DCHECK(!callback.is_null()); | 67 DCHECK(!callback.is_null()); |
68 InitializeForwarder(); | 68 InitializeForwarder(); |
69 } | 69 } |
70 | 70 |
71 ~CancelableCallback() {} | 71 ~CancelableCallback() {} |
72 | 72 |
73 // Cancels and drops the reference to the wrapped callback. | 73 // Cancels and drops the reference to the wrapped callback. |
74 void Cancel() { | 74 void Cancel() { |
75 weak_factory_.InvalidateWeakPtrs(); | 75 weak_factory_.InvalidateWeakPtrs(); |
76 forwarder_.Reset(); | 76 forwarder_.Reset(); |
77 callback_.Reset(); | 77 callback_.Reset(); |
78 } | 78 } |
79 | 79 |
80 // Returns true if the wrapped callback has been cancelled. | 80 // Returns true if the wrapped callback has been cancelled. |
81 bool IsCancelled() const { | 81 bool IsCancelled() const { |
82 return callback_.is_null(); | 82 return callback_.is_null(); |
83 } | 83 } |
84 | 84 |
85 // Sets |callback| as the closure that may be cancelled. |callback| may not | 85 // Sets |callback| as the closure that may be cancelled. |callback| may not |
86 // be null. Outstanding and any previously wrapped callbacks are cancelled. | 86 // be null. Outstanding and any previously wrapped callbacks are cancelled. |
87 void Reset(const base::Callback<void(void)>& callback) { | 87 void Reset(const base::Callback<void(A...)>& callback) { |
88 DCHECK(!callback.is_null()); | 88 DCHECK(!callback.is_null()); |
89 | 89 |
90 // Outstanding tasks (e.g., posted to a message loop) must not be called. | 90 // Outstanding tasks (e.g., posted to a message loop) must not be called. |
91 Cancel(); | 91 Cancel(); |
92 | 92 |
93 // |forwarder_| is no longer valid after Cancel(), so re-bind. | 93 // |forwarder_| is no longer valid after Cancel(), so re-bind. |
94 InitializeForwarder(); | 94 InitializeForwarder(); |
95 | 95 |
96 callback_ = callback; | 96 callback_ = callback; |
97 } | 97 } |
98 | 98 |
99 // Returns a callback that can be disabled by calling Cancel(). | 99 // Returns a callback that can be disabled by calling Cancel(). |
100 const base::Callback<void(void)>& callback() const { | 100 const base::Callback<void(A...)>& callback() const { |
101 return forwarder_; | 101 return forwarder_; |
102 } | 102 } |
103 | 103 |
104 private: | 104 private: |
105 void Forward() { | 105 void Forward(A... args) const { |
106 callback_.Run(); | 106 callback_.Run(args...); |
107 } | 107 } |
108 | 108 |
109 // Helper method to bind |forwarder_| using a weak pointer from | 109 // Helper method to bind |forwarder_| using a weak pointer from |
110 // |weak_factory_|. | 110 // |weak_factory_|. |
111 void InitializeForwarder() { | 111 void InitializeForwarder() { |
112 forwarder_ = base::Bind(&CancelableCallback<void(void)>::Forward, | 112 forwarder_ = base::Bind(&CancelableCallback<void(A...)>::Forward, |
113 weak_factory_.GetWeakPtr()); | 113 weak_factory_.GetWeakPtr()); |
114 } | 114 } |
115 | 115 |
116 // Used to ensure Forward() is not run when this object is destroyed. | 116 // Used to ensure Forward() is not run when this object is destroyed. |
117 base::WeakPtrFactory<CancelableCallback<void(void)> > weak_factory_; | 117 // TODO(ckehoe): This should be the last class member. |
| 118 // Move it there when crbug.com/433583 is fixed. |
| 119 base::WeakPtrFactory<CancelableCallback<void(A...)> > weak_factory_; |
118 | 120 |
119 // The wrapper closure. | 121 // The wrapper closure. |
120 base::Callback<void(void)> forwarder_; | 122 base::Callback<void(A...)> forwarder_; |
121 | 123 |
122 // The stored closure that may be cancelled. | 124 // The stored closure that may be cancelled. |
123 base::Callback<void(void)> callback_; | 125 base::Callback<void(A...)> callback_; |
124 | 126 |
125 DISALLOW_COPY_AND_ASSIGN(CancelableCallback); | 127 DISALLOW_COPY_AND_ASSIGN(CancelableCallback); |
126 }; | 128 }; |
127 | 129 |
128 template <typename A1> | |
129 class CancelableCallback<void(A1)> { | |
130 public: | |
131 CancelableCallback() : weak_factory_(this) {} | |
132 | |
133 // |callback| must not be null. | |
134 explicit CancelableCallback(const base::Callback<void(A1)>& callback) | |
135 : weak_factory_(this), | |
136 callback_(callback) { | |
137 DCHECK(!callback.is_null()); | |
138 InitializeForwarder(); | |
139 } | |
140 | |
141 ~CancelableCallback() {} | |
142 | |
143 // Cancels and drops the reference to the wrapped callback. | |
144 void Cancel() { | |
145 weak_factory_.InvalidateWeakPtrs(); | |
146 forwarder_.Reset(); | |
147 callback_.Reset(); | |
148 } | |
149 | |
150 // Returns true if the wrapped callback has been cancelled. | |
151 bool IsCancelled() const { | |
152 return callback_.is_null(); | |
153 } | |
154 | |
155 // Sets |callback| as the closure that may be cancelled. |callback| may not | |
156 // be null. Outstanding and any previously wrapped callbacks are cancelled. | |
157 void Reset(const base::Callback<void(A1)>& callback) { | |
158 DCHECK(!callback.is_null()); | |
159 | |
160 // Outstanding tasks (e.g., posted to a message loop) must not be called. | |
161 Cancel(); | |
162 | |
163 // |forwarder_| is no longer valid after Cancel(), so re-bind. | |
164 InitializeForwarder(); | |
165 | |
166 callback_ = callback; | |
167 } | |
168 | |
169 // Returns a callback that can be disabled by calling Cancel(). | |
170 const base::Callback<void(A1)>& callback() const { | |
171 return forwarder_; | |
172 } | |
173 | |
174 private: | |
175 void Forward(A1 a1) const { | |
176 callback_.Run(a1); | |
177 } | |
178 | |
179 // Helper method to bind |forwarder_| using a weak pointer from | |
180 // |weak_factory_|. | |
181 void InitializeForwarder() { | |
182 forwarder_ = base::Bind(&CancelableCallback<void(A1)>::Forward, | |
183 weak_factory_.GetWeakPtr()); | |
184 } | |
185 | |
186 // Used to ensure Forward() is not run when this object is destroyed. | |
187 base::WeakPtrFactory<CancelableCallback<void(A1)> > weak_factory_; | |
188 | |
189 // The wrapper closure. | |
190 base::Callback<void(A1)> forwarder_; | |
191 | |
192 // The stored closure that may be cancelled. | |
193 base::Callback<void(A1)> callback_; | |
194 | |
195 DISALLOW_COPY_AND_ASSIGN(CancelableCallback); | |
196 }; | |
197 | |
198 template <typename A1, typename A2> | |
199 class CancelableCallback<void(A1, A2)> { | |
200 public: | |
201 CancelableCallback() : weak_factory_(this) {} | |
202 | |
203 // |callback| must not be null. | |
204 explicit CancelableCallback(const base::Callback<void(A1, A2)>& callback) | |
205 : weak_factory_(this), | |
206 callback_(callback) { | |
207 DCHECK(!callback.is_null()); | |
208 InitializeForwarder(); | |
209 } | |
210 | |
211 ~CancelableCallback() {} | |
212 | |
213 // Cancels and drops the reference to the wrapped callback. | |
214 void Cancel() { | |
215 weak_factory_.InvalidateWeakPtrs(); | |
216 forwarder_.Reset(); | |
217 callback_.Reset(); | |
218 } | |
219 | |
220 // Returns true if the wrapped callback has been cancelled. | |
221 bool IsCancelled() const { | |
222 return callback_.is_null(); | |
223 } | |
224 | |
225 // Sets |callback| as the closure that may be cancelled. |callback| may not | |
226 // be null. Outstanding and any previously wrapped callbacks are cancelled. | |
227 void Reset(const base::Callback<void(A1, A2)>& callback) { | |
228 DCHECK(!callback.is_null()); | |
229 | |
230 // Outstanding tasks (e.g., posted to a message loop) must not be called. | |
231 Cancel(); | |
232 | |
233 // |forwarder_| is no longer valid after Cancel(), so re-bind. | |
234 InitializeForwarder(); | |
235 | |
236 callback_ = callback; | |
237 } | |
238 | |
239 // Returns a callback that can be disabled by calling Cancel(). | |
240 const base::Callback<void(A1, A2)>& callback() const { | |
241 return forwarder_; | |
242 } | |
243 | |
244 private: | |
245 void Forward(A1 a1, A2 a2) const { | |
246 callback_.Run(a1, a2); | |
247 } | |
248 | |
249 // Helper method to bind |forwarder_| using a weak pointer from | |
250 // |weak_factory_|. | |
251 void InitializeForwarder() { | |
252 forwarder_ = base::Bind(&CancelableCallback<void(A1, A2)>::Forward, | |
253 weak_factory_.GetWeakPtr()); | |
254 } | |
255 | |
256 // The wrapper closure. | |
257 base::Callback<void(A1, A2)> forwarder_; | |
258 | |
259 // The stored closure that may be cancelled. | |
260 base::Callback<void(A1, A2)> callback_; | |
261 | |
262 // Used to ensure Forward() is not run when this object is destroyed. | |
263 base::WeakPtrFactory<CancelableCallback<void(A1, A2)> > weak_factory_; | |
264 DISALLOW_COPY_AND_ASSIGN(CancelableCallback); | |
265 }; | |
266 | |
267 typedef CancelableCallback<void(void)> CancelableClosure; | 130 typedef CancelableCallback<void(void)> CancelableClosure; |
268 | 131 |
269 } // namespace base | 132 } // namespace base |
270 | 133 |
271 #endif // BASE_CANCELABLE_CALLBACK_H_ | 134 #endif // BASE_CANCELABLE_CALLBACK_H_ |
OLD | NEW |