diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 434f40d8db..823ec723ff 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -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" diff --git a/atom/common/native_mate_converters/callback.h b/atom/common/native_mate_converters/callback.h index 6cf3504041..666f6bae03 100644 --- a/atom/common/native_mate_converters/callback.h +++ b/atom/common/native_mate_converters/callback.h @@ -5,6 +5,7 @@ #ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ +#include #include #include "atom/common/api/locker.h" @@ -54,7 +55,8 @@ struct V8FunctionInvoker(ArgTypes...)> { v8::Local holder = function.NewHandle(isolate); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); - std::vector> args{ConvertToV8(isolate, raw)...}; + std::vector> args{ + ConvertToV8(isolate, std::forward(raw))...}; v8::MaybeLocal ret = holder->Call( context, holder, args.size(), args.empty() ? nullptr : &args.front()); if (ret.IsEmpty()) @@ -78,7 +80,8 @@ struct V8FunctionInvoker { v8::Local holder = function.NewHandle(isolate); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); - std::vector> args{ConvertToV8(isolate, raw)...}; + std::vector> args{ + ConvertToV8(isolate, std::forward(raw))...}; holder ->Call(context, holder, args.size(), args.empty() ? nullptr : &args.front()) @@ -101,7 +104,8 @@ struct V8FunctionInvoker { v8::Local holder = function.NewHandle(isolate); v8::Local context = holder->CreationContext(); v8::Context::Scope context_scope(context); - std::vector> args{ConvertToV8(isolate, raw)...}; + std::vector> args{ + ConvertToV8(isolate, std::forward(raw))...}; v8::Local result; auto maybe_result = holder->Call(context, holder, args.size(), args.empty() ? nullptr : &args.front()); @@ -138,20 +142,6 @@ struct NativeFunctionInvoker { } // namespace internal -template -struct Converter> { - static bool FromV8(v8::Isolate* isolate, - v8::Local val, - base::OnceCallback* out) { - if (!val->IsFunction()) - return false; - - *out = base::BindOnce(&internal::V8FunctionInvoker::Go, isolate, - internal::SafeV8Function(isolate, val)); - return true; - } -}; - template struct Converter> { static v8::Local ToV8(v8::Isolate* isolate, diff --git a/atom/common/native_mate_converters/once_callback.h b/atom/common/native_mate_converters/once_callback.h new file mode 100644 index 0000000000..f0bc60fc34 --- /dev/null +++ b/atom/common/native_mate_converters/once_callback.h @@ -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 + +#include "atom/common/native_mate_converters/callback.h" + +namespace mate { + +namespace internal { + +// Manages the OnceCallback with ref-couting. +template +class RefCountedOnceCallback + : public base::RefCounted> { + public: + explicit RefCountedOnceCallback(base::OnceCallback callback) + : callback_(std::move(callback)) {} + + base::OnceCallback GetCallback() { return std::move(callback_); } + + private: + friend class base::RefCounted>; + ~RefCountedOnceCallback() = default; + + base::OnceCallback callback_; +}; + +// Invokes the OnceCallback. +template +struct InvokeOnceCallback {}; + +template +struct InvokeOnceCallback { + static void Go( + scoped_refptr> holder, + ArgTypes... args) { + base::OnceCallback callback = holder->GetCallback(); + DCHECK(!callback.is_null()); + std::move(callback).Run(std::move(args)...); + } +}; + +template +struct InvokeOnceCallback { + static ReturnType Go( + scoped_refptr> holder, + ArgTypes... args) { + base::OnceCallback callback = holder->GetCallback(); + DCHECK(!callback.is_null()); + return std::move(callback).Run(std::move(args)...); + } +}; + +} // namespace internal + +template +struct Converter> { + static v8::Local ToV8(v8::Isolate* isolate, + base::OnceCallback val) { + // Reuse the converter of base::RepeatingCallback by storing the callback + // with a RefCounted. + auto holder = base::MakeRefCounted>( + std::move(val)); + return Converter>::ToV8( + isolate, + base::BindRepeating(&internal::InvokeOnceCallback::Go, holder)); + } + + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + base::OnceCallback* out) { + if (!val->IsFunction()) + return false; + *out = base::BindOnce(&internal::V8FunctionInvoker::Go, isolate, + internal::SafeV8Function(isolate, val)); + return true; + } +}; + +} // namespace mate + +#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_ diff --git a/filenames.gni b/filenames.gni index 8c40a7e2d5..4d916217a5 100644 --- a/filenames.gni +++ b/filenames.gni @@ -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", diff --git a/native_mate/native_mate/converter.h b/native_mate/native_mate/converter.h index 0e167eca9d..58daa15aae 100644 --- a/native_mate/native_mate/converter.h +++ b/native_mate/native_mate/converter.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "base/strings/string_piece.h" @@ -304,6 +305,12 @@ v8::Local ConvertToV8(v8::Isolate* isolate, const T& input) { return Converter::ToV8(isolate, input); } +template +v8::Local ConvertToV8(v8::Isolate* isolate, T&& input) { + return Converter::type>::ToV8( + isolate, std::move(input)); +} + inline v8::Local ConvertToV8(v8::Isolate* isolate, const char* input) { return Converter::ToV8(isolate, input);