Molybden API
Loading...
Searching...
No Matches
js_accessible_method_impl_detail.hpp
1// Copyright (c) 2000-2024 TeamDev. All rights reserved.
2// TeamDev PROPRIETARY and CONFIDENTIAL.
3// Use is subject to license terms.
4
5#ifndef MOLYBDEN_JS_ACCESSIBLE_METHOD_IMPL_DETAIL_HPP
6#define MOLYBDEN_JS_ACCESSIBLE_METHOD_IMPL_DETAIL_HPP
7
8#include "molybden/js/internal/js_value_converter.hpp"
9
10namespace molybden {
11namespace internal {
12
13template <class C, class R, class... T>
14JsAccessibleMethodImplBase<C, R, T...>::JsAccessibleMethodImplBase(
15 C* object,
16 MethodSignature<C, R, T...> method)
17 : object_(object), call_(method) {
18 AreAllConvertibleFromJsDirectly<R, T...>::check();
19}
20
21template <class C, class R, class... T>
22R JsAccessibleMethodImplBase<C, R, T...>::callInternal(T... args) {
23 return (object_->*call_)(args...);
24}
25
26template <class C, class R, class... T>
27template <std::size_t... I>
28JsReturnValue JsAccessibleMethodImplBase<C, R, T...>::checkedCall(
29 const std::vector<JsValue>& values,
30 index_sequence<I...>) {
31 if (sizeof...(T) != values.size()) {
32 return JsReturnValue(
33 JsError{std::to_string(values.size()) +
34 " arguments were provided to the C++ method, but " +
35 std::to_string(sizeof...(T)) + " are required."});
36 }
37 auto converter = internal::IndexedJsValueConverter<T...>(values);
38 std::vector<bool> convertible{converter.template isConvertible<I>()...};
39 for (int i = 0; i < convertible.size(); ++i) {
40 if (!convertible[i]) {
41 std::vector<std::string> arg_types{
42 converter.template convertErrorTypeInfo<I>()...};
43 return JsReturnValue(JsError{
44 std::string("exception: the ") + std::to_string(i + 1) +
45 "-th argument is not convertible to " + arg_types[i] + ".",
46 ExceptionType::kTypeError});
47 }
48 }
49 return JsReturnValue(wrappedCall(converter.template convert<I>()...));
50}
51
52template <class C, class R, class... T>
53JsReturnValue JsAccessibleMethodImplBase<C, R, T...>::call(
54 const std::vector<JsValue>& values) {
55 return checkedCall(values, index_sequence_for<T...>());
56}
57
58template <class C, class R, class... T>
59JsValue JsAccessibleMethodImpl<C, R, T...>::wrappedCall(T... args) {
60 return JsValue::from(
61 JsAccessibleMethodImplBase<C, R, T...>::callInternal(args...));
62}
63
64template <class C, class... T>
65JsValue JsAccessibleMethodImpl<C, void, T...>::wrappedCall(T... args) {
66 JsAccessibleMethodImplBase<C, void, T...>::callInternal(args...);
67 return {};
68}
69
70template <class C, class R, class... T>
71JsAccessibleMethodImpl<C, R, T...>::JsAccessibleMethodImpl(
72 C* object,
73 MethodSignature<C, R, T...> method)
74 : JsAccessibleMethodImplBase<C, R, T...>(object, method) {}
75
76template <class C, class... T>
77JsAccessibleMethodImpl<C, void, T...>::JsAccessibleMethodImpl(
78 C* object,
79 MethodSignature<C, void, T...> method)
80 : JsAccessibleMethodImplBase<C, void, T...>(object, method) {}
81
82} // namespace internal
83} // namespace molybden
84
85#endif // MOLYBDEN_JS_ACCESSIBLE_METHOD_IMPL_DETAIL_HPP