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.
5 #ifndef MEDIA_BASE_CALLBACK_HOLDER_H_
6 #define MEDIA_BASE_CALLBACK_HOLDER_H_
9 #include "base/callback.h"
10 #include "base/callback_helpers.h"
11 #include "media/base/bind_to_loop.h"
15 // A helper class that can hold a callback from being fired.
16 template <typename CB
> class CallbackHolder
{
18 CallbackHolder() : hold_(false) {}
21 // Make sure all callbacks are satisfied!
23 DCHECK(original_cb_
.is_null());
24 DCHECK(held_cb_
.is_null());
27 // Sets the callback to be potentially held.
28 void SetCallback(const CB
& cb
) {
29 DCHECK(original_cb_
.is_null());
30 DCHECK(held_cb_
.is_null());
35 return original_cb_
.is_null() && held_cb_
.is_null();
38 // Holds the callback when Run() is called.
39 void HoldCallback() { hold_
= true; }
41 // Runs or holds the callback as specified by |hold_|.
42 // This method has overloaded versions to support different types of CB.
44 DCHECK(held_cb_
.is_null());
46 held_cb_
= base::ResetAndReturn(&original_cb_
);
48 base::ResetAndReturn(&original_cb_
).Run();
51 template <typename A1
> void RunOrHold(A1 a1
) {
52 DCHECK(held_cb_
.is_null());
54 held_cb_
= base::Bind(base::ResetAndReturn(&original_cb_
),
55 internal::TrampolineForward(a1
));
57 base::ResetAndReturn(&original_cb_
).Run(a1
);
61 template <typename A1
, typename A2
> void RunOrHold(A1 a1
, A2 a2
) {
62 DCHECK(held_cb_
.is_null());
64 held_cb_
= base::Bind(base::ResetAndReturn(&original_cb_
),
65 internal::TrampolineForward(a1
),
66 internal::TrampolineForward(a2
));
68 base::ResetAndReturn(&original_cb_
).Run(a1
, a2
);
72 // Releases and runs the held callback.
73 void RunHeldCallback() {
75 DCHECK(!held_cb_
.is_null());
77 base::ResetAndReturn(&held_cb_
).Run();
83 base::Closure held_cb_
;
88 #endif // MEDIA_BASE_CALLBACK_HOLDER_H_