blob: 91f37d03fef390fe904a3c93475fb28b7a5085e2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
#define MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
#include <type_traits>
#include <utility>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "mojo/public/cpp/bindings/lib/callback_internal.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
namespace mojo {
template <typename Sig>
class Callback;
// Represents a callback with any number of parameters and no return value. The
// callback is executed by calling its Run() method. The callback may be "null",
// meaning it does nothing.
template <typename... Args>
class Callback<void(Args...)> {
public:
// An interface that may be implemented to define the Run() method.
struct Runnable {
virtual ~Runnable() {}
virtual void Run(
// ForwardType ensures String is passed as a const reference. Can't use
// universal refs (Args&&) here since this method itself isn't templated
// because it is a virtual interface. So we have to take the arguments
// all by value (except String which we take as a const reference due to
// ForwardType).
typename internal::Callback_ParamTraits<Args>::ForwardType...) = 0;
};
// Constructs a "null" callback that does nothing.
Callback() {}
// Constructs a callback that will run |runnable|. The callback takes
// ownership of |runnable|.
explicit Callback(Runnable* runnable) : sink_(new RunnableHolder(runnable)) {}
// As above, but can take an object that isn't derived from Runnable, so long
// as it has a compatible operator() or Run() method. operator() will be
// preferred if the type has both.
//
// The std::enable_if is used to disable this constructor if the argument is
// derived from Runnable. This is needed because the compiler will pick this
// constructor instead of the Runnable* one above when the argument is of the
// type of the derived class instead of down casted to a Runnable. i.e:
// class Foo : public Callback::Runnable {
// ...
// };
// Callback cb(new Foo);
//
// The call site can fix this by using a static_cast to down cast to a
// Runnable*, but that shouldn't be necessary.
template <
typename Sink,
typename std::enable_if<!std::is_base_of<
Runnable,
typename std::remove_pointer<Sink>::type>::value>::type* = nullptr>
Callback(const Sink& sink) {
using sink_type = typename internal::Conditional<
internal::HasCompatibleCallOperator<Sink, Args...>::value,
FunctorAdapter<Sink>, RunnableAdapter<Sink>>::type;
sink_ = new RunnableHolder(new sink_type(sink));
}
// As above, but can take a compatible function pointer.
Callback(void (*function_ptr)(
typename internal::Callback_ParamTraits<Args>::ForwardType...))
: sink_(new RunnableHolder(new FunctionPtrAdapter(function_ptr))) {}
// Executes the callback function.
void Run(typename internal::Callback_ParamTraits<Args>::ForwardType... args)
const {
if (sink_)
sink_->runnable->Run(std::forward<
typename internal::Callback_ParamTraits<Args>::ForwardType>(
args)...);
}
bool is_null() const { return !sink_.get(); }
// Resets the callback to the "null" state.
void reset() { sink_ = nullptr; }
private:
// Adapts a class that has a Run() method but is not derived from Runnable to
// be callable by Callback.
template <typename Sink>
struct RunnableAdapter : public Runnable {
explicit RunnableAdapter(const Sink& sink) : sink(sink) {}
virtual void Run(
typename internal::Callback_ParamTraits<Args>::ForwardType... args)
override {
sink.Run(std::forward<
typename internal::Callback_ParamTraits<Args>::ForwardType>(
args)...);
}
Sink sink;
};
// Adapts a class that has a compatible operator() to be callable by Callback.
template <typename Sink>
struct FunctorAdapter : public Runnable {
explicit FunctorAdapter(const Sink& sink) : sink(sink) {}
virtual void Run(
typename internal::Callback_ParamTraits<Args>::ForwardType... args)
override {
sink.operator()(
std::forward<
typename internal::Callback_ParamTraits<Args>::ForwardType>(
args)...);
}
Sink sink;
};
// Adapts a function pointer.
struct FunctionPtrAdapter : public Runnable {
private:
using FunctionPtr =
void (*)(typename internal::Callback_ParamTraits<Args>::ForwardType...);
public:
explicit FunctionPtrAdapter(FunctionPtr function_ptr)
: function_ptr(function_ptr) {}
virtual void Run(
typename internal::Callback_ParamTraits<Args>::ForwardType... args)
override {
(*function_ptr)(
std::forward<
typename internal::Callback_ParamTraits<Args>::ForwardType>(
args)...);
}
FunctionPtr function_ptr;
};
struct RunnableHolder : public base::RefCountedThreadSafe<RunnableHolder> {
explicit RunnableHolder(Runnable* runnable) : runnable(runnable) {}
scoped_ptr<Runnable> runnable;
private:
friend class base::RefCountedThreadSafe<RunnableHolder>;
~RunnableHolder() {}
};
scoped_refptr<RunnableHolder> sink_;
};
// A specialization of Callback which takes no parameters.
typedef Callback<void()> Closure;
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
|