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,72 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
4
|
+
import com.facebook.react.bridge.queue.MessageQueueThread;
|
|
5
|
+
import com.facebook.react.bridge.queue.MessageQueueThreadImpl;
|
|
6
|
+
import com.facebook.react.bridge.queue.MessageQueueThreadPerfStats;
|
|
7
|
+
import com.facebook.react.bridge.queue.MessageQueueThreadSpec;
|
|
8
|
+
import java.lang.reflect.Field;
|
|
9
|
+
import java.util.concurrent.Callable;
|
|
10
|
+
import java.util.concurrent.Future;
|
|
11
|
+
|
|
12
|
+
// This class is an almost exact copy of MessageQueueThreadImpl taken from here:
|
|
13
|
+
// https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/MessageQueueThreadImpl.java
|
|
14
|
+
// The only method that has changed is `quitSynchronous()` (see comment above
|
|
15
|
+
// function implementation for details).
|
|
16
|
+
@DoNotStrip
|
|
17
|
+
public abstract class WorkletsMessageQueueThreadBase implements MessageQueueThread {
|
|
18
|
+
protected final MessageQueueThreadImpl messageQueueThread;
|
|
19
|
+
|
|
20
|
+
public WorkletsMessageQueueThreadBase() {
|
|
21
|
+
messageQueueThread =
|
|
22
|
+
MessageQueueThreadImpl.create(
|
|
23
|
+
MessageQueueThreadSpec.mainThreadSpec(),
|
|
24
|
+
exception -> {
|
|
25
|
+
throw new RuntimeException(exception);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Override
|
|
30
|
+
public <T> Future<T> callOnQueue(Callable<T> callable) {
|
|
31
|
+
return messageQueueThread.callOnQueue(callable);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@Override
|
|
35
|
+
public boolean isOnThread() {
|
|
36
|
+
return messageQueueThread.isOnThread();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Override
|
|
40
|
+
public void assertIsOnThread() {
|
|
41
|
+
messageQueueThread.assertIsOnThread();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Override
|
|
45
|
+
public void assertIsOnThread(String s) {
|
|
46
|
+
messageQueueThread.assertIsOnThread(s);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// We don't want to quit the main looper (which is what MessageQueueThreadImpl would have done),
|
|
50
|
+
// but we still want to prevent anything else from executing.
|
|
51
|
+
@Override
|
|
52
|
+
public void quitSynchronous() {
|
|
53
|
+
try {
|
|
54
|
+
Field mIsFinished = messageQueueThread.getClass().getDeclaredField("mIsFinished");
|
|
55
|
+
mIsFinished.setAccessible(true);
|
|
56
|
+
mIsFinished.set(messageQueueThread, true);
|
|
57
|
+
mIsFinished.setAccessible(false);
|
|
58
|
+
} catch (NoSuchFieldException | IllegalAccessException e) {
|
|
59
|
+
e.printStackTrace();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@Override
|
|
64
|
+
public MessageQueueThreadPerfStats getPerfStats() {
|
|
65
|
+
return messageQueueThread.getPerfStats();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@Override
|
|
69
|
+
public void resetPerfStats() {
|
|
70
|
+
messageQueueThread.resetPerfStats();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.OptIn;
|
|
4
|
+
import com.facebook.jni.HybridData;
|
|
5
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
6
|
+
import com.facebook.react.bridge.LifecycleEventListener;
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
9
|
+
import com.facebook.react.bridge.queue.MessageQueueThread;
|
|
10
|
+
import com.facebook.react.common.annotations.FrameworkAPI;
|
|
11
|
+
import com.facebook.react.module.annotations.ReactModule;
|
|
12
|
+
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
|
|
13
|
+
import com.facebook.soloader.SoLoader;
|
|
14
|
+
import java.util.Objects;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @noinspection JavaJniMissingFunction
|
|
18
|
+
*/
|
|
19
|
+
@ReactModule(name = WorkletsModule.NAME)
|
|
20
|
+
public class WorkletsModule extends NativeWorkletsModuleSpec implements LifecycleEventListener {
|
|
21
|
+
static {
|
|
22
|
+
SoLoader.loadLibrary("worklets");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@DoNotStrip
|
|
26
|
+
@SuppressWarnings("unused")
|
|
27
|
+
private HybridData mHybridData;
|
|
28
|
+
|
|
29
|
+
@SuppressWarnings("unused")
|
|
30
|
+
protected HybridData getHybridData() {
|
|
31
|
+
return mHybridData;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private final WorkletsMessageQueueThread mMessageQueueThread = new WorkletsMessageQueueThread();
|
|
35
|
+
private final AndroidUIScheduler mAndroidUIScheduler;
|
|
36
|
+
private final AnimationFrameQueue mAnimationFrameQueue;
|
|
37
|
+
private boolean mSlowAnimationsEnabled;
|
|
38
|
+
|
|
39
|
+
@OptIn(markerClass = FrameworkAPI.class)
|
|
40
|
+
private native HybridData initHybrid(
|
|
41
|
+
long jsContext,
|
|
42
|
+
String valueUnpackerCode,
|
|
43
|
+
MessageQueueThread messageQueueThread,
|
|
44
|
+
CallInvokerHolderImpl jsCallInvokerHolder,
|
|
45
|
+
AndroidUIScheduler androidUIScheduler);
|
|
46
|
+
|
|
47
|
+
public WorkletsModule(ReactApplicationContext reactContext) {
|
|
48
|
+
super(reactContext);
|
|
49
|
+
reactContext.assertOnJSQueueThread();
|
|
50
|
+
mAndroidUIScheduler = new AndroidUIScheduler(reactContext);
|
|
51
|
+
mAnimationFrameQueue = new AnimationFrameQueue(reactContext);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@OptIn(markerClass = FrameworkAPI.class)
|
|
55
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
56
|
+
public boolean installTurboModule(String valueUnpackerCode) {
|
|
57
|
+
var context = getReactApplicationContext();
|
|
58
|
+
context.assertOnJSQueueThread();
|
|
59
|
+
|
|
60
|
+
var jsContext = Objects.requireNonNull(context.getJavaScriptContextHolder()).get();
|
|
61
|
+
var jsCallInvokerHolder = JSCallInvokerResolver.getJSCallInvokerHolder(context);
|
|
62
|
+
|
|
63
|
+
mHybridData =
|
|
64
|
+
initHybrid(
|
|
65
|
+
jsContext,
|
|
66
|
+
valueUnpackerCode,
|
|
67
|
+
mMessageQueueThread,
|
|
68
|
+
jsCallInvokerHolder,
|
|
69
|
+
mAndroidUIScheduler);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public void requestAnimationFrame(AnimationFrameCallback animationFrameCallback) {
|
|
74
|
+
mAnimationFrameQueue.requestAnimationFrame(animationFrameCallback);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public void toggleSlowAnimations() {
|
|
78
|
+
final int ANIMATIONS_DRAG_FACTOR = 10;
|
|
79
|
+
mSlowAnimationsEnabled = !mSlowAnimationsEnabled;
|
|
80
|
+
mAnimationFrameQueue.enableSlowAnimations(mSlowAnimationsEnabled, ANIMATIONS_DRAG_FACTOR);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public void invalidate() {
|
|
84
|
+
// We have to destroy extra runtimes when invalidate is called. If we clean
|
|
85
|
+
// it up later instead there's a chance the runtime will retain references
|
|
86
|
+
// to invalidated memory and will crash on its destruction.
|
|
87
|
+
invalidateCpp();
|
|
88
|
+
|
|
89
|
+
mAndroidUIScheduler.deactivate();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private native void invalidateCpp();
|
|
93
|
+
|
|
94
|
+
@Override
|
|
95
|
+
public void onHostResume() {
|
|
96
|
+
mAnimationFrameQueue.resume();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@Override
|
|
100
|
+
public void onHostPause() {
|
|
101
|
+
mAnimationFrameQueue.pause();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@Override
|
|
105
|
+
public void onHostDestroy() {}
|
|
106
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.facebook.react.BaseReactPackage;
|
|
5
|
+
import com.facebook.react.ReactPackage;
|
|
6
|
+
import com.facebook.react.bridge.NativeModule;
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
+
import com.facebook.react.module.annotations.ReactModule;
|
|
9
|
+
import com.facebook.react.module.annotations.ReactModuleList;
|
|
10
|
+
import com.facebook.react.module.model.ReactModuleInfo;
|
|
11
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
|
12
|
+
import java.util.HashMap;
|
|
13
|
+
import java.util.Map;
|
|
14
|
+
import java.util.Objects;
|
|
15
|
+
|
|
16
|
+
@ReactModuleList(nativeModules = {WorkletsModule.class})
|
|
17
|
+
public class WorkletsPackage extends BaseReactPackage implements ReactPackage {
|
|
18
|
+
@Override
|
|
19
|
+
public NativeModule getModule(
|
|
20
|
+
@NonNull String name, @NonNull ReactApplicationContext reactContext) {
|
|
21
|
+
return switch (name) {
|
|
22
|
+
case WorkletsModule.NAME -> new WorkletsModule(reactContext);
|
|
23
|
+
default -> null;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Override
|
|
28
|
+
public ReactModuleInfoProvider getReactModuleInfoProvider() {
|
|
29
|
+
Class<? extends NativeModule>[] moduleList = new Class[] {WorkletsModule.class};
|
|
30
|
+
|
|
31
|
+
final Map<String, ReactModuleInfo> reactModuleInfoMap = new HashMap<>();
|
|
32
|
+
for (Class<? extends NativeModule> moduleClass : moduleList) {
|
|
33
|
+
ReactModule reactModule =
|
|
34
|
+
Objects.requireNonNull(moduleClass.getAnnotation(ReactModule.class));
|
|
35
|
+
|
|
36
|
+
reactModuleInfoMap.put(
|
|
37
|
+
reactModule.name(),
|
|
38
|
+
new ReactModuleInfo(
|
|
39
|
+
reactModule.name(),
|
|
40
|
+
moduleClass.getName(),
|
|
41
|
+
reactModule.canOverrideExistingModule(),
|
|
42
|
+
reactModule.needsEagerInit(),
|
|
43
|
+
reactModule.isCxxModule(),
|
|
44
|
+
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return () -> reactModuleInfoMap;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
5
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
6
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
7
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
|
8
|
+
import javax.annotation.Nonnull;
|
|
9
|
+
|
|
10
|
+
public abstract class NativeWorkletsModuleSpec extends ReactContextBaseJavaModule
|
|
11
|
+
implements TurboModule {
|
|
12
|
+
public static final String NAME = "WorkletsModule";
|
|
13
|
+
|
|
14
|
+
public NativeWorkletsModuleSpec(ReactApplicationContext reactContext) {
|
|
15
|
+
super(reactContext);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@Override
|
|
19
|
+
public @Nonnull String getName() {
|
|
20
|
+
return NAME;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
24
|
+
@DoNotStrip
|
|
25
|
+
public abstract boolean installTurboModule(String valueUnpackerCode);
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#if __cplusplus
|
|
2
|
+
|
|
3
|
+
#import <worklets/apple/WorkletsDisplayLink.h>
|
|
4
|
+
#import <functional>
|
|
5
|
+
|
|
6
|
+
@interface AnimationFrameQueue : NSObject
|
|
7
|
+
|
|
8
|
+
- (void)requestAnimationFrame:(std::function<void(double)>)callback;
|
|
9
|
+
- (void)executeQueue:(WorkletsDisplayLink *)displayLink;
|
|
10
|
+
|
|
11
|
+
- (void)invalidate;
|
|
12
|
+
|
|
13
|
+
@end
|
|
14
|
+
|
|
15
|
+
#endif // __cplusplus
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#import <worklets/apple/AnimationFrameQueue.h>
|
|
2
|
+
#import <worklets/apple/AssertJavaScriptQueue.h>
|
|
3
|
+
#import <worklets/apple/AssertTurboModuleManagerQueue.h>
|
|
4
|
+
#import <worklets/apple/SlowAnimations.h>
|
|
5
|
+
|
|
6
|
+
#import <React/RCTAssert.h>
|
|
7
|
+
|
|
8
|
+
@implementation AnimationFrameQueue {
|
|
9
|
+
/* DisplayLink is thread safe. */
|
|
10
|
+
WorkletsDisplayLink *displayLink_;
|
|
11
|
+
std::vector<std::function<void(double)>> frameCallbacks_;
|
|
12
|
+
std::mutex callbacksMutex_;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
typedef void (^AnimationFrameCallback)(WorkletsDisplayLink *displayLink);
|
|
16
|
+
|
|
17
|
+
#pragma mark-- public
|
|
18
|
+
|
|
19
|
+
- (instancetype)init
|
|
20
|
+
{
|
|
21
|
+
AssertJavaScriptQueue();
|
|
22
|
+
displayLink_ = [WorkletsDisplayLink displayLinkWithTarget:self selector:@selector(executeQueue:)];
|
|
23
|
+
#if TARGET_OS_OSX
|
|
24
|
+
// nothing
|
|
25
|
+
#else // TARGET_OS_OSX
|
|
26
|
+
displayLink_.preferredFramesPerSecond = 120; // will fallback to 60 fps for devices without Pro Motion display
|
|
27
|
+
#endif // TARGET_OS_OSX
|
|
28
|
+
[displayLink_ setPaused:TRUE];
|
|
29
|
+
[displayLink_ addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
|
30
|
+
return self;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
- (void)requestAnimationFrame:(std::function<void(double)>)callback
|
|
34
|
+
{
|
|
35
|
+
{
|
|
36
|
+
std::lock_guard<std::mutex> lock(callbacksMutex_);
|
|
37
|
+
frameCallbacks_.push_back(callback);
|
|
38
|
+
}
|
|
39
|
+
[self scheduleQueueExecution];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
- (void)invalidate
|
|
43
|
+
{
|
|
44
|
+
AssertTurboModuleManagerQueue();
|
|
45
|
+
[displayLink_ invalidate];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#pragma mark-- private
|
|
49
|
+
|
|
50
|
+
- (void)scheduleQueueExecution
|
|
51
|
+
{
|
|
52
|
+
[displayLink_ setPaused:FALSE];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
- (void)executeQueue:(WorkletsDisplayLink *)displayLink
|
|
56
|
+
{
|
|
57
|
+
RCTAssertMainQueue();
|
|
58
|
+
|
|
59
|
+
auto frameCallbacks = [self pullCallbacks];
|
|
60
|
+
[displayLink_ setPaused:TRUE];
|
|
61
|
+
|
|
62
|
+
#if TARGET_OS_OSX
|
|
63
|
+
auto targetTimestamp = displayLink.timestamp + displayLink.duration;
|
|
64
|
+
#else // TARGET_OS_OSX
|
|
65
|
+
auto targetTimestamp = displayLink.targetTimestamp;
|
|
66
|
+
#endif // TARGET_OS_OSX
|
|
67
|
+
targetTimestamp = worklets::calculateTimestampWithSlowAnimations(targetTimestamp);
|
|
68
|
+
|
|
69
|
+
for (const auto &callback : frameCallbacks) {
|
|
70
|
+
callback(targetTimestamp);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
- (std::vector<std::function<void(double)>>)pullCallbacks
|
|
75
|
+
{
|
|
76
|
+
RCTAssertMainQueue();
|
|
77
|
+
std::lock_guard<std::mutex> lock(callbacksMutex_);
|
|
78
|
+
return std::move(frameCallbacks_);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#import <react/debug/react_native_assert.h>
|
|
2
|
+
|
|
3
|
+
// Copied from RCTJSThreadManager.mm
|
|
4
|
+
static NSString *const RCTJSThreadName = @"com.facebook.react.runtime.JavaScript";
|
|
5
|
+
|
|
6
|
+
static BOOL IsJavaScriptQueue()
|
|
7
|
+
{
|
|
8
|
+
return [NSThread.currentThread.name isEqualToString:RCTJSThreadName];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static void AssertJavaScriptQueue()
|
|
12
|
+
{
|
|
13
|
+
react_native_assert(IsJavaScriptQueue() && "This function must be called on the JavaScript queue");
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#import <react/debug/react_native_assert.h>
|
|
2
|
+
|
|
3
|
+
constexpr auto turboModuleManagerQueueLabel =
|
|
4
|
+
"com.meta.react.turbomodulemanager.queue";
|
|
5
|
+
|
|
6
|
+
static bool IsTurboModuleManagerQueue() {
|
|
7
|
+
const auto currentQueueLabel =
|
|
8
|
+
dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL);
|
|
9
|
+
return strcmp(currentQueueLabel, turboModuleManagerQueueLabel) == 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static void AssertTurboModuleManagerQueue() {
|
|
13
|
+
react_native_assert(
|
|
14
|
+
IsTurboModuleManagerQueue() &&
|
|
15
|
+
"This function must be called on the TurboModuleManager queue");
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#import <worklets/Tools/UIScheduler.h>
|
|
2
|
+
|
|
3
|
+
namespace worklets {
|
|
4
|
+
|
|
5
|
+
using namespace facebook;
|
|
6
|
+
using namespace react;
|
|
7
|
+
using namespace worklets;
|
|
8
|
+
|
|
9
|
+
class IOSUIScheduler : public UIScheduler {
|
|
10
|
+
public:
|
|
11
|
+
void scheduleOnUI(std::function<void()> job) override;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
} // namespace worklets
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#import <worklets/apple/IOSUIScheduler.h>
|
|
2
|
+
|
|
3
|
+
namespace worklets {
|
|
4
|
+
|
|
5
|
+
using namespace facebook;
|
|
6
|
+
using namespace react;
|
|
7
|
+
|
|
8
|
+
void IOSUIScheduler::scheduleOnUI(std::function<void()> job)
|
|
9
|
+
{
|
|
10
|
+
if ([NSThread isMainThread]) {
|
|
11
|
+
job();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
UIScheduler::scheduleOnUI(job);
|
|
16
|
+
|
|
17
|
+
if (!scheduledOnUI_) {
|
|
18
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
19
|
+
triggerUI();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
} // namespace worklets
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import <worklets/Tools/PlatformLogger.h>
|
|
3
|
+
|
|
4
|
+
namespace worklets {
|
|
5
|
+
|
|
6
|
+
void PlatformLogger::log(const char *str)
|
|
7
|
+
{
|
|
8
|
+
NSLog(@"%@", [NSString stringWithCString:str encoding:[NSString defaultCStringEncoding]]);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
void PlatformLogger::log(const std::string &str)
|
|
12
|
+
{
|
|
13
|
+
log(str.c_str());
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
void PlatformLogger::log(const double d)
|
|
17
|
+
{
|
|
18
|
+
NSLog(@"%lf", d);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
void PlatformLogger::log(const int i)
|
|
22
|
+
{
|
|
23
|
+
NSLog(@"%i", i);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void PlatformLogger::log(const bool b)
|
|
27
|
+
{
|
|
28
|
+
log(b ? "true" : "false");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
} // namespace worklets
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#import <QuartzCore/QuartzCore.h>
|
|
2
|
+
|
|
3
|
+
#import <worklets/apple/SlowAnimations.h>
|
|
4
|
+
|
|
5
|
+
#if TARGET_IPHONE_SIMULATOR
|
|
6
|
+
#import <dlfcn.h>
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
namespace worklets {
|
|
10
|
+
|
|
11
|
+
CGFloat getUIAnimationDragCoefficient(void)
|
|
12
|
+
{
|
|
13
|
+
static float (*UIAnimationDragCoefficient)(void) = NULL;
|
|
14
|
+
#if TARGET_IPHONE_SIMULATOR
|
|
15
|
+
static dispatch_once_t onceToken;
|
|
16
|
+
dispatch_once(&onceToken, ^{
|
|
17
|
+
UIAnimationDragCoefficient = (float (*)(void))dlsym(RTLD_DEFAULT, "UIAnimationDragCoefficient");
|
|
18
|
+
});
|
|
19
|
+
#endif
|
|
20
|
+
return UIAnimationDragCoefficient ? UIAnimationDragCoefficient() : 1.f;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
CFTimeInterval calculateTimestampWithSlowAnimations(CFTimeInterval currentTimestamp)
|
|
24
|
+
{
|
|
25
|
+
static const auto MILLISECONDS_IN_SECOND = 1000;
|
|
26
|
+
#if TARGET_IPHONE_SIMULATOR
|
|
27
|
+
static CFTimeInterval dragCoefChangedTimestamp = CACurrentMediaTime();
|
|
28
|
+
static CGFloat previousDragCoef = getUIAnimationDragCoefficient();
|
|
29
|
+
|
|
30
|
+
const CGFloat dragCoef = getUIAnimationDragCoefficient();
|
|
31
|
+
if (previousDragCoef != dragCoef) {
|
|
32
|
+
previousDragCoef = dragCoef;
|
|
33
|
+
dragCoefChangedTimestamp = CACurrentMediaTime();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const bool areSlowAnimationsEnabled = dragCoef != 1.f;
|
|
37
|
+
if (areSlowAnimationsEnabled) {
|
|
38
|
+
currentTimestamp = (dragCoefChangedTimestamp + (currentTimestamp - dragCoefChangedTimestamp) / dragCoef);
|
|
39
|
+
}
|
|
40
|
+
currentTimestamp *= MILLISECONDS_IN_SECOND;
|
|
41
|
+
return currentTimestamp;
|
|
42
|
+
#else // TARGET_IPHONE_SIMULATOR
|
|
43
|
+
return currentTimestamp;
|
|
44
|
+
#endif // TARGET_IPHONE_SIMULATOR
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
} // namespace worklets
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#if TARGET_OS_OSX
|
|
2
|
+
|
|
3
|
+
#ifdef __cplusplus
|
|
4
|
+
extern "C" {
|
|
5
|
+
#endif // __cplusplus
|
|
6
|
+
|
|
7
|
+
#import <React/RCTPlatformDisplayLink.h>
|
|
8
|
+
|
|
9
|
+
#ifdef __cplusplus
|
|
10
|
+
}
|
|
11
|
+
#endif // __cplusplus
|
|
12
|
+
|
|
13
|
+
typedef RCTPlatformDisplayLink WorkletsDisplayLink;
|
|
14
|
+
|
|
15
|
+
#else // TARGET_OS_OSX
|
|
16
|
+
|
|
17
|
+
#import <QuartzCore/CADisplayLink.h>
|
|
18
|
+
|
|
19
|
+
typedef CADisplayLink WorkletsDisplayLink;
|
|
20
|
+
|
|
21
|
+
#endif // TARGET_OS_OSX
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
#import <React/RCTMessageThread.h>
|
|
5
|
+
|
|
6
|
+
namespace facebook {
|
|
7
|
+
namespace react {
|
|
8
|
+
|
|
9
|
+
class WorkletsMessageThread : public RCTMessageThread {
|
|
10
|
+
public:
|
|
11
|
+
using RCTMessageThread::RCTMessageThread;
|
|
12
|
+
virtual void quitSynchronous() override;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
} // namespace react
|
|
16
|
+
} // namespace facebook
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#import <worklets/apple/AssertJavaScriptQueue.h>
|
|
2
|
+
#import <worklets/apple/WorkletsMessageThread.h>
|
|
3
|
+
|
|
4
|
+
namespace facebook {
|
|
5
|
+
namespace react {
|
|
6
|
+
|
|
7
|
+
// Essentially the same as RCTMessageThread, but with public fields.
|
|
8
|
+
struct WorkletsMessageThreadPublic {
|
|
9
|
+
// I don't know why we need three vtables (if you know then feel free to explain it instead of this message),
|
|
10
|
+
// but this is what makes the casts in quitSynchronous() work correctly.
|
|
11
|
+
void *vtable1;
|
|
12
|
+
void *vtable2;
|
|
13
|
+
void *vtable3;
|
|
14
|
+
CFRunLoopRef m_cfRunLoop;
|
|
15
|
+
RCTJavaScriptCompleteBlock m_errorBlock;
|
|
16
|
+
std::atomic_bool m_shutdown;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// We need to prevent any new code from being executed on the thread as there
|
|
20
|
+
// is an assertion for that in the destructor of RCTMessageThread, but we have
|
|
21
|
+
// to override quitSynchronous() as it would quit the main looper and freeze
|
|
22
|
+
// the app.
|
|
23
|
+
void WorkletsMessageThread::quitSynchronous()
|
|
24
|
+
{
|
|
25
|
+
AssertJavaScriptQueue();
|
|
26
|
+
RCTMessageThread *rctThread = static_cast<RCTMessageThread *>(this);
|
|
27
|
+
WorkletsMessageThreadPublic *rctThreadPublic = reinterpret_cast<WorkletsMessageThreadPublic *>(rctThread);
|
|
28
|
+
rctThreadPublic->m_shutdown = true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
} // namespace react
|
|
32
|
+
} // namespace facebook
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import <React/RCTCallInvokerModule.h>
|
|
2
|
+
#import <React/RCTEventEmitter.h>
|
|
3
|
+
|
|
4
|
+
#import <worklets/NativeModules/WorkletsModuleProxy.h>
|
|
5
|
+
|
|
6
|
+
@interface WorkletsModule : RCTEventEmitter <RCTCallInvokerModule>
|
|
7
|
+
|
|
8
|
+
- (std::shared_ptr<worklets::WorkletsModuleProxy>)getWorkletsModuleProxy;
|
|
9
|
+
|
|
10
|
+
@end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#import <worklets/Tools/SingleInstanceChecker.h>
|
|
2
|
+
#import <worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h>
|
|
3
|
+
#import <worklets/apple/AnimationFrameQueue.h>
|
|
4
|
+
#import <worklets/apple/AssertJavaScriptQueue.h>
|
|
5
|
+
#import <worklets/apple/AssertTurboModuleManagerQueue.h>
|
|
6
|
+
#import <worklets/apple/IOSUIScheduler.h>
|
|
7
|
+
#import <worklets/apple/WorkletsMessageThread.h>
|
|
8
|
+
#import <worklets/apple/WorkletsModule.h>
|
|
9
|
+
|
|
10
|
+
#import <React/RCTCallInvoker.h>
|
|
11
|
+
|
|
12
|
+
using worklets::RNRuntimeWorkletDecorator;
|
|
13
|
+
using worklets::WorkletsModuleProxy;
|
|
14
|
+
|
|
15
|
+
@interface RCTBridge (JSIRuntime)
|
|
16
|
+
- (void *)runtime;
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@implementation WorkletsModule {
|
|
20
|
+
AnimationFrameQueue *animationFrameQueue_;
|
|
21
|
+
std::shared_ptr<WorkletsModuleProxy> workletsModuleProxy_;
|
|
22
|
+
#ifndef NDEBUG
|
|
23
|
+
worklets::SingleInstanceChecker<WorkletsModule> singleInstanceChecker_;
|
|
24
|
+
#endif // NDEBUG
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
- (std::shared_ptr<WorkletsModuleProxy>)getWorkletsModuleProxy
|
|
28
|
+
{
|
|
29
|
+
AssertJavaScriptQueue();
|
|
30
|
+
return workletsModuleProxy_;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@synthesize callInvoker = _callInvoker;
|
|
34
|
+
|
|
35
|
+
RCT_EXPORT_MODULE(WorkletsModule);
|
|
36
|
+
|
|
37
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(installTurboModule : (nonnull NSString *)valueUnpackerCode)
|
|
38
|
+
{
|
|
39
|
+
AssertJavaScriptQueue();
|
|
40
|
+
|
|
41
|
+
react_native_assert(self.bridge != nullptr);
|
|
42
|
+
react_native_assert(self.bridge.runtime != nullptr);
|
|
43
|
+
jsi::Runtime &rnRuntime = *reinterpret_cast<facebook::jsi::Runtime *>(self.bridge.runtime);
|
|
44
|
+
|
|
45
|
+
auto jsQueue = std::make_shared<WorkletsMessageThread>([NSRunLoop currentRunLoop], ^(NSError *error) {
|
|
46
|
+
throw error;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
std::string valueUnpackerCodeStr = [valueUnpackerCode UTF8String];
|
|
50
|
+
auto jsCallInvoker = _callInvoker.callInvoker;
|
|
51
|
+
auto jsScheduler = std::make_shared<worklets::JSScheduler>(rnRuntime, jsCallInvoker);
|
|
52
|
+
auto uiScheduler = std::make_shared<worklets::IOSUIScheduler>();
|
|
53
|
+
animationFrameQueue_ = [AnimationFrameQueue new];
|
|
54
|
+
auto forwardedRequestAnimationFrame = std::function<void(std::function<void(const double)>)>(
|
|
55
|
+
[animationFrameQueue = animationFrameQueue_](std::function<void(const double)> callback) {
|
|
56
|
+
[animationFrameQueue requestAnimationFrame:callback];
|
|
57
|
+
});
|
|
58
|
+
workletsModuleProxy_ = std::make_shared<WorkletsModuleProxy>(
|
|
59
|
+
rnRuntime,
|
|
60
|
+
valueUnpackerCodeStr,
|
|
61
|
+
jsQueue,
|
|
62
|
+
jsCallInvoker,
|
|
63
|
+
jsScheduler,
|
|
64
|
+
uiScheduler,
|
|
65
|
+
std::move(forwardedRequestAnimationFrame));
|
|
66
|
+
RNRuntimeWorkletDecorator::decorate(rnRuntime, workletsModuleProxy_);
|
|
67
|
+
|
|
68
|
+
return @YES;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
- (void)invalidate
|
|
72
|
+
{
|
|
73
|
+
AssertTurboModuleManagerQueue();
|
|
74
|
+
|
|
75
|
+
[animationFrameQueue_ invalidate];
|
|
76
|
+
|
|
77
|
+
// We have to destroy extra runtimes when invalidate is called. If we clean
|
|
78
|
+
// it up later instead there's a chance the runtime will retain references
|
|
79
|
+
// to invalidated memory and will crash on destruction.
|
|
80
|
+
workletsModuleProxy_.reset();
|
|
81
|
+
|
|
82
|
+
[super invalidate];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@end
|