chore: support converting OnceCallback to V8 (#17941)
This commit is contained in:
parent
93d9dafacc
commit
3142d5ca00
5 changed files with 103 additions and 18 deletions
|
@ -35,7 +35,6 @@
|
|||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/mouse_util.h"
|
||||
#include "atom/common/native_mate_converters/blink_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
|
@ -43,6 +42,7 @@
|
|||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/network_converter.h"
|
||||
#include "atom/common/native_mate_converters/once_callback.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/api/locker.h"
|
||||
|
@ -54,7 +55,8 @@ struct V8FunctionInvoker<v8::Local<v8::Value>(ArgTypes...)> {
|
|||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{ConvertToV8(isolate, raw)...};
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
v8::MaybeLocal<v8::Value> ret = holder->Call(
|
||||
context, holder, args.size(), args.empty() ? nullptr : &args.front());
|
||||
if (ret.IsEmpty())
|
||||
|
@ -78,7 +80,8 @@ struct V8FunctionInvoker<void(ArgTypes...)> {
|
|||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{ConvertToV8(isolate, raw)...};
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
holder
|
||||
->Call(context, holder, args.size(),
|
||||
args.empty() ? nullptr : &args.front())
|
||||
|
@ -101,7 +104,8 @@ struct V8FunctionInvoker<ReturnType(ArgTypes...)> {
|
|||
v8::Local<v8::Function> holder = function.NewHandle(isolate);
|
||||
v8::Local<v8::Context> context = holder->CreationContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
std::vector<v8::Local<v8::Value>> args{ConvertToV8(isolate, raw)...};
|
||||
std::vector<v8::Local<v8::Value>> args{
|
||||
ConvertToV8(isolate, std::forward<ArgTypes>(raw))...};
|
||||
v8::Local<v8::Value> result;
|
||||
auto maybe_result = holder->Call(context, holder, args.size(),
|
||||
args.empty() ? nullptr : &args.front());
|
||||
|
@ -138,20 +142,6 @@ struct NativeFunctionInvoker<ReturnType(ArgTypes...)> {
|
|||
|
||||
} // namespace internal
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::OnceCallback<Sig>> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::OnceCallback<Sig>* out) {
|
||||
if (!val->IsFunction())
|
||||
return false;
|
||||
|
||||
*out = base::BindOnce(&internal::V8FunctionInvoker<Sig>::Go, isolate,
|
||||
internal::SafeV8Function(isolate, val));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::RepeatingCallback<Sig>> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
|
|
87
atom/common/native_mate_converters/once_callback.h
Normal file
87
atom/common/native_mate_converters/once_callback.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2019 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_
|
||||
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Manages the OnceCallback with ref-couting.
|
||||
template <typename Sig>
|
||||
class RefCountedOnceCallback
|
||||
: public base::RefCounted<RefCountedOnceCallback<Sig>> {
|
||||
public:
|
||||
explicit RefCountedOnceCallback(base::OnceCallback<Sig> callback)
|
||||
: callback_(std::move(callback)) {}
|
||||
|
||||
base::OnceCallback<Sig> GetCallback() { return std::move(callback_); }
|
||||
|
||||
private:
|
||||
friend class base::RefCounted<RefCountedOnceCallback<Sig>>;
|
||||
~RefCountedOnceCallback() = default;
|
||||
|
||||
base::OnceCallback<Sig> callback_;
|
||||
};
|
||||
|
||||
// Invokes the OnceCallback.
|
||||
template <typename Sig>
|
||||
struct InvokeOnceCallback {};
|
||||
|
||||
template <typename... ArgTypes>
|
||||
struct InvokeOnceCallback<void(ArgTypes...)> {
|
||||
static void Go(
|
||||
scoped_refptr<RefCountedOnceCallback<void(ArgTypes...)>> holder,
|
||||
ArgTypes... args) {
|
||||
base::OnceCallback<void(ArgTypes...)> callback = holder->GetCallback();
|
||||
DCHECK(!callback.is_null());
|
||||
std::move(callback).Run(std::move(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ReturnType, typename... ArgTypes>
|
||||
struct InvokeOnceCallback<ReturnType(ArgTypes...)> {
|
||||
static ReturnType Go(
|
||||
scoped_refptr<RefCountedOnceCallback<ReturnType(ArgTypes...)>> holder,
|
||||
ArgTypes... args) {
|
||||
base::OnceCallback<void(ArgTypes...)> callback = holder->GetCallback();
|
||||
DCHECK(!callback.is_null());
|
||||
return std::move(callback).Run(std::move(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename Sig>
|
||||
struct Converter<base::OnceCallback<Sig>> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
base::OnceCallback<Sig> val) {
|
||||
// Reuse the converter of base::RepeatingCallback by storing the callback
|
||||
// with a RefCounted.
|
||||
auto holder = base::MakeRefCounted<internal::RefCountedOnceCallback<Sig>>(
|
||||
std::move(val));
|
||||
return Converter<base::RepeatingCallback<Sig>>::ToV8(
|
||||
isolate,
|
||||
base::BindRepeating(&internal::InvokeOnceCallback<Sig>::Go, holder));
|
||||
}
|
||||
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::OnceCallback<Sig>* out) {
|
||||
if (!val->IsFunction())
|
||||
return false;
|
||||
*out = base::BindOnce(&internal::V8FunctionInvoker<Sig>::Go, isolate,
|
||||
internal::SafeV8Function(isolate, val));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_
|
|
@ -631,6 +631,7 @@ filenames = {
|
|||
"atom/common/native_mate_converters/net_converter.h",
|
||||
"atom/common/native_mate_converters/network_converter.cc",
|
||||
"atom/common/native_mate_converters/network_converter.h",
|
||||
"atom/common/native_mate_converters/once_callback.h",
|
||||
"atom/common/native_mate_converters/string16_converter.h",
|
||||
"atom/common/native_mate_converters/ui_base_types_converter.h",
|
||||
"atom/common/native_mate_converters/v8_value_converter.cc",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "base/strings/string_piece.h"
|
||||
|
@ -304,6 +305,12 @@ v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, const T& input) {
|
|||
return Converter<T>::ToV8(isolate, input);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, T&& input) {
|
||||
return Converter<typename std::remove_reference<T>::type>::ToV8(
|
||||
isolate, std::move(input));
|
||||
}
|
||||
|
||||
inline v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate,
|
||||
const char* input) {
|
||||
return Converter<const char*>::ToV8(isolate, input);
|
||||
|
|
Loading…
Reference in a new issue