chore: support converting OnceCallback to V8 (#17941)

This commit is contained in:
Cheng Zhao 2019-04-25 09:40:27 +09:00 committed by GitHub
parent 93d9dafacc
commit 3142d5ca00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 18 deletions

View file

@ -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"

View file

@ -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,

View 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_

View file

@ -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",

View file

@ -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);