/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include namespace facebook::react::bridging { template JSReturnT callFromJs( jsi::Runtime &rt, ReturnT (ClassT::*method)(jsi::Runtime &, ArgsT...), const std::shared_ptr &jsInvoker, ClassT *instance, JSArgsT &&...args) { static_assert(sizeof...(ArgsT) == sizeof...(JSArgsT), "Incorrect arguments length"); static_assert((supportsFromJs && ...), "Incompatible arguments"); if constexpr (std::is_void_v) { static_assert(std::is_void_v, "Method must return void when JSReturnT is void"); } if constexpr (std::is_void_v) { (instance->*method)(rt, fromJs(rt, std::forward(args), jsInvoker)...); } else if constexpr (std::is_void_v) { static_assert(std::is_same_v, "Void functions may only return undefined"); (instance->*method)(rt, fromJs(rt, std::forward(args), jsInvoker)...); return jsi::Value(); } else if constexpr (is_jsi_v || supportsToJs) { static_assert(supportsToJs, "Incompatible return type"); return toJs(rt, (instance->*method)(rt, fromJs(rt, std::forward(args), jsInvoker)...), jsInvoker); } else if constexpr (is_optional_jsi_v) { static_assert( is_optional_v ? supportsToJs : supportsToJs, "Incompatible return type"); auto result = toJs(rt, (instance->*method)(rt, fromJs(rt, std::forward(args), jsInvoker)...), jsInvoker); if constexpr (std::is_same_v) { if (result.isNull() || result.isUndefined()) { return std::nullopt; } } return convert(rt, std::move(result)); } else { static_assert(std::is_convertible_v, "Incompatible return type"); return (instance->*method)(rt, fromJs(rt, std::forward(args), jsInvoker)...); } } template constexpr size_t getParameterCount(ReturnT (* /*unused*/)(ArgsT...)) { return sizeof...(ArgsT); } template constexpr size_t getParameterCount(ReturnT (Class::* /*unused*/)(ArgsT...)) { return sizeof...(ArgsT); } } // namespace facebook::react::bridging