|
5 | 5 | #pragma once
|
6 | 6 |
|
7 | 7 | #include "HybridObject.h"
|
| 8 | +#include <array> |
8 | 9 | #include <jsi/jsi.h>
|
9 | 10 | #include <memory>
|
10 | 11 | #include <type_traits>
|
11 | 12 | #include <unordered_map>
|
12 |
| -#include <array> |
13 | 13 |
|
14 | 14 | namespace margelo {
|
15 | 15 |
|
@@ -84,52 +84,61 @@ template <> struct JSIConverter<std::string> {
|
84 | 84 | };
|
85 | 85 |
|
86 | 86 | template <typename TInner> struct JSIConverter<std::optional<TInner>> {
|
87 |
| - static std::optional<TInner> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { |
88 |
| - if (arg.isUndefined() || arg.isNull()) { |
89 |
| - return std::nullopt; |
90 |
| - } else { |
91 |
| - return JSIConverter<TInner>::fromJSI(runtime, std::move(arg)); |
92 |
| - } |
| 87 | + static std::optional<TInner> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { |
| 88 | + if (arg.isUndefined() || arg.isNull()) { |
| 89 | + return std::nullopt; |
| 90 | + } else { |
| 91 | + return JSIConverter<TInner>::fromJSI(runtime, std::move(arg)); |
93 | 92 | }
|
94 |
| - static jsi::Value toJSI(jsi::Runtime& runtime, std::optional<TInner> arg) { |
95 |
| - if (arg == std::nullopt) { |
96 |
| - return jsi::Value::undefined(); |
97 |
| - } else { |
98 |
| - return JSIConverter<TInner>::toJSI(runtime, arg); |
99 |
| - } |
| 93 | + } |
| 94 | + static jsi::Value toJSI(jsi::Runtime& runtime, std::optional<TInner> arg) { |
| 95 | + if (arg == std::nullopt) { |
| 96 | + return jsi::Value::undefined(); |
| 97 | + } else { |
| 98 | + return JSIConverter<TInner>::toJSI(runtime, arg); |
100 | 99 | }
|
| 100 | + } |
101 | 101 | };
|
102 | 102 |
|
103 |
| -template <typename ReturnType, typename... Args> |
104 |
| -struct JSIConverter<std::function<ReturnType(Args...)>> { |
105 |
| - static std::function<ReturnType(Args...)> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { |
106 |
| - jsi::Function function = arg.asObject(runtime).asFunction(runtime); |
107 |
| - std::shared_ptr<jsi::Function> sharedFunction = std::make_shared<jsi::Function>(std::move(function)); |
108 |
| - return [&runtime, sharedFunction] (Args... args) -> ReturnType { |
109 |
| - jsi::Value result = sharedFunction->call(runtime, JSIConverter<Args>::toJSI(runtime, args)...); |
110 |
| - if constexpr (std::is_same_v<ReturnType, void>) { |
111 |
| - return; |
112 |
| - } else { |
113 |
| - return JSIConverter<ReturnType>::fromJSI(runtime, std::move(result)); |
114 |
| - } |
115 |
| - }; |
116 |
| - } |
117 |
| - |
118 |
| - /*template<size_t... Is> |
119 |
| - static jsi::Value callHybridFunction(const std::function<ReturnType(Args...)>& function, jsi::Runtime& runtime, const jsi::Value* args, std::index_sequence<Is...>) { |
120 |
| - ReturnType result = function(JSIConverter<Args>::fromJSI(runtime, args[Is])...); |
121 |
| - return JSIConverter<ReturnType>::toJSI(runtime, result); |
122 |
| - }*/ |
123 |
| - static jsi::Value toJSI(jsi::Runtime& runtime, std::function<ReturnType(Args...)> function) { |
124 |
| - return jsi::Value::undefined(); |
125 |
| - /*jsi::HostFunctionType jsFunction = [function = std::move(function)] (jsi::Runtime& runtime, |
126 |
| - const jsi::Value& thisValue, |
127 |
| - const jsi::Value* args, |
128 |
| - size_t count) -> jsi::Value { |
129 |
| - callHybridFunction(function, runtime, args, std::index_sequence_for<Args...>{}); |
130 |
| - }; |
131 |
| - return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "hostFunction"), sizeof...(Args), jsFunction);*/ |
| 103 | +template <typename ReturnType, typename... Args> struct JSIConverter<std::function<ReturnType(Args...)>> { |
| 104 | + static std::function<ReturnType(Args...)> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { |
| 105 | + jsi::Function function = arg.asObject(runtime).asFunction(runtime); |
| 106 | + std::shared_ptr<jsi::Function> sharedFunction = std::make_shared<jsi::Function>(std::move(function)); |
| 107 | + return [&runtime, sharedFunction](Args... args) -> ReturnType { |
| 108 | + jsi::Value result = sharedFunction->call(runtime, JSIConverter<Args>::toJSI(runtime, args)...); |
| 109 | + if constexpr (std::is_same_v<ReturnType, void>) { |
| 110 | + // it is a void function (returns undefined) |
| 111 | + return; |
| 112 | + } else { |
| 113 | + // it returns a custom type, parse it from the JSI value. |
| 114 | + return JSIConverter<ReturnType>::fromJSI(runtime, std::move(result)); |
| 115 | + } |
| 116 | + }; |
| 117 | + } |
| 118 | + |
| 119 | + template <size_t... Is> |
| 120 | + static jsi::Value callHybridFunction(const std::function<ReturnType(Args...)>& function, jsi::Runtime& runtime, const jsi::Value* args, |
| 121 | + std::index_sequence<Is...>) { |
| 122 | + if constexpr (std::is_same_v<ReturnType, void>) { |
| 123 | + function(JSIConverter<Args>::fromJSI(runtime, args[Is])...); |
| 124 | + return jsi::Value::undefined(); |
| 125 | + } else { |
| 126 | + ReturnType result = function(JSIConverter<Args>::fromJSI(runtime, args[Is])...); |
| 127 | + return JSIConverter<ReturnType>::toJSI(runtime, result); |
132 | 128 | }
|
| 129 | + } |
| 130 | + static jsi::Value toJSI(jsi::Runtime& runtime, std::function<ReturnType(Args...)> function) { |
| 131 | + jsi::HostFunctionType jsFunction = [function = std::move(function)](jsi::Runtime& runtime, const jsi::Value& thisValue, |
| 132 | + const jsi::Value* args, size_t count) -> jsi::Value { |
| 133 | + if (count != sizeof...(Args)) { |
| 134 | + [[unlikely]]; |
| 135 | + throw jsi::JSError(runtime, "Function expected " + std::to_string(sizeof...(Args)) + " arguments, but received " + |
| 136 | + std::to_string(count) + "!"); |
| 137 | + } |
| 138 | + return callHybridFunction(function, runtime, args, std::index_sequence_for<Args...>{}); |
| 139 | + }; |
| 140 | + return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "hostFunction"), sizeof...(Args), jsFunction); |
| 141 | + } |
133 | 142 | };
|
134 | 143 |
|
135 | 144 | template <typename ElementType> struct JSIConverter<std::vector<ElementType>> {
|
|
0 commit comments