-
Notifications
You must be signed in to change notification settings - Fork 1
/
_JsiBridge.mm
107 lines (84 loc) · 4.49 KB
/
_JsiBridge.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#import "_JsiBridge.h"
#import <React/RCTBridge+Private.h>
#import <ReactCommon/RCTTurboModule.h>
#import <jsi/jsi.h>
#import "JsiBridgeEmitter.mm"
#include "iostream"
#include "map"
using namespace facebook;
jsi::Value convertNSStringToJSIString(jsi::Runtime &runtime, NSString *value)
{
return jsi::String::createFromUtf8(runtime, [value UTF8String] ?: "");
}
@implementation JsiBridge
RCT_EXPORT_MODULE()
std::map<std::string, std::shared_ptr<facebook::jsi::Function>> callbacks;
RCTCxxBridge *_cxxBridge;
RCTBridge *_bridge;
jsi::Runtime *_runtime;
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) {
NSLog(@"Installing JsiBridge polyfill Bindings...");
_bridge = [RCTBridge currentBridge];
_cxxBridge = (RCTCxxBridge*)_bridge;
if (_cxxBridge == nil) return @false;
_runtime = (jsi::Runtime*) _cxxBridge.runtime;
if (_runtime == nil) return @false;
auto& runtime = *_runtime;
[JsiBridgeEmitter.shared registerJsiBridge:self];
auto registerCallback = jsi::Function::createFromHostFunction(runtime,
jsi::PropNameID::forUtf8(runtime, "registerCallback"),
2,
[](jsi::Runtime& runtime,
const jsi::Value& thisArg,
const jsi::Value* args,
size_t count) -> jsi::Value {
auto name = args[0].asString(runtime).utf8(runtime);
std::cout<<"😀addCallback " + name << std::endl;
auto callback = args[1].asObject(runtime).asFunction(runtime);
callbacks[name] = std::make_shared<jsi::Function>(std::move(callback));
return jsi::Value::undefined();
});
auto removeCallback = jsi::Function::createFromHostFunction(runtime,
jsi::PropNameID::forUtf8(runtime, "removeCallback"),
1,
[](jsi::Runtime& runtime,
const jsi::Value& thisArg,
const jsi::Value* args,
size_t count) -> jsi::Value {
auto name = args[0].asString(runtime).utf8(runtime);
std::cout<<"😀removecallback " + name << std::endl;
callbacks.erase(name);
return jsi::Value::undefined();
});
auto emit = jsi::Function::createFromHostFunction(runtime,
jsi::PropNameID::forUtf8(runtime, "emit"),
2,
[=](jsi::Runtime &runtime,
const jsi::Value &thisArg,
const jsi::Value *args,
size_t count) -> jsi::Value {
auto name = args[0].asString(runtime).utf8(runtime);
auto data = args[1].asString(runtime).utf8(runtime);
auto nameString = [NSString stringWithUTF8String:name.c_str()];
auto dataString = [NSString stringWithUTF8String:data.c_str()];
[JsiBridgeEmitter.shared emitNative:nameString with:dataString];
return jsi::Value::undefined();
});
jsi::Object _jsiBridge = jsi::Object(runtime);
_jsiBridge.setProperty(runtime, "registerCallback", std::move(registerCallback));
_jsiBridge.setProperty(runtime, "removeCallback", std::move(removeCallback));
_jsiBridge.setProperty(runtime, "emit", std::move(emit));
runtime.global().setProperty(runtime, "_JsiBridge", std::move(_jsiBridge));
return @true;
}
- (void)emitJs:(NSString *)name with:(NSString *)data {
auto stdName = [name UTF8String];
if (callbacks.find(stdName) != callbacks.end()) {
auto& runtime = *_runtime;
_bridge.jsCallInvoker->invokeAsync([&runtime, n = stdName, d = data] () {
auto dd = convertNSStringToJSIString(runtime, d);
callbacks[n]->call(runtime, dd);
});
}
}
@end