Chromium Code Reviews| 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 |