Skip to content

Commit 644383f

Browse files
committed
fix: Fix JSIConverter<function>::fromJSI (2/2)
1 parent 2797b91 commit 644383f

File tree

2 files changed

+65
-54
lines changed

2 files changed

+65
-54
lines changed

package/cpp/jsi/JSIConverter.h

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
#pragma once
66

77
#include "HybridObject.h"
8+
#include <array>
89
#include <jsi/jsi.h>
910
#include <memory>
1011
#include <type_traits>
1112
#include <unordered_map>
12-
#include <array>
1313

1414
namespace margelo {
1515

@@ -84,52 +84,61 @@ template <> struct JSIConverter<std::string> {
8484
};
8585

8686
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));
9392
}
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);
10099
}
100+
}
101101
};
102102

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);
132128
}
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+
}
133142
};
134143

135144
template <typename ElementType> struct JSIConverter<std::vector<ElementType>> {

package/cpp/test/TestHybridObject.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,25 @@ namespace margelo {
1212

1313
class TestHybridObject : public HybridObject {
1414
public:
15-
int getInt() { return _int; }
16-
void setInt(int newValue) { _int = newValue; }
17-
std::string getString() { return _string; }
18-
void setString(std::string newValue) { _string = newValue; }
15+
int getInt() {
16+
return _int;
17+
}
18+
void setInt(int newValue) {
19+
_int = newValue;
20+
}
21+
std::string getString() {
22+
return _string;
23+
}
24+
void setString(std::string newValue) {
25+
_string = newValue;
26+
}
1927

2028
std::unordered_map<std::string, double> multipleArguments(int first, bool second, std::string third) {
21-
return std::unordered_map<std::string, double> {
22-
{"first", 5312},
23-
{"second", 532233},
24-
{"third", 2786}
25-
};
29+
return std::unordered_map<std::string, double>{{"first", 5312}, {"second", 532233}, {"third", 2786}};
2630
}
2731

2832
std::function<int()> getIntGetter() {
29-
return [this]() -> int {
30-
return this->_int;
31-
};
33+
return [this]() -> int { return this->_int; };
3234
}
3335
void sayHelloCallback(std::function<void(std::string)> callback) {
3436
callback("Test Hybrid");

0 commit comments

Comments
 (0)