2019-04-25 00:40:27 +00:00
|
|
|
// 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.
|
|
|
|
|
2019-06-19 20:56:58 +00:00
|
|
|
#ifndef SHELL_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_
|
|
|
|
#define SHELL_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_
|
2019-04-25 00:40:27 +00:00
|
|
|
|
|
|
|
#include <utility>
|
|
|
|
|
2019-06-19 20:46:59 +00:00
|
|
|
#include "shell/common/native_mate_converters/callback.h"
|
2019-04-25 00:40:27 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2019-06-19 20:56:58 +00:00
|
|
|
#endif // SHELL_COMMON_NATIVE_MATE_CONVERTERS_ONCE_CALLBACK_H_
|