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