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,85 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.8)
|
|
2
|
+
|
|
3
|
+
file(GLOB_RECURSE WORKLETS_COMMON_CPP_SOURCES CONFIGURE_DEPENDS
|
|
4
|
+
"${COMMON_CPP_DIR}/worklets/*.cpp")
|
|
5
|
+
file(GLOB_RECURSE WORKLETS_ANDROID_CPP_SOURCES CONFIGURE_DEPENDS
|
|
6
|
+
"${ANDROID_CPP_DIR}/worklets/*.cpp")
|
|
7
|
+
|
|
8
|
+
# Consume shared libraries and headers from prefabs
|
|
9
|
+
find_package(fbjni REQUIRED CONFIG)
|
|
10
|
+
find_package(ReactAndroid REQUIRED CONFIG)
|
|
11
|
+
|
|
12
|
+
if(${JS_RUNTIME} STREQUAL "hermes")
|
|
13
|
+
find_package(hermes-engine REQUIRED CONFIG)
|
|
14
|
+
endif()
|
|
15
|
+
|
|
16
|
+
add_library(worklets SHARED ${WORKLETS_COMMON_CPP_SOURCES}
|
|
17
|
+
${WORKLETS_ANDROID_CPP_SOURCES})
|
|
18
|
+
|
|
19
|
+
# includes
|
|
20
|
+
target_include_directories(worklets PUBLIC "${COMMON_CPP_DIR}"
|
|
21
|
+
"${ANDROID_CPP_DIR}")
|
|
22
|
+
|
|
23
|
+
target_include_directories(
|
|
24
|
+
worklets
|
|
25
|
+
PRIVATE "${REACT_NATIVE_DIR}/ReactCommon"
|
|
26
|
+
"${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react/turbomodule"
|
|
27
|
+
"${REACT_NATIVE_DIR}/ReactCommon/react/nativemodule/core/ReactCommon"
|
|
28
|
+
"${REACT_NATIVE_DIR}/ReactCommon/callinvoker"
|
|
29
|
+
"${REACT_NATIVE_DIR}/ReactCommon/runtimeexecutor")
|
|
30
|
+
|
|
31
|
+
if(${IS_NEW_ARCHITECTURE_ENABLED})
|
|
32
|
+
target_include_directories(
|
|
33
|
+
worklets
|
|
34
|
+
PRIVATE
|
|
35
|
+
"${REACT_NATIVE_DIR}/ReactCommon/yoga"
|
|
36
|
+
"${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx")
|
|
37
|
+
|
|
38
|
+
if(ReactAndroid_VERSION_MINOR LESS 76)
|
|
39
|
+
target_link_libraries(
|
|
40
|
+
worklets ReactAndroid::fabricjni ReactAndroid::react_debug
|
|
41
|
+
ReactAndroid::react_render_core
|
|
42
|
+
ReactAndroid::react_render_componentregistry ReactAndroid::rrc_view)
|
|
43
|
+
endif()
|
|
44
|
+
endif()
|
|
45
|
+
|
|
46
|
+
# build shared lib
|
|
47
|
+
set_target_properties(worklets PROPERTIES LINKER_LANGUAGE CXX)
|
|
48
|
+
|
|
49
|
+
target_link_libraries(worklets log ReactAndroid::jsi fbjni::fbjni)
|
|
50
|
+
|
|
51
|
+
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
|
52
|
+
target_link_libraries(worklets ReactAndroid::reactnative)
|
|
53
|
+
else()
|
|
54
|
+
target_link_libraries(
|
|
55
|
+
worklets ReactAndroid::react_nativemodule_core ReactAndroid::folly_runtime
|
|
56
|
+
ReactAndroid::glog ReactAndroid::reactnativejni)
|
|
57
|
+
endif()
|
|
58
|
+
|
|
59
|
+
if(${JS_RUNTIME} STREQUAL "hermes")
|
|
60
|
+
target_link_libraries(worklets hermes-engine::libhermes)
|
|
61
|
+
|
|
62
|
+
if(${HERMES_ENABLE_DEBUGGER})
|
|
63
|
+
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
|
64
|
+
target_link_libraries(worklets ReactAndroid::hermestooling)
|
|
65
|
+
else()
|
|
66
|
+
target_link_libraries(worklets ReactAndroid::hermes_executor)
|
|
67
|
+
endif()
|
|
68
|
+
endif()
|
|
69
|
+
elseif(${JS_RUNTIME} STREQUAL "jsc")
|
|
70
|
+
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
|
71
|
+
target_link_libraries(worklets ReactAndroid::jsctooling)
|
|
72
|
+
else()
|
|
73
|
+
target_link_libraries(worklets ReactAndroid::jscexecutor)
|
|
74
|
+
endif()
|
|
75
|
+
elseif(${JS_RUNTIME} STREQUAL "v8")
|
|
76
|
+
# TODO: Refactor this when adding support for newest V8
|
|
77
|
+
target_include_directories(worklets PRIVATE "${JS_RUNTIME_DIR}/src")
|
|
78
|
+
file(GLOB V8_SO_DIR "${JS_RUNTIME_DIR}/android/build/intermediates/\
|
|
79
|
+
library_jni/**/jni/${ANDROID_ABI}")
|
|
80
|
+
find_library(
|
|
81
|
+
V8EXECUTOR_LIB v8executor
|
|
82
|
+
PATHS ${V8_SO_DIR}
|
|
83
|
+
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
|
84
|
+
target_link_libraries(worklets ${V8EXECUTOR_LIB})
|
|
85
|
+
endif()
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#include <worklets/android/AndroidUIScheduler.h>
|
|
2
|
+
|
|
3
|
+
namespace worklets {
|
|
4
|
+
|
|
5
|
+
using namespace facebook;
|
|
6
|
+
using namespace react;
|
|
7
|
+
|
|
8
|
+
class UISchedulerWrapper : public UIScheduler {
|
|
9
|
+
private:
|
|
10
|
+
jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler_;
|
|
11
|
+
|
|
12
|
+
public:
|
|
13
|
+
explicit UISchedulerWrapper(
|
|
14
|
+
jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler)
|
|
15
|
+
: androidUiScheduler_(androidUiScheduler) {}
|
|
16
|
+
|
|
17
|
+
void scheduleOnUI(std::function<void()> job) override {
|
|
18
|
+
UIScheduler::scheduleOnUI(job);
|
|
19
|
+
if (!scheduledOnUI_) {
|
|
20
|
+
scheduledOnUI_ = true;
|
|
21
|
+
androidUiScheduler_->cthis()->scheduleTriggerOnUI();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
AndroidUIScheduler::AndroidUIScheduler(
|
|
27
|
+
jni::alias_ref<AndroidUIScheduler::javaobject> jThis)
|
|
28
|
+
: javaPart_(jni::make_global(jThis)),
|
|
29
|
+
uiScheduler_(
|
|
30
|
+
std::make_shared<UISchedulerWrapper>(jni::make_global(jThis))) {}
|
|
31
|
+
|
|
32
|
+
jni::local_ref<AndroidUIScheduler::jhybriddata> AndroidUIScheduler::initHybrid(
|
|
33
|
+
jni::alias_ref<jhybridobject> jThis) {
|
|
34
|
+
return makeCxxInstance(jThis);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
void AndroidUIScheduler::triggerUI() {
|
|
38
|
+
if (!uiScheduler_) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
uiScheduler_->triggerUI();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void AndroidUIScheduler::scheduleTriggerOnUI() {
|
|
45
|
+
static const auto method =
|
|
46
|
+
javaPart_->getClass()->getMethod<void()>("scheduleTriggerOnUI");
|
|
47
|
+
method(javaPart_.get());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
void AndroidUIScheduler::invalidate() {
|
|
51
|
+
javaPart_ = nullptr;
|
|
52
|
+
uiScheduler_.reset();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
void AndroidUIScheduler::registerNatives() {
|
|
56
|
+
registerHybrid({
|
|
57
|
+
makeNativeMethod("initHybrid", AndroidUIScheduler::initHybrid),
|
|
58
|
+
makeNativeMethod("triggerUI", AndroidUIScheduler::triggerUI),
|
|
59
|
+
makeNativeMethod("invalidate", AndroidUIScheduler::invalidate),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
} // namespace worklets
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <worklets/Tools/UIScheduler.h>
|
|
4
|
+
|
|
5
|
+
#include <fbjni/fbjni.h>
|
|
6
|
+
#include <jsi/jsi.h>
|
|
7
|
+
|
|
8
|
+
namespace worklets {
|
|
9
|
+
|
|
10
|
+
using namespace facebook;
|
|
11
|
+
using namespace worklets;
|
|
12
|
+
|
|
13
|
+
class AndroidUIScheduler : public jni::HybridClass<AndroidUIScheduler> {
|
|
14
|
+
public:
|
|
15
|
+
static auto constexpr kJavaDescriptor =
|
|
16
|
+
"Lcom/swmansion/worklets/AndroidUIScheduler;";
|
|
17
|
+
static jni::local_ref<jhybriddata> initHybrid(
|
|
18
|
+
jni::alias_ref<jhybridobject> jThis);
|
|
19
|
+
static void registerNatives();
|
|
20
|
+
|
|
21
|
+
std::shared_ptr<UIScheduler> getUIScheduler() {
|
|
22
|
+
return uiScheduler_;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
void scheduleTriggerOnUI();
|
|
26
|
+
|
|
27
|
+
private:
|
|
28
|
+
friend HybridBase;
|
|
29
|
+
|
|
30
|
+
void triggerUI();
|
|
31
|
+
|
|
32
|
+
void invalidate();
|
|
33
|
+
|
|
34
|
+
jni::global_ref<AndroidUIScheduler::javaobject> javaPart_;
|
|
35
|
+
std::shared_ptr<UIScheduler> uiScheduler_;
|
|
36
|
+
|
|
37
|
+
explicit AndroidUIScheduler(
|
|
38
|
+
jni::alias_ref<AndroidUIScheduler::jhybridobject> jThis);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
} // namespace worklets
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <fbjni/fbjni.h>
|
|
4
|
+
|
|
5
|
+
namespace worklets {
|
|
6
|
+
|
|
7
|
+
class AnimationFrameCallback
|
|
8
|
+
: public facebook::jni::HybridClass<AnimationFrameCallback> {
|
|
9
|
+
public:
|
|
10
|
+
static auto constexpr kJavaDescriptor =
|
|
11
|
+
"Lcom/swmansion/worklets/AnimationFrameCallback;";
|
|
12
|
+
|
|
13
|
+
void onAnimationFrame(double timestampMs) {
|
|
14
|
+
callback_(timestampMs);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static void registerNatives() {
|
|
18
|
+
javaClassStatic()->registerNatives({
|
|
19
|
+
makeNativeMethod(
|
|
20
|
+
"onAnimationFrame", AnimationFrameCallback::onAnimationFrame),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private:
|
|
25
|
+
friend HybridBase;
|
|
26
|
+
|
|
27
|
+
explicit AnimationFrameCallback(std::function<void(const double)> callback)
|
|
28
|
+
: callback_(std::move(callback)) {}
|
|
29
|
+
|
|
30
|
+
std::function<void(double)> callback_;
|
|
31
|
+
};
|
|
32
|
+
} // namespace worklets
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#include <android/log.h>
|
|
2
|
+
|
|
3
|
+
#include <worklets/Tools/PlatformLogger.h>
|
|
4
|
+
|
|
5
|
+
constexpr const auto tag = "Worklets";
|
|
6
|
+
|
|
7
|
+
namespace worklets {
|
|
8
|
+
|
|
9
|
+
void PlatformLogger::log(const char *str) {
|
|
10
|
+
__android_log_print(ANDROID_LOG_VERBOSE, tag, "%s", str);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
void PlatformLogger::log(const std::string &str) {
|
|
14
|
+
log(str.c_str());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
void PlatformLogger::log(const double d) {
|
|
18
|
+
__android_log_print(ANDROID_LOG_VERBOSE, tag, "%f", d);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
void PlatformLogger::log(const int i) {
|
|
22
|
+
__android_log_print(ANDROID_LOG_VERBOSE, tag, "%d", i);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
void PlatformLogger::log(const bool b) {
|
|
26
|
+
log(b ? "true" : "false");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
} // namespace worklets
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#include <react/jni/JMessageQueueThread.h>
|
|
2
|
+
|
|
3
|
+
#include <worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h>
|
|
4
|
+
#include <worklets/android/AnimationFrameCallback.h>
|
|
5
|
+
#include <worklets/android/WorkletsModule.h>
|
|
6
|
+
|
|
7
|
+
namespace worklets {
|
|
8
|
+
|
|
9
|
+
using namespace facebook;
|
|
10
|
+
using namespace react;
|
|
11
|
+
|
|
12
|
+
WorkletsModule::WorkletsModule(
|
|
13
|
+
jni::alias_ref<jhybridobject> jThis,
|
|
14
|
+
jsi::Runtime *rnRuntime,
|
|
15
|
+
const std::string &valueUnpackerCode,
|
|
16
|
+
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
|
|
17
|
+
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker,
|
|
18
|
+
const std::shared_ptr<worklets::JSScheduler> &jsScheduler,
|
|
19
|
+
const std::shared_ptr<UIScheduler> &uiScheduler)
|
|
20
|
+
: javaPart_(jni::make_global(jThis)),
|
|
21
|
+
rnRuntime_(rnRuntime),
|
|
22
|
+
workletsModuleProxy_(std::make_shared<WorkletsModuleProxy>(
|
|
23
|
+
*rnRuntime,
|
|
24
|
+
valueUnpackerCode,
|
|
25
|
+
std::make_shared<JMessageQueueThread>(messageQueueThread),
|
|
26
|
+
jsCallInvoker,
|
|
27
|
+
jsScheduler,
|
|
28
|
+
uiScheduler,
|
|
29
|
+
getForwardedRequestAnimationFrame())) {
|
|
30
|
+
RNRuntimeWorkletDecorator::decorate(*rnRuntime_, workletsModuleProxy_);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
jni::local_ref<WorkletsModule::jhybriddata> WorkletsModule::initHybrid(
|
|
34
|
+
jni::alias_ref<jhybridobject> jThis,
|
|
35
|
+
jlong jsContext,
|
|
36
|
+
const std::string &valueUnpackerCode,
|
|
37
|
+
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
|
|
38
|
+
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
|
|
39
|
+
jsCallInvokerHolder,
|
|
40
|
+
jni::alias_ref<worklets::AndroidUIScheduler::javaobject>
|
|
41
|
+
androidUIScheduler) {
|
|
42
|
+
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
|
|
43
|
+
auto rnRuntime = reinterpret_cast<jsi::Runtime *>(jsContext);
|
|
44
|
+
auto jsScheduler =
|
|
45
|
+
std::make_shared<worklets::JSScheduler>(*rnRuntime, jsCallInvoker);
|
|
46
|
+
auto uiScheduler = androidUIScheduler->cthis()->getUIScheduler();
|
|
47
|
+
return makeCxxInstance(
|
|
48
|
+
jThis,
|
|
49
|
+
rnRuntime,
|
|
50
|
+
valueUnpackerCode,
|
|
51
|
+
messageQueueThread,
|
|
52
|
+
jsCallInvoker,
|
|
53
|
+
jsScheduler,
|
|
54
|
+
uiScheduler);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
std::function<void(std::function<void(const double)>)>
|
|
58
|
+
WorkletsModule::getForwardedRequestAnimationFrame() {
|
|
59
|
+
return [javaPart =
|
|
60
|
+
javaPart_](std::function<void(const double)> &&callback) -> void {
|
|
61
|
+
static const auto jRequestAnimationFrame =
|
|
62
|
+
javaPart->getClass()
|
|
63
|
+
->getMethod<void(AnimationFrameCallback::javaobject)>(
|
|
64
|
+
"requestAnimationFrame");
|
|
65
|
+
jRequestAnimationFrame(
|
|
66
|
+
javaPart.get(),
|
|
67
|
+
AnimationFrameCallback::newObjectCxxArgs(std::move(callback)).get());
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
void WorkletsModule::invalidateCpp() {
|
|
72
|
+
javaPart_.reset();
|
|
73
|
+
workletsModuleProxy_.reset();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void WorkletsModule::registerNatives() {
|
|
77
|
+
registerHybrid({
|
|
78
|
+
makeNativeMethod("initHybrid", WorkletsModule::initHybrid),
|
|
79
|
+
makeNativeMethod("invalidateCpp", WorkletsModule::invalidateCpp),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
} // namespace worklets
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <ReactCommon/CallInvokerHolder.h>
|
|
4
|
+
#include <fbjni/fbjni.h>
|
|
5
|
+
#include <jsi/jsi.h>
|
|
6
|
+
#include <react/jni/JMessageQueueThread.h>
|
|
7
|
+
|
|
8
|
+
#include <worklets/NativeModules/WorkletsModuleProxy.h>
|
|
9
|
+
#include <worklets/android/AndroidUIScheduler.h>
|
|
10
|
+
|
|
11
|
+
namespace worklets {
|
|
12
|
+
|
|
13
|
+
using namespace facebook;
|
|
14
|
+
using namespace facebook::jni;
|
|
15
|
+
|
|
16
|
+
class WorkletsModule : public jni::HybridClass<WorkletsModule> {
|
|
17
|
+
public:
|
|
18
|
+
static auto constexpr kJavaDescriptor =
|
|
19
|
+
"Lcom/swmansion/worklets/WorkletsModule;";
|
|
20
|
+
|
|
21
|
+
static jni::local_ref<jhybriddata> initHybrid(
|
|
22
|
+
jni::alias_ref<jhybridobject> jThis,
|
|
23
|
+
jlong jsContext,
|
|
24
|
+
const std::string &valueUnpackerCode,
|
|
25
|
+
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
|
|
26
|
+
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
|
|
27
|
+
jsCallInvokerHolder,
|
|
28
|
+
jni::alias_ref<worklets::AndroidUIScheduler::javaobject>
|
|
29
|
+
androidUIScheduler);
|
|
30
|
+
|
|
31
|
+
static void registerNatives();
|
|
32
|
+
|
|
33
|
+
inline std::shared_ptr<WorkletsModuleProxy> getWorkletsModuleProxy() {
|
|
34
|
+
return workletsModuleProxy_;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private:
|
|
38
|
+
explicit WorkletsModule(
|
|
39
|
+
jni::alias_ref<jhybridobject> jThis,
|
|
40
|
+
jsi::Runtime *rnRuntime,
|
|
41
|
+
const std::string &valueUnpackerCode,
|
|
42
|
+
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
|
|
43
|
+
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker,
|
|
44
|
+
const std::shared_ptr<worklets::JSScheduler> &jsScheduler,
|
|
45
|
+
const std::shared_ptr<UIScheduler> &uiScheduler);
|
|
46
|
+
|
|
47
|
+
void invalidateCpp();
|
|
48
|
+
|
|
49
|
+
template <class Signature>
|
|
50
|
+
JMethod<Signature> getJniMethod(std::string const &methodName) {
|
|
51
|
+
return javaPart_->getClass()->getMethod<Signature>(methodName.c_str());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
std::function<void(std::function<void(const double)>)>
|
|
55
|
+
getForwardedRequestAnimationFrame();
|
|
56
|
+
|
|
57
|
+
friend HybridBase;
|
|
58
|
+
jni::global_ref<WorkletsModule::javaobject> javaPart_;
|
|
59
|
+
jsi::Runtime *rnRuntime_;
|
|
60
|
+
std::shared_ptr<WorkletsModuleProxy> workletsModuleProxy_;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
} // namespace worklets
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#include <fbjni/fbjni.h>
|
|
2
|
+
|
|
3
|
+
#include <worklets/android/AndroidUIScheduler.h>
|
|
4
|
+
#include <worklets/android/AnimationFrameCallback.h>
|
|
5
|
+
#include <worklets/android/WorkletsModule.h>
|
|
6
|
+
|
|
7
|
+
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
|
8
|
+
return facebook::jni::initialize(vm, [] {
|
|
9
|
+
worklets::WorkletsModule::registerNatives();
|
|
10
|
+
worklets::AndroidUIScheduler::registerNatives();
|
|
11
|
+
worklets::AnimationFrameCallback::registerNatives();
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import com.facebook.jni.HybridData;
|
|
4
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
5
|
+
import com.facebook.react.bridge.GuardedRunnable;
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
7
|
+
import com.facebook.react.bridge.UiThreadUtil;
|
|
8
|
+
import java.util.concurrent.atomic.AtomicBoolean;
|
|
9
|
+
|
|
10
|
+
public class AndroidUIScheduler {
|
|
11
|
+
|
|
12
|
+
@DoNotStrip
|
|
13
|
+
@SuppressWarnings("unused")
|
|
14
|
+
private final HybridData mHybridData;
|
|
15
|
+
|
|
16
|
+
private final ReactApplicationContext mContext;
|
|
17
|
+
private final AtomicBoolean mActive = new AtomicBoolean(true);
|
|
18
|
+
|
|
19
|
+
private final Runnable mUIThreadRunnable =
|
|
20
|
+
() -> {
|
|
21
|
+
/**
|
|
22
|
+
* This callback is called on the UI thread, but the module is invalidated on the JS thread.
|
|
23
|
+
* Therefore we must synchronize for reloads. Without synchronization the cpp part gets torn
|
|
24
|
+
* down while the UI thread is still executing it, leading to crashes.
|
|
25
|
+
*/
|
|
26
|
+
synchronized (mActive) {
|
|
27
|
+
if (mActive.get()) {
|
|
28
|
+
triggerUI();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
public AndroidUIScheduler(ReactApplicationContext context) {
|
|
34
|
+
mHybridData = initHybrid();
|
|
35
|
+
mContext = context;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private native HybridData initHybrid();
|
|
39
|
+
|
|
40
|
+
public native void triggerUI();
|
|
41
|
+
|
|
42
|
+
public native void invalidate();
|
|
43
|
+
|
|
44
|
+
@DoNotStrip
|
|
45
|
+
private void scheduleTriggerOnUI() {
|
|
46
|
+
UiThreadUtil.runOnUiThread(
|
|
47
|
+
new GuardedRunnable(mContext.getExceptionHandler()) {
|
|
48
|
+
public void runGuarded() {
|
|
49
|
+
mUIThreadRunnable.run();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public void deactivate() {
|
|
55
|
+
synchronized (mActive) {
|
|
56
|
+
mActive.set(false);
|
|
57
|
+
invalidate();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
package/android/src/main/java/com/swmansion/worklets/AnimationFrameQueue/AnimationFrameCallback.java
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import com.facebook.jni.HybridData;
|
|
4
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @noinspection JavaJniMissingFunction
|
|
8
|
+
*/
|
|
9
|
+
@DoNotStrip
|
|
10
|
+
public class AnimationFrameCallback {
|
|
11
|
+
|
|
12
|
+
@DoNotStrip private final HybridData mHybridData;
|
|
13
|
+
|
|
14
|
+
@DoNotStrip
|
|
15
|
+
private AnimationFrameCallback(HybridData hybridData) {
|
|
16
|
+
mHybridData = hybridData;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public native void onAnimationFrame(double timestampMs);
|
|
20
|
+
}
|
package/android/src/main/java/com/swmansion/worklets/AnimationFrameQueue/AnimationFrameQueue.java
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import android.os.SystemClock;
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
5
|
+
import com.facebook.react.modules.core.ReactChoreographer;
|
|
6
|
+
import com.facebook.react.uimanager.GuardedFrameCallback;
|
|
7
|
+
import java.util.ArrayList;
|
|
8
|
+
import java.util.List;
|
|
9
|
+
import java.util.concurrent.atomic.AtomicBoolean;
|
|
10
|
+
|
|
11
|
+
public class AnimationFrameQueue {
|
|
12
|
+
|
|
13
|
+
private Long mFirstUptime = SystemClock.uptimeMillis();
|
|
14
|
+
private boolean mSlowAnimationsEnabled = false;
|
|
15
|
+
private double lastFrameTimeMs;
|
|
16
|
+
private int mAnimationsDragFactor = 1;
|
|
17
|
+
|
|
18
|
+
/// ReactChoreographer is
|
|
19
|
+
/// <a
|
|
20
|
+
// href="https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/ReactChoreographer.kt#L21">thread safe</a>.
|
|
21
|
+
///
|
|
22
|
+
private final ReactChoreographer mReactChoreographer = ReactChoreographer.getInstance();
|
|
23
|
+
private final GuardedFrameCallback mChoreographerCallback;
|
|
24
|
+
private final AtomicBoolean mCallbackPosted = new AtomicBoolean();
|
|
25
|
+
private final AtomicBoolean mPaused = new AtomicBoolean();
|
|
26
|
+
private final List<AnimationFrameCallback> mFrameCallbacks = new ArrayList<>();
|
|
27
|
+
|
|
28
|
+
public AnimationFrameQueue(ReactApplicationContext reactApplicationContext) {
|
|
29
|
+
mChoreographerCallback =
|
|
30
|
+
new GuardedFrameCallback(reactApplicationContext) {
|
|
31
|
+
@Override
|
|
32
|
+
protected void doFrameGuarded(long frameTimeNanos) {
|
|
33
|
+
executeQueue(frameTimeNanos);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public void resume() {
|
|
39
|
+
if (mPaused.getAndSet(false)) {
|
|
40
|
+
scheduleQueueExecution();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public void pause() {
|
|
45
|
+
synchronized (mPaused) {
|
|
46
|
+
if (!mPaused.getAndSet(true) && mCallbackPosted.getAndSet(false)) {
|
|
47
|
+
mReactChoreographer.removeFrameCallback(
|
|
48
|
+
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, mChoreographerCallback);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public void requestAnimationFrame(AnimationFrameCallback animationFrameCallback) {
|
|
54
|
+
synchronized (mFrameCallbacks) {
|
|
55
|
+
mFrameCallbacks.add(animationFrameCallback);
|
|
56
|
+
}
|
|
57
|
+
scheduleQueueExecution();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public void enableSlowAnimations(boolean slowAnimationsEnabled, int animationsDragFactor) {
|
|
61
|
+
mSlowAnimationsEnabled = slowAnimationsEnabled;
|
|
62
|
+
mAnimationsDragFactor = animationsDragFactor;
|
|
63
|
+
if (slowAnimationsEnabled) {
|
|
64
|
+
mFirstUptime = SystemClock.uptimeMillis();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private void scheduleQueueExecution() {
|
|
69
|
+
synchronized (mPaused) {
|
|
70
|
+
if (!mPaused.get() && !mCallbackPosted.getAndSet(true)) {
|
|
71
|
+
mReactChoreographer.postFrameCallback(
|
|
72
|
+
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, mChoreographerCallback);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private void executeQueue(long frameTimeNanos) {
|
|
78
|
+
double currentFrameTimeMs = calculateTimestamp(frameTimeNanos);
|
|
79
|
+
if (currentFrameTimeMs <= lastFrameTimeMs) {
|
|
80
|
+
// It is possible for ChoreographerCallback to be executed twice within the same frame
|
|
81
|
+
// due to frame drops. If this occurs, the additional callback execution should be ignored.
|
|
82
|
+
mCallbackPosted.set(false);
|
|
83
|
+
scheduleQueueExecution();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var frameCallbacks = pullCallbacks();
|
|
88
|
+
mCallbackPosted.set(false);
|
|
89
|
+
|
|
90
|
+
lastFrameTimeMs = currentFrameTimeMs;
|
|
91
|
+
for (var callback : frameCallbacks) {
|
|
92
|
+
callback.onAnimationFrame(currentFrameTimeMs);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private List<AnimationFrameCallback> pullCallbacks() {
|
|
97
|
+
synchronized (mFrameCallbacks) {
|
|
98
|
+
List<AnimationFrameCallback> frameCallbacks = new ArrayList<>(mFrameCallbacks);
|
|
99
|
+
mFrameCallbacks.clear();
|
|
100
|
+
return frameCallbacks;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private double calculateTimestamp(long frameTimeNanos) {
|
|
105
|
+
final double NANOSECONDS_IN_MILLISECONDS = 1000000;
|
|
106
|
+
double currentFrameTimeMs = frameTimeNanos / NANOSECONDS_IN_MILLISECONDS;
|
|
107
|
+
if (mSlowAnimationsEnabled) {
|
|
108
|
+
currentFrameTimeMs =
|
|
109
|
+
mFirstUptime + (currentFrameTimeMs - mFirstUptime) / mAnimationsDragFactor;
|
|
110
|
+
}
|
|
111
|
+
return currentFrameTimeMs;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.OptIn;
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
5
|
+
import com.facebook.react.common.annotations.FrameworkAPI;
|
|
6
|
+
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
|
|
7
|
+
|
|
8
|
+
public class JSCallInvokerResolver {
|
|
9
|
+
|
|
10
|
+
@OptIn(markerClass = FrameworkAPI.class)
|
|
11
|
+
public static CallInvokerHolderImpl getJSCallInvokerHolder(ReactApplicationContext context) {
|
|
12
|
+
try {
|
|
13
|
+
var method = context.getClass().getMethod("getJSCallInvokerHolder");
|
|
14
|
+
return (CallInvokerHolderImpl) method.invoke(context);
|
|
15
|
+
} catch (Exception ignored) {
|
|
16
|
+
// In newer implementations, the method is in CatalystInstance, continue.
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
var catalystInstance = context.getClass().getMethod("getCatalystInstance").invoke(context);
|
|
20
|
+
assert catalystInstance != null;
|
|
21
|
+
var method = catalystInstance.getClass().getMethod("getJSCallInvokerHolder");
|
|
22
|
+
return (CallInvokerHolderImpl) method.invoke(catalystInstance);
|
|
23
|
+
} catch (Exception e) {
|
|
24
|
+
throw new RuntimeException("Failed to get JSCallInvokerHolder", e);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.swmansion.worklets;
|
|
2
|
+
|
|
3
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
4
|
+
|
|
5
|
+
@DoNotStrip
|
|
6
|
+
public class WorkletsMessageQueueThread extends WorkletsMessageQueueThreadBase {
|
|
7
|
+
@Override
|
|
8
|
+
public boolean runOnQueue(Runnable runnable) {
|
|
9
|
+
return messageQueueThread.runOnQueue(runnable);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@Override
|
|
13
|
+
public boolean isIdle() {
|
|
14
|
+
return messageQueueThread.isIdle();
|
|
15
|
+
}
|
|
16
|
+
}
|