react-native-worklets 0.0.1-alpha → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Common/cpp/worklets/AnimationFrameQueue/AnimationFrameBatchinator.cpp +71 -0
- package/Common/cpp/worklets/AnimationFrameQueue/AnimationFrameBatchinator.h +38 -0
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +131 -0
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +82 -0
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.cpp +72 -0
- package/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.h +44 -0
- package/Common/cpp/worklets/Registries/EventHandlerRegistry.cpp +94 -0
- package/Common/cpp/worklets/Registries/EventHandlerRegistry.h +49 -0
- package/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.cpp +8 -0
- package/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.h +39 -0
- package/Common/cpp/worklets/SharedItems/Shareables.cpp +326 -0
- package/Common/cpp/worklets/SharedItems/Shareables.h +345 -0
- package/Common/cpp/worklets/Tools/AsyncQueue.cpp +52 -0
- package/Common/cpp/worklets/Tools/AsyncQueue.h +35 -0
- package/Common/cpp/worklets/Tools/Defs.h +10 -0
- package/Common/cpp/worklets/Tools/JSISerializer.cpp +342 -0
- package/Common/cpp/worklets/Tools/JSISerializer.h +47 -0
- package/Common/cpp/worklets/Tools/JSLogger.cpp +16 -0
- package/Common/cpp/worklets/Tools/JSLogger.h +20 -0
- package/Common/cpp/worklets/Tools/JSScheduler.cpp +10 -0
- package/Common/cpp/worklets/Tools/JSScheduler.h +29 -0
- package/Common/cpp/worklets/Tools/PlatformLogger.h +16 -0
- package/Common/cpp/worklets/Tools/SingleInstanceChecker.h +72 -0
- package/Common/cpp/worklets/Tools/ThreadSafeQueue.h +49 -0
- package/Common/cpp/worklets/Tools/UIScheduler.cpp +19 -0
- package/Common/cpp/worklets/Tools/UIScheduler.h +22 -0
- package/Common/cpp/worklets/Tools/WorkletEventHandler.cpp +29 -0
- package/Common/cpp/worklets/Tools/WorkletEventHandler.h +41 -0
- package/Common/cpp/worklets/Tools/WorkletsJSIUtils.cpp +26 -0
- package/Common/cpp/worklets/Tools/WorkletsJSIUtils.h +199 -0
- package/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.cpp +20 -0
- package/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h +19 -0
- package/Common/cpp/worklets/WorkletRuntime/RuntimeInitialization.md +191 -0
- package/Common/cpp/worklets/WorkletRuntime/UIRuntimeDecorator.cpp +19 -0
- package/Common/cpp/worklets/WorkletRuntime/UIRuntimeDecorator.h +16 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletHermesRuntime.cpp +108 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletHermesRuntime.h +127 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +183 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +90 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeCollector.h +36 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +179 -0
- package/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +22 -0
- package/LICENSE +20 -0
- package/README.md +27 -0
- package/RNWorklets.podspec +70 -0
- package/android/CMakeLists.txt +56 -0
- package/android/build.gradle +313 -0
- package/android/gradle.properties +5 -0
- package/android/proguard-rules.pro +3 -0
- package/android/spotless.gradle +9 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/worklets/CMakeLists.txt +85 -0
- package/android/src/main/cpp/worklets/android/AndroidUIScheduler.cpp +63 -0
- package/android/src/main/cpp/worklets/android/AndroidUIScheduler.h +41 -0
- package/android/src/main/cpp/worklets/android/AnimationFrameCallback.h +32 -0
- package/android/src/main/cpp/worklets/android/PlatformLogger.cpp +29 -0
- package/android/src/main/cpp/worklets/android/WorkletsModule.cpp +83 -0
- package/android/src/main/cpp/worklets/android/WorkletsModule.h +63 -0
- package/android/src/main/cpp/worklets/android/WorkletsOnLoad.cpp +13 -0
- package/android/src/main/java/com/swmansion/worklets/AndroidUIScheduler.java +60 -0
- package/android/src/main/java/com/swmansion/worklets/AnimationFrameQueue/AnimationFrameCallback.java +20 -0
- package/android/src/main/java/com/swmansion/worklets/AnimationFrameQueue/AnimationFrameQueue.java +113 -0
- package/android/src/main/java/com/swmansion/worklets/JSCallInvokerResolver.java +27 -0
- package/android/src/main/java/com/swmansion/worklets/WorkletsMessageQueueThread.java +16 -0
- package/android/src/main/java/com/swmansion/worklets/WorkletsMessageQueueThreadBase.java +72 -0
- package/android/src/main/java/com/swmansion/worklets/WorkletsModule.java +106 -0
- package/android/src/main/java/com/swmansion/worklets/WorkletsPackage.java +49 -0
- package/android/src/paper/com/swmansion/worklets/NativeWorkletsModuleSpec.java +26 -0
- package/apple/worklets/apple/AnimationFrameQueue.h +15 -0
- package/apple/worklets/apple/AnimationFrameQueue.mm +81 -0
- package/apple/worklets/apple/AssertJavaScriptQueue.h +14 -0
- package/apple/worklets/apple/AssertTurboModuleManagerQueue.h +16 -0
- package/apple/worklets/apple/IOSUIScheduler.h +14 -0
- package/apple/worklets/apple/IOSUIScheduler.mm +24 -0
- package/apple/worklets/apple/PlatformLogger.mm +31 -0
- package/apple/worklets/apple/SlowAnimations.h +8 -0
- package/apple/worklets/apple/SlowAnimations.mm +47 -0
- package/apple/worklets/apple/WorkletsDisplayLink.h +21 -0
- package/apple/worklets/apple/WorkletsMessageThread.h +16 -0
- package/apple/worklets/apple/WorkletsMessageThread.mm +32 -0
- package/apple/worklets/apple/WorkletsModule.h +10 -0
- package/apple/worklets/apple/WorkletsModule.mm +85 -0
- package/lib/module/PlatformChecker.js +35 -0
- package/lib/module/PlatformChecker.js.map +1 -0
- package/lib/module/WorkletsError.js +13 -0
- package/lib/module/WorkletsError.js.map +1 -0
- package/lib/module/WorkletsModule/JSWorklets.js +36 -0
- package/lib/module/WorkletsModule/JSWorklets.js.map +1 -0
- package/lib/module/WorkletsModule/NativeWorklets.js +39 -0
- package/lib/module/WorkletsModule/NativeWorklets.js.map +1 -0
- package/lib/module/WorkletsModule/index.js +4 -0
- package/lib/module/WorkletsModule/index.js.map +1 -0
- package/lib/module/WorkletsModule/workletsModuleInstance.js +7 -0
- package/lib/module/WorkletsModule/workletsModuleInstance.js.map +1 -0
- package/lib/module/WorkletsModule/workletsModuleInstance.web.js +5 -0
- package/lib/module/WorkletsModule/workletsModuleInstance.web.js.map +1 -0
- package/lib/module/WorkletsModule/workletsModuleProxy.js +4 -0
- package/lib/module/WorkletsModule/workletsModuleProxy.js.map +1 -0
- package/lib/module/animationFrameQueue/mockedRequestAnimationFrame.js +10 -0
- package/lib/module/animationFrameQueue/mockedRequestAnimationFrame.js.map +1 -0
- package/lib/module/animationFrameQueue/requestAnimationFrame.js +36 -0
- package/lib/module/animationFrameQueue/requestAnimationFrame.js.map +1 -0
- package/lib/module/errors.js +78 -0
- package/lib/module/errors.js.map +1 -0
- package/lib/module/index.js +17 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/initializers.js +158 -0
- package/lib/module/initializers.js.map +1 -0
- package/lib/module/logger/LogBox.js +15 -0
- package/lib/module/logger/LogBox.js.map +1 -0
- package/lib/module/logger/index.js +5 -0
- package/lib/module/logger/index.js.map +1 -0
- package/lib/module/logger/logger.js +137 -0
- package/lib/module/logger/logger.js.map +1 -0
- package/lib/module/privateGlobals.d.js +8 -0
- package/lib/module/privateGlobals.d.js.map +1 -0
- package/lib/module/runtimes.js +63 -0
- package/lib/module/runtimes.js.map +1 -0
- package/lib/module/shareableMappingCache.js +39 -0
- package/lib/module/shareableMappingCache.js.map +1 -0
- package/lib/module/shareables.js +417 -0
- package/lib/module/shareables.js.map +1 -0
- package/lib/module/specs/NativeWorkletsModule.js +5 -0
- package/lib/module/specs/NativeWorkletsModule.js.map +1 -0
- package/lib/module/specs/index.js +5 -0
- package/lib/module/specs/index.js.map +1 -0
- package/lib/module/threads.js +204 -0
- package/lib/module/threads.js.map +1 -0
- package/lib/module/valueUnpacker.js +83 -0
- package/lib/module/valueUnpacker.js.map +1 -0
- package/lib/module/workletFunction.js +37 -0
- package/lib/module/workletFunction.js.map +1 -0
- package/lib/module/workletTypes.js +12 -0
- package/lib/module/workletTypes.js.map +1 -0
- package/lib/typescript/PlatformChecker.d.ts +7 -0
- package/lib/typescript/PlatformChecker.d.ts.map +1 -0
- package/lib/typescript/WorkletsError.d.ts +3 -0
- package/lib/typescript/WorkletsError.d.ts.map +1 -0
- package/lib/typescript/WorkletsModule/JSWorklets.d.ts +3 -0
- package/lib/typescript/WorkletsModule/JSWorklets.d.ts.map +1 -0
- package/lib/typescript/WorkletsModule/NativeWorklets.d.ts +5 -0
- package/lib/typescript/WorkletsModule/NativeWorklets.d.ts.map +1 -0
- package/lib/typescript/WorkletsModule/index.d.ts +3 -0
- package/lib/typescript/WorkletsModule/index.d.ts.map +1 -0
- package/lib/typescript/WorkletsModule/workletsModuleInstance.d.ts +2 -0
- package/lib/typescript/WorkletsModule/workletsModuleInstance.d.ts.map +1 -0
- package/lib/typescript/WorkletsModule/workletsModuleInstance.web.d.ts +2 -0
- package/lib/typescript/WorkletsModule/workletsModuleInstance.web.d.ts.map +1 -0
- package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts +12 -0
- package/lib/typescript/WorkletsModule/workletsModuleProxy.d.ts.map +1 -0
- package/lib/typescript/animationFrameQueue/mockedRequestAnimationFrame.d.ts +6 -0
- package/lib/typescript/animationFrameQueue/mockedRequestAnimationFrame.d.ts.map +1 -0
- package/lib/typescript/animationFrameQueue/requestAnimationFrame.d.ts +2 -0
- package/lib/typescript/animationFrameQueue/requestAnimationFrame.d.ts.map +1 -0
- package/lib/typescript/errors.d.ts +19 -0
- package/lib/typescript/errors.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +13 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/initializers.d.ts +6 -0
- package/lib/typescript/initializers.d.ts.map +1 -0
- package/lib/typescript/logger/LogBox.d.ts +32 -0
- package/lib/typescript/logger/LogBox.d.ts.map +1 -0
- package/lib/typescript/logger/index.d.ts +3 -0
- package/lib/typescript/logger/index.d.ts.map +1 -0
- package/lib/typescript/logger/logger.d.ts +52 -0
- package/lib/typescript/logger/logger.d.ts.map +1 -0
- package/lib/typescript/runtimes.d.ts +16 -0
- package/lib/typescript/runtimes.d.ts.map +1 -0
- package/lib/typescript/shareableMappingCache.d.ts +16 -0
- package/lib/typescript/shareableMappingCache.d.ts.map +1 -0
- package/lib/typescript/shareables.d.ts +15 -0
- package/lib/typescript/shareables.d.ts.map +1 -0
- package/lib/typescript/specs/NativeWorkletsModule.d.ts +7 -0
- package/lib/typescript/specs/NativeWorkletsModule.d.ts.map +1 -0
- package/lib/typescript/specs/index.d.ts +3 -0
- package/lib/typescript/specs/index.d.ts.map +1 -0
- package/lib/typescript/threads.d.ts +49 -0
- package/lib/typescript/threads.d.ts.map +1 -0
- package/lib/typescript/valueUnpacker.d.ts +2 -0
- package/lib/typescript/valueUnpacker.d.ts.map +1 -0
- package/lib/typescript/workletFunction.d.ts +27 -0
- package/lib/typescript/workletFunction.d.ts.map +1 -0
- package/lib/typescript/workletTypes.d.ts +49 -0
- package/lib/typescript/workletTypes.d.ts.map +1 -0
- package/package.json +106 -8
- package/plugin/index.js +3 -0
- package/scripts/worklets_utils.rb +53 -0
- package/src/PlatformChecker.ts +43 -0
- package/src/WorkletsError.ts +13 -0
- package/src/WorkletsModule/JSWorklets.ts +57 -0
- package/src/WorkletsModule/NativeWorklets.ts +68 -0
- package/src/WorkletsModule/index.ts +7 -0
- package/src/WorkletsModule/workletsModuleInstance.ts +9 -0
- package/src/WorkletsModule/workletsModuleInstance.web.ts +5 -0
- package/src/WorkletsModule/workletsModuleProxy.ts +30 -0
- package/src/animationFrameQueue/mockedRequestAnimationFrame.ts +11 -0
- package/src/animationFrameQueue/requestAnimationFrame.ts +41 -0
- package/src/errors.ts +103 -0
- package/src/index.ts +42 -0
- package/src/initializers.ts +175 -0
- package/src/logger/LogBox.ts +55 -0
- package/src/logger/index.ts +3 -0
- package/src/logger/logger.ts +155 -0
- package/src/privateGlobals.d.ts +41 -0
- package/src/runtimes.ts +92 -0
- package/src/shareableMappingCache.ts +44 -0
- package/src/shareables.ts +577 -0
- package/src/specs/NativeWorkletsModule.ts +9 -0
- package/src/specs/index.ts +5 -0
- package/src/threads.ts +275 -0
- package/src/valueUnpacker.ts +110 -0
- package/src/workletFunction.ts +47 -0
- package/src/workletTypes.ts +76 -0
- package/Animated.js +0 -13
- package/AnimatedEvent.js +0 -167
- package/AnimatedImplementation.js +0 -666
- package/CoreAnimated.js +0 -43
- package/Easing.js +0 -236
- package/NativeAnimatedHelper.js +0 -226
- package/SpringConfig.js +0 -79
- package/animations/Animation.js +0 -36
- package/animations/DecayAnimation.js +0 -70
- package/animations/SpringAnimation.js +0 -125
- package/animations/TimingAnimation.js +0 -70
- package/bezier.js +0 -128
- package/createAnimatedComponent.js +0 -188
- package/nodes/AnimatedBlock.js +0 -19
- package/nodes/AnimatedClock.js +0 -76
- package/nodes/AnimatedCond.js +0 -23
- package/nodes/AnimatedDetach.js +0 -15
- package/nodes/AnimatedInterpolation.js +0 -338
- package/nodes/AnimatedNode.js +0 -97
- package/nodes/AnimatedOnChange.js +0 -28
- package/nodes/AnimatedOp.js +0 -17
- package/nodes/AnimatedProps.js +0 -154
- package/nodes/AnimatedSet.js +0 -19
- package/nodes/AnimatedStartClock.js +0 -21
- package/nodes/AnimatedStopClock.js +0 -21
- package/nodes/AnimatedStyle.js +0 -89
- package/nodes/AnimatedTracking.js +0 -36
- package/nodes/AnimatedTransform.js +0 -93
- package/nodes/AnimatedValue.js +0 -271
- package/nodes/AnimatedWithInput.js +0 -21
- package/nodes/SpringNode.js +0 -106
- package/nodes/TimingStep.js +0 -44
- package/utils.js +0 -28
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
#include <worklets/SharedItems/Shareables.h>
|
|
2
|
+
|
|
3
|
+
using namespace facebook;
|
|
4
|
+
|
|
5
|
+
namespace worklets {
|
|
6
|
+
|
|
7
|
+
jsi::Function getValueUnpacker(jsi::Runtime &rt) {
|
|
8
|
+
auto valueUnpacker = rt.global().getProperty(rt, "__valueUnpacker");
|
|
9
|
+
assert(valueUnpacker.isObject() && "valueUnpacker not found");
|
|
10
|
+
return valueUnpacker.asObject(rt).asFunction(rt);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
#ifndef NDEBUG
|
|
14
|
+
|
|
15
|
+
static const auto callGuardLambda = [](facebook::jsi::Runtime &rt,
|
|
16
|
+
const facebook::jsi::Value &thisVal,
|
|
17
|
+
const facebook::jsi::Value *args,
|
|
18
|
+
size_t count) {
|
|
19
|
+
return args[0].asObject(rt).asFunction(rt).call(rt, args + 1, count - 1);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
jsi::Function getCallGuard(jsi::Runtime &rt) {
|
|
23
|
+
auto callGuard = rt.global().getProperty(rt, "__callGuardDEV");
|
|
24
|
+
if (callGuard.isObject()) {
|
|
25
|
+
// Use JS implementation if `__callGuardDEV` has already been installed.
|
|
26
|
+
// This is the desired behavior.
|
|
27
|
+
return callGuard.asObject(rt).asFunction(rt);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Otherwise, fallback to C++ JSI implementation. This is necessary so that we
|
|
31
|
+
// can install `__callGuardDEV` itself and should happen only once. Note that
|
|
32
|
+
// the C++ implementation doesn't intercept errors and simply throws them as
|
|
33
|
+
// C++ exceptions which crashes the app. We assume that installing the guard
|
|
34
|
+
// doesn't throw any errors.
|
|
35
|
+
return jsi::Function::createFromHostFunction(
|
|
36
|
+
rt, jsi::PropNameID::forAscii(rt, "callGuard"), 1, callGuardLambda);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#endif // NDEBUG
|
|
40
|
+
|
|
41
|
+
jsi::Value makeShareableClone(
|
|
42
|
+
jsi::Runtime &rt,
|
|
43
|
+
const jsi::Value &value,
|
|
44
|
+
const jsi::Value &shouldRetainRemote,
|
|
45
|
+
const jsi::Value &nativeStateSource) {
|
|
46
|
+
std::shared_ptr<Shareable> shareable;
|
|
47
|
+
if (value.isObject()) {
|
|
48
|
+
auto object = value.asObject(rt);
|
|
49
|
+
if (!object.getProperty(rt, "__workletHash").isUndefined()) {
|
|
50
|
+
if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
|
|
51
|
+
shareable =
|
|
52
|
+
std::make_shared<RetainingShareable<ShareableWorklet>>(rt, object);
|
|
53
|
+
} else {
|
|
54
|
+
shareable = std::make_shared<ShareableWorklet>(rt, object);
|
|
55
|
+
}
|
|
56
|
+
} else if (!object.getProperty(rt, "__init").isUndefined()) {
|
|
57
|
+
shareable = std::make_shared<ShareableHandle>(rt, object);
|
|
58
|
+
} else if (object.isFunction(rt)) {
|
|
59
|
+
auto function = object.asFunction(rt);
|
|
60
|
+
if (function.isHostFunction(rt)) {
|
|
61
|
+
shareable =
|
|
62
|
+
std::make_shared<ShareableHostFunction>(rt, std::move(function));
|
|
63
|
+
} else {
|
|
64
|
+
shareable =
|
|
65
|
+
std::make_shared<ShareableRemoteFunction>(rt, std::move(function));
|
|
66
|
+
}
|
|
67
|
+
} else if (object.isArray(rt)) {
|
|
68
|
+
if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
|
|
69
|
+
shareable = std::make_shared<RetainingShareable<ShareableArray>>(
|
|
70
|
+
rt, object.asArray(rt));
|
|
71
|
+
} else {
|
|
72
|
+
shareable = std::make_shared<ShareableArray>(rt, object.asArray(rt));
|
|
73
|
+
}
|
|
74
|
+
} else if (object.isArrayBuffer(rt)) {
|
|
75
|
+
shareable =
|
|
76
|
+
std::make_shared<ShareableArrayBuffer>(rt, object.getArrayBuffer(rt));
|
|
77
|
+
} else if (object.isHostObject(rt)) {
|
|
78
|
+
if (object.isHostObject<ShareableJSRef>(rt)) {
|
|
79
|
+
return object;
|
|
80
|
+
}
|
|
81
|
+
shareable =
|
|
82
|
+
std::make_shared<ShareableHostObject>(rt, object.getHostObject(rt));
|
|
83
|
+
} else {
|
|
84
|
+
if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
|
|
85
|
+
shareable = std::make_shared<RetainingShareable<ShareableObject>>(
|
|
86
|
+
rt, object, nativeStateSource);
|
|
87
|
+
} else {
|
|
88
|
+
shareable =
|
|
89
|
+
std::make_shared<ShareableObject>(rt, object, nativeStateSource);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} else if (value.isString()) {
|
|
93
|
+
shareable = std::make_shared<ShareableString>(value.asString(rt).utf8(rt));
|
|
94
|
+
} else if (value.isUndefined()) {
|
|
95
|
+
shareable = std::make_shared<ShareableScalar>();
|
|
96
|
+
} else if (value.isNull()) {
|
|
97
|
+
shareable = std::make_shared<ShareableScalar>(nullptr);
|
|
98
|
+
} else if (value.isBool()) {
|
|
99
|
+
shareable = std::make_shared<ShareableScalar>(value.getBool());
|
|
100
|
+
} else if (value.isNumber()) {
|
|
101
|
+
shareable = std::make_shared<ShareableScalar>(value.getNumber());
|
|
102
|
+
} else if (value.isBigInt()) {
|
|
103
|
+
shareable = std::make_shared<ShareableBigInt>(rt, value.getBigInt(rt));
|
|
104
|
+
} else if (value.isSymbol()) {
|
|
105
|
+
// TODO: this is only a placeholder implementation, here we replace symbols
|
|
106
|
+
// with strings in order to make certain objects to be captured. There isn't
|
|
107
|
+
// yet any usecase for using symbols on the UI runtime so it is fine to keep
|
|
108
|
+
// it like this for now.
|
|
109
|
+
shareable =
|
|
110
|
+
std::make_shared<ShareableString>(value.getSymbol(rt).toString(rt));
|
|
111
|
+
} else {
|
|
112
|
+
throw std::runtime_error(
|
|
113
|
+
"[Worklets] Attempted to convert an unsupported value type.");
|
|
114
|
+
}
|
|
115
|
+
return ShareableJSRef::newHostObject(rt, shareable);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
std::shared_ptr<Shareable> extractShareableOrThrow(
|
|
119
|
+
jsi::Runtime &rt,
|
|
120
|
+
const jsi::Value &maybeShareableValue,
|
|
121
|
+
const std::string &errorMessage) {
|
|
122
|
+
if (maybeShareableValue.isObject()) {
|
|
123
|
+
auto object = maybeShareableValue.asObject(rt);
|
|
124
|
+
if (object.isHostObject<ShareableJSRef>(rt)) {
|
|
125
|
+
return object.getHostObject<ShareableJSRef>(rt)->value();
|
|
126
|
+
}
|
|
127
|
+
throw std::runtime_error(
|
|
128
|
+
"[Worklets] Attempted to extract from a HostObject that wasn't converted to a Shareable.");
|
|
129
|
+
} else if (maybeShareableValue.isUndefined()) {
|
|
130
|
+
return Shareable::undefined();
|
|
131
|
+
}
|
|
132
|
+
throw std::runtime_error(errorMessage);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
Shareable::~Shareable() {}
|
|
136
|
+
|
|
137
|
+
std::shared_ptr<Shareable> Shareable::undefined() {
|
|
138
|
+
static auto undefined = std::make_shared<ShareableScalar>();
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
template <typename BaseClass>
|
|
143
|
+
jsi::Value RetainingShareable<BaseClass>::toJSValue(jsi::Runtime &rt) {
|
|
144
|
+
if (&rt == primaryRuntime_) {
|
|
145
|
+
// TODO: it is suboptimal to generate new object every time getJS is
|
|
146
|
+
// called on host runtime – the objects we are generating already exists
|
|
147
|
+
// and we should possibly just grab a hold of such object and use it here
|
|
148
|
+
// instead of creating a new JS representation. As far as I understand the
|
|
149
|
+
// only case where it can be realistically called this way is when a
|
|
150
|
+
// shared value is created and then accessed on the same runtime
|
|
151
|
+
return BaseClass::toJSValue(rt);
|
|
152
|
+
}
|
|
153
|
+
if (secondaryValue_ == nullptr) {
|
|
154
|
+
auto value = BaseClass::toJSValue(rt);
|
|
155
|
+
secondaryValue_ = std::make_unique<jsi::Value>(rt, value);
|
|
156
|
+
secondaryRuntime_ = &rt;
|
|
157
|
+
return value;
|
|
158
|
+
}
|
|
159
|
+
if (&rt == secondaryRuntime_) {
|
|
160
|
+
return jsi::Value(rt, *secondaryValue_);
|
|
161
|
+
}
|
|
162
|
+
return BaseClass::toJSValue(rt);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
ShareableJSRef::~ShareableJSRef() {}
|
|
166
|
+
|
|
167
|
+
ShareableArray::ShareableArray(jsi::Runtime &rt, const jsi::Array &array)
|
|
168
|
+
: Shareable(ArrayType) {
|
|
169
|
+
auto size = array.size(rt);
|
|
170
|
+
data_.reserve(size);
|
|
171
|
+
for (size_t i = 0; i < size; i++) {
|
|
172
|
+
data_.push_back(extractShareableOrThrow(rt, array.getValueAtIndex(rt, i)));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
jsi::Value ShareableArray::toJSValue(jsi::Runtime &rt) {
|
|
177
|
+
auto size = data_.size();
|
|
178
|
+
auto ary = jsi::Array(rt, size);
|
|
179
|
+
for (size_t i = 0; i < size; i++) {
|
|
180
|
+
ary.setValueAtIndex(rt, i, data_[i]->toJSValue(rt));
|
|
181
|
+
}
|
|
182
|
+
return ary;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
jsi::Value ShareableArrayBuffer::toJSValue(jsi::Runtime &rt) {
|
|
186
|
+
auto size = static_cast<int>(data_.size());
|
|
187
|
+
auto arrayBuffer = rt.global()
|
|
188
|
+
.getPropertyAsFunction(rt, "ArrayBuffer")
|
|
189
|
+
.callAsConstructor(rt, size)
|
|
190
|
+
.getObject(rt)
|
|
191
|
+
.getArrayBuffer(rt);
|
|
192
|
+
memcpy(arrayBuffer.data(rt), data_.data(), size);
|
|
193
|
+
return arrayBuffer;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
ShareableObject::ShareableObject(jsi::Runtime &rt, const jsi::Object &object)
|
|
197
|
+
: Shareable(ObjectType) {
|
|
198
|
+
auto propertyNames = object.getPropertyNames(rt);
|
|
199
|
+
auto size = propertyNames.size(rt);
|
|
200
|
+
data_.reserve(size);
|
|
201
|
+
for (size_t i = 0; i < size; i++) {
|
|
202
|
+
auto key = propertyNames.getValueAtIndex(rt, i).asString(rt);
|
|
203
|
+
auto value = extractShareableOrThrow(rt, object.getProperty(rt, key));
|
|
204
|
+
data_.emplace_back(key.utf8(rt), value);
|
|
205
|
+
}
|
|
206
|
+
if (object.hasNativeState(rt)) {
|
|
207
|
+
nativeState_ = object.getNativeState(rt);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
ShareableObject::ShareableObject(
|
|
212
|
+
jsi::Runtime &rt,
|
|
213
|
+
const jsi::Object &object,
|
|
214
|
+
const jsi::Value &nativeStateSource)
|
|
215
|
+
: ShareableObject(rt, object) {
|
|
216
|
+
if (nativeStateSource.isObject() &&
|
|
217
|
+
nativeStateSource.asObject(rt).hasNativeState(rt)) {
|
|
218
|
+
nativeState_ = nativeStateSource.asObject(rt).getNativeState(rt);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
jsi::Value ShareableObject::toJSValue(jsi::Runtime &rt) {
|
|
223
|
+
auto obj = jsi::Object(rt);
|
|
224
|
+
for (size_t i = 0, size = data_.size(); i < size; i++) {
|
|
225
|
+
obj.setProperty(
|
|
226
|
+
rt,
|
|
227
|
+
jsi::String::createFromUtf8(rt, data_[i].first),
|
|
228
|
+
data_[i].second->toJSValue(rt));
|
|
229
|
+
}
|
|
230
|
+
if (nativeState_ != nullptr) {
|
|
231
|
+
obj.setNativeState(rt, nativeState_);
|
|
232
|
+
}
|
|
233
|
+
return obj;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
jsi::Value ShareableHostObject::toJSValue(jsi::Runtime &rt) {
|
|
237
|
+
return jsi::Object::createFromHostObject(rt, hostObject_);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
jsi::Value ShareableHostFunction::toJSValue(jsi::Runtime &rt) {
|
|
241
|
+
return jsi::Function::createFromHostFunction(
|
|
242
|
+
rt, jsi::PropNameID::forUtf8(rt, name_), paramCount_, hostFunction_);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
jsi::Value ShareableWorklet::toJSValue(jsi::Runtime &rt) {
|
|
246
|
+
assert(
|
|
247
|
+
std::any_of(
|
|
248
|
+
data_.cbegin(),
|
|
249
|
+
data_.cend(),
|
|
250
|
+
[](const auto &item) { return item.first == "__workletHash"; }) &&
|
|
251
|
+
"ShareableWorklet doesn't have `__workletHash` property");
|
|
252
|
+
jsi::Value obj = ShareableObject::toJSValue(rt);
|
|
253
|
+
return getValueUnpacker(rt).call(
|
|
254
|
+
rt, obj, jsi::String::createFromAscii(rt, "Worklet"));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
jsi::Value ShareableRemoteFunction::toJSValue(jsi::Runtime &rt) {
|
|
258
|
+
if (&rt == runtime_) {
|
|
259
|
+
return jsi::Value(rt, *function_);
|
|
260
|
+
} else {
|
|
261
|
+
#ifndef NDEBUG
|
|
262
|
+
return getValueUnpacker(rt).call(
|
|
263
|
+
rt,
|
|
264
|
+
ShareableJSRef::newHostObject(rt, shared_from_this()),
|
|
265
|
+
jsi::String::createFromAscii(rt, "RemoteFunction"),
|
|
266
|
+
jsi::String::createFromUtf8(rt, name_));
|
|
267
|
+
#else
|
|
268
|
+
return ShareableJSRef::newHostObject(rt, shared_from_this());
|
|
269
|
+
#endif
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
jsi::Value ShareableHandle::toJSValue(jsi::Runtime &rt) {
|
|
274
|
+
if (remoteValue_ == nullptr) {
|
|
275
|
+
auto initObj = initializer_->toJSValue(rt);
|
|
276
|
+
auto value = std::make_unique<jsi::Value>(getValueUnpacker(rt).call(
|
|
277
|
+
rt, initObj, jsi::String::createFromAscii(rt, "Handle")));
|
|
278
|
+
|
|
279
|
+
// We are locking the initialization here since the thread that is
|
|
280
|
+
// initalizing can be pre-empted on runtime lock. E.g.
|
|
281
|
+
// UI thread can be pre-empted on initialization of a shared value and then
|
|
282
|
+
// JS thread can try to access the shared value, locking the whole runtime.
|
|
283
|
+
// If we put the lock on `getValueUnpacker` part (basically any part that
|
|
284
|
+
// requires runtime) we would get a deadlock since UI thread would never
|
|
285
|
+
// release it.
|
|
286
|
+
std::unique_lock<std::mutex> lock(initializationMutex_);
|
|
287
|
+
if (remoteValue_ == nullptr) {
|
|
288
|
+
remoteValue_ = std::move(value);
|
|
289
|
+
remoteRuntime_ = &rt;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (&rt == remoteRuntime_) {
|
|
293
|
+
return jsi::Value(rt, *remoteValue_);
|
|
294
|
+
}
|
|
295
|
+
auto initObj = initializer_->toJSValue(rt);
|
|
296
|
+
return getValueUnpacker(rt).call(
|
|
297
|
+
rt, initObj, jsi::String::createFromAscii(rt, "Handle"));
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
jsi::Value ShareableString::toJSValue(jsi::Runtime &rt) {
|
|
301
|
+
return jsi::String::createFromUtf8(rt, data_);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
jsi::Value ShareableBigInt::toJSValue(jsi::Runtime &rt) {
|
|
305
|
+
return rt.global()
|
|
306
|
+
.getPropertyAsFunction(rt, "BigInt")
|
|
307
|
+
.call(rt, jsi::String::createFromUtf8(rt, string_));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
jsi::Value ShareableScalar::toJSValue(jsi::Runtime &) {
|
|
311
|
+
switch (valueType_) {
|
|
312
|
+
case Shareable::UndefinedType:
|
|
313
|
+
return jsi::Value();
|
|
314
|
+
case Shareable::NullType:
|
|
315
|
+
return jsi::Value(nullptr);
|
|
316
|
+
case Shareable::BooleanType:
|
|
317
|
+
return jsi::Value(data_.boolean);
|
|
318
|
+
case Shareable::NumberType:
|
|
319
|
+
return jsi::Value(data_.number);
|
|
320
|
+
default:
|
|
321
|
+
throw std::runtime_error(
|
|
322
|
+
"[Worklets] Attempted to convert object that's not of a scalar type.");
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
} // namespace worklets
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <worklets/Registries/WorkletRuntimeRegistry.h>
|
|
4
|
+
|
|
5
|
+
#include <jsi/jsi.h>
|
|
6
|
+
|
|
7
|
+
#include <memory>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <utility>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
using namespace facebook;
|
|
13
|
+
|
|
14
|
+
namespace worklets {
|
|
15
|
+
|
|
16
|
+
jsi::Function getValueUnpacker(jsi::Runtime &rt);
|
|
17
|
+
|
|
18
|
+
#ifndef NDEBUG
|
|
19
|
+
jsi::Function getCallGuard(jsi::Runtime &rt);
|
|
20
|
+
#endif // NDEBUG
|
|
21
|
+
|
|
22
|
+
// If possible, please use `WorkletRuntime::runGuarded` instead.
|
|
23
|
+
template <typename... Args>
|
|
24
|
+
inline jsi::Value runOnRuntimeGuarded(
|
|
25
|
+
jsi::Runtime &rt,
|
|
26
|
+
const jsi::Value &function,
|
|
27
|
+
Args &&...args) {
|
|
28
|
+
// We only use callGuard in debug mode, otherwise we call the provided
|
|
29
|
+
// function directly. CallGuard provides a way of capturing exceptions in
|
|
30
|
+
// JavaScript and propagating them to the main React Native thread such that
|
|
31
|
+
// they can be presented using RN's LogBox.
|
|
32
|
+
#ifndef NDEBUG
|
|
33
|
+
return getCallGuard(rt).call(rt, function, args...);
|
|
34
|
+
#else
|
|
35
|
+
return function.asObject(rt).asFunction(rt).call(rt, args...);
|
|
36
|
+
#endif
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
inline void cleanupIfRuntimeExists(
|
|
40
|
+
jsi::Runtime *rt,
|
|
41
|
+
std::unique_ptr<jsi::Value> &value) {
|
|
42
|
+
if (rt != nullptr && !WorkletRuntimeRegistry::isRuntimeAlive(rt)) {
|
|
43
|
+
// The below use of unique_ptr.release prevents the smart pointer from
|
|
44
|
+
// calling the destructor of the kept object. This effectively results in
|
|
45
|
+
// leaking some memory. We do this on purpose, as sometimes we would keep
|
|
46
|
+
// references to JSI objects past the lifetime of its runtime (e.g.,
|
|
47
|
+
// shared values references from the RN VM holds reference to JSI objects
|
|
48
|
+
// on the UI runtime). When the UI runtime is terminated, the orphaned JSI
|
|
49
|
+
// objects would crash the app when their destructors are called, because
|
|
50
|
+
// they call into a memory that's managed by the terminated runtime. We
|
|
51
|
+
// accept the tradeoff of leaking memory here, as it has a limited impact.
|
|
52
|
+
// This scenario can only occur when the React instance is torn down which
|
|
53
|
+
// happens in development mode during app reloads, or in production when
|
|
54
|
+
// the app is being shut down gracefully by the system. An alternative
|
|
55
|
+
// solution would require us to keep track of all JSI values that are in
|
|
56
|
+
// use which would require additional data structure and compute spent on
|
|
57
|
+
// bookkeeping that only for the sake of destroying the values in time
|
|
58
|
+
// before the runtime is terminated. Note that the underlying memory that
|
|
59
|
+
// jsi::Value refers to is managed by the VM and gets freed along with the
|
|
60
|
+
// runtime.
|
|
61
|
+
value.release();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
class Shareable {
|
|
66
|
+
public:
|
|
67
|
+
virtual jsi::Value toJSValue(jsi::Runtime &rt) = 0;
|
|
68
|
+
|
|
69
|
+
virtual ~Shareable();
|
|
70
|
+
|
|
71
|
+
enum ValueType {
|
|
72
|
+
UndefinedType,
|
|
73
|
+
NullType,
|
|
74
|
+
BooleanType,
|
|
75
|
+
NumberType,
|
|
76
|
+
// SymbolType, TODO
|
|
77
|
+
BigIntType,
|
|
78
|
+
StringType,
|
|
79
|
+
ObjectType,
|
|
80
|
+
ArrayType,
|
|
81
|
+
WorkletType,
|
|
82
|
+
RemoteFunctionType,
|
|
83
|
+
HandleType,
|
|
84
|
+
HostObjectType,
|
|
85
|
+
HostFunctionType,
|
|
86
|
+
ArrayBufferType,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
explicit Shareable(ValueType valueType) : valueType_(valueType) {}
|
|
90
|
+
|
|
91
|
+
inline ValueType valueType() const {
|
|
92
|
+
return valueType_;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static std::shared_ptr<Shareable> undefined();
|
|
96
|
+
|
|
97
|
+
protected:
|
|
98
|
+
ValueType valueType_;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
template <typename BaseClass>
|
|
102
|
+
class RetainingShareable : virtual public BaseClass {
|
|
103
|
+
private:
|
|
104
|
+
jsi::Runtime *primaryRuntime_;
|
|
105
|
+
jsi::Runtime *secondaryRuntime_;
|
|
106
|
+
std::unique_ptr<jsi::Value> secondaryValue_;
|
|
107
|
+
|
|
108
|
+
public:
|
|
109
|
+
template <typename... Args>
|
|
110
|
+
explicit RetainingShareable(jsi::Runtime &rt, Args &&...args)
|
|
111
|
+
: BaseClass(rt, std::forward<Args>(args)...), primaryRuntime_(&rt) {}
|
|
112
|
+
|
|
113
|
+
jsi::Value toJSValue(jsi::Runtime &rt);
|
|
114
|
+
|
|
115
|
+
~RetainingShareable() {
|
|
116
|
+
cleanupIfRuntimeExists(secondaryRuntime_, secondaryValue_);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
class ShareableJSRef : public jsi::HostObject {
|
|
121
|
+
private:
|
|
122
|
+
const std::shared_ptr<Shareable> value_;
|
|
123
|
+
|
|
124
|
+
public:
|
|
125
|
+
explicit ShareableJSRef(const std::shared_ptr<Shareable> &value)
|
|
126
|
+
: value_(value) {}
|
|
127
|
+
|
|
128
|
+
virtual ~ShareableJSRef();
|
|
129
|
+
|
|
130
|
+
std::shared_ptr<Shareable> value() const {
|
|
131
|
+
return value_;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
static jsi::Object newHostObject(
|
|
135
|
+
jsi::Runtime &rt,
|
|
136
|
+
const std::shared_ptr<Shareable> &value) {
|
|
137
|
+
return jsi::Object::createFromHostObject(
|
|
138
|
+
rt, std::make_shared<ShareableJSRef>(value));
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
jsi::Value makeShareableClone(
|
|
143
|
+
jsi::Runtime &rt,
|
|
144
|
+
const jsi::Value &value,
|
|
145
|
+
const jsi::Value &shouldRetainRemote,
|
|
146
|
+
const jsi::Value &nativeStateSource);
|
|
147
|
+
|
|
148
|
+
std::shared_ptr<Shareable> extractShareableOrThrow(
|
|
149
|
+
jsi::Runtime &rt,
|
|
150
|
+
const jsi::Value &maybeShareableValue,
|
|
151
|
+
const std::string &errorMessage =
|
|
152
|
+
"[Worklets] Expecting the object to be of type ShareableJSRef.");
|
|
153
|
+
|
|
154
|
+
template <typename T>
|
|
155
|
+
std::shared_ptr<T> extractShareableOrThrow(
|
|
156
|
+
jsi::Runtime &rt,
|
|
157
|
+
const jsi::Value &shareableRef,
|
|
158
|
+
const std::string &errorMessage =
|
|
159
|
+
"[Worklets] Provided shareable object is of an incompatible type.") {
|
|
160
|
+
auto res = std::dynamic_pointer_cast<T>(
|
|
161
|
+
extractShareableOrThrow(rt, shareableRef, errorMessage));
|
|
162
|
+
if (!res) {
|
|
163
|
+
throw std::runtime_error(errorMessage);
|
|
164
|
+
}
|
|
165
|
+
return res;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
class ShareableArray : public Shareable {
|
|
169
|
+
public:
|
|
170
|
+
ShareableArray(jsi::Runtime &rt, const jsi::Array &array);
|
|
171
|
+
|
|
172
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
173
|
+
|
|
174
|
+
protected:
|
|
175
|
+
std::vector<std::shared_ptr<Shareable>> data_;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
class ShareableObject : public Shareable {
|
|
179
|
+
public:
|
|
180
|
+
ShareableObject(jsi::Runtime &rt, const jsi::Object &object);
|
|
181
|
+
|
|
182
|
+
ShareableObject(
|
|
183
|
+
jsi::Runtime &rt,
|
|
184
|
+
const jsi::Object &object,
|
|
185
|
+
const jsi::Value &nativeStateSource);
|
|
186
|
+
|
|
187
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
188
|
+
|
|
189
|
+
protected:
|
|
190
|
+
std::vector<std::pair<std::string, std::shared_ptr<Shareable>>> data_;
|
|
191
|
+
std::shared_ptr<jsi::NativeState> nativeState_;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
class ShareableHostObject : public Shareable {
|
|
195
|
+
public:
|
|
196
|
+
ShareableHostObject(
|
|
197
|
+
jsi::Runtime &,
|
|
198
|
+
const std::shared_ptr<jsi::HostObject> &hostObject)
|
|
199
|
+
: Shareable(HostObjectType), hostObject_(hostObject) {}
|
|
200
|
+
|
|
201
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
202
|
+
|
|
203
|
+
protected:
|
|
204
|
+
const std::shared_ptr<jsi::HostObject> hostObject_;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
class ShareableHostFunction : public Shareable {
|
|
208
|
+
public:
|
|
209
|
+
ShareableHostFunction(jsi::Runtime &rt, jsi::Function function)
|
|
210
|
+
: Shareable(HostFunctionType),
|
|
211
|
+
hostFunction_(
|
|
212
|
+
(assert(function.isHostFunction(rt)),
|
|
213
|
+
function.getHostFunction(rt))),
|
|
214
|
+
name_(function.getProperty(rt, "name").asString(rt).utf8(rt)),
|
|
215
|
+
paramCount_(function.getProperty(rt, "length").asNumber()) {}
|
|
216
|
+
|
|
217
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
218
|
+
|
|
219
|
+
protected:
|
|
220
|
+
const jsi::HostFunctionType hostFunction_;
|
|
221
|
+
const std::string name_;
|
|
222
|
+
const unsigned int paramCount_;
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
class ShareableArrayBuffer : public Shareable {
|
|
226
|
+
public:
|
|
227
|
+
ShareableArrayBuffer(jsi::Runtime &rt, const jsi::ArrayBuffer &arrayBuffer)
|
|
228
|
+
: Shareable(ArrayBufferType),
|
|
229
|
+
data_(
|
|
230
|
+
arrayBuffer.data(rt),
|
|
231
|
+
arrayBuffer.data(rt) + arrayBuffer.size(rt)) {}
|
|
232
|
+
|
|
233
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
234
|
+
|
|
235
|
+
protected:
|
|
236
|
+
const std::vector<uint8_t> data_;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
class ShareableWorklet : public ShareableObject {
|
|
240
|
+
public:
|
|
241
|
+
ShareableWorklet(jsi::Runtime &rt, const jsi::Object &worklet)
|
|
242
|
+
: ShareableObject(rt, worklet) {
|
|
243
|
+
valueType_ = WorkletType;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
class ShareableRemoteFunction
|
|
250
|
+
: public Shareable,
|
|
251
|
+
public std::enable_shared_from_this<ShareableRemoteFunction> {
|
|
252
|
+
private:
|
|
253
|
+
jsi::Runtime *runtime_;
|
|
254
|
+
#ifndef NDEBUG
|
|
255
|
+
const std::string name_;
|
|
256
|
+
#endif
|
|
257
|
+
std::unique_ptr<jsi::Value> function_;
|
|
258
|
+
|
|
259
|
+
public:
|
|
260
|
+
ShareableRemoteFunction(jsi::Runtime &rt, jsi::Function &&function)
|
|
261
|
+
: Shareable(RemoteFunctionType),
|
|
262
|
+
runtime_(&rt),
|
|
263
|
+
#ifndef NDEBUG
|
|
264
|
+
name_(function.getProperty(rt, "name").asString(rt).utf8(rt)),
|
|
265
|
+
#endif
|
|
266
|
+
function_(std::make_unique<jsi::Value>(rt, std::move(function))) {
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
~ShareableRemoteFunction() {
|
|
270
|
+
cleanupIfRuntimeExists(runtime_, function_);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
class ShareableHandle : public Shareable {
|
|
277
|
+
private:
|
|
278
|
+
// We don't release the initializer since the handle can get
|
|
279
|
+
// initialized in parallel on multiple threads. However this is not a problem,
|
|
280
|
+
// since the final value is taken from a cache on the runtime which guarantees
|
|
281
|
+
// sequential access.
|
|
282
|
+
std::unique_ptr<ShareableObject> initializer_;
|
|
283
|
+
std::unique_ptr<jsi::Value> remoteValue_;
|
|
284
|
+
mutable std::mutex initializationMutex_;
|
|
285
|
+
jsi::Runtime *remoteRuntime_;
|
|
286
|
+
|
|
287
|
+
public:
|
|
288
|
+
ShareableHandle(jsi::Runtime &rt, const jsi::Object &initializerObject)
|
|
289
|
+
: Shareable(HandleType),
|
|
290
|
+
initializer_(std::make_unique<ShareableObject>(rt, initializerObject)) {
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
~ShareableHandle() {
|
|
294
|
+
cleanupIfRuntimeExists(remoteRuntime_, remoteValue_);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
class ShareableString : public Shareable {
|
|
301
|
+
public:
|
|
302
|
+
explicit ShareableString(const std::string &string)
|
|
303
|
+
: Shareable(StringType), data_(string) {}
|
|
304
|
+
|
|
305
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
306
|
+
|
|
307
|
+
protected:
|
|
308
|
+
const std::string data_;
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
class ShareableBigInt : public Shareable {
|
|
312
|
+
public:
|
|
313
|
+
explicit ShareableBigInt(jsi::Runtime &rt, const jsi::BigInt &bigint)
|
|
314
|
+
: Shareable(BigIntType), string_(bigint.toString(rt).utf8(rt)) {}
|
|
315
|
+
|
|
316
|
+
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
|
317
|
+
|
|
318
|
+
protected:
|
|
319
|
+
const std::string string_;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
class ShareableScalar : public Shareable {
|
|
323
|
+
public:
|
|
324
|
+
explicit ShareableScalar(double number) : Shareable(NumberType) {
|
|
325
|
+
data_.number = number;
|
|
326
|
+
}
|
|
327
|
+
explicit ShareableScalar(bool boolean) : Shareable(BooleanType) {
|
|
328
|
+
data_.boolean = boolean;
|
|
329
|
+
}
|
|
330
|
+
ShareableScalar() : Shareable(UndefinedType) {}
|
|
331
|
+
explicit ShareableScalar(std::nullptr_t) : Shareable(NullType) {}
|
|
332
|
+
|
|
333
|
+
jsi::Value toJSValue(jsi::Runtime &);
|
|
334
|
+
|
|
335
|
+
protected:
|
|
336
|
+
union Data {
|
|
337
|
+
bool boolean;
|
|
338
|
+
double number;
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
private:
|
|
342
|
+
Data data_;
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
} // namespace worklets
|