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