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,49 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <condition_variable>
|
|
4
|
+
#include <mutex>
|
|
5
|
+
#include <queue>
|
|
6
|
+
#include <utility>
|
|
7
|
+
|
|
8
|
+
namespace worklets {
|
|
9
|
+
|
|
10
|
+
//
|
|
11
|
+
// Copyright (c) 2013 Juan Palacios juan.palacios.puyana@gmail.com
|
|
12
|
+
// Subject to the BSD 2-Clause License
|
|
13
|
+
// - see < https://opensource.org/license/bsd-2-clause/ >
|
|
14
|
+
//
|
|
15
|
+
template <typename T>
|
|
16
|
+
class ThreadSafeQueue {
|
|
17
|
+
public:
|
|
18
|
+
T pop() {
|
|
19
|
+
std::unique_lock<std::mutex> mlock(mutex_);
|
|
20
|
+
while (queue_.empty()) {
|
|
21
|
+
cond_.wait(mlock);
|
|
22
|
+
}
|
|
23
|
+
const auto item = queue_.front();
|
|
24
|
+
queue_.pop();
|
|
25
|
+
return item;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
void push(T &&item) {
|
|
29
|
+
std::unique_lock<std::mutex> mlock(mutex_);
|
|
30
|
+
queue_.push(std::move(item));
|
|
31
|
+
mlock.unlock();
|
|
32
|
+
cond_.notify_one();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
bool empty() const {
|
|
36
|
+
std::unique_lock<std::mutex> mlock(mutex_);
|
|
37
|
+
const auto res = queue_.empty();
|
|
38
|
+
mlock.unlock();
|
|
39
|
+
cond_.notify_one();
|
|
40
|
+
return res;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private:
|
|
44
|
+
std::queue<T> queue_;
|
|
45
|
+
mutable std::mutex mutex_;
|
|
46
|
+
mutable std::condition_variable cond_;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
} // namespace worklets
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#include <worklets/Tools/UIScheduler.h>
|
|
2
|
+
|
|
3
|
+
#include <utility>
|
|
4
|
+
|
|
5
|
+
namespace worklets {
|
|
6
|
+
|
|
7
|
+
void UIScheduler::scheduleOnUI(std::function<void()> job) {
|
|
8
|
+
uiJobs_.push(std::move(job));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
void UIScheduler::triggerUI() {
|
|
12
|
+
scheduledOnUI_ = false;
|
|
13
|
+
while (!uiJobs_.empty()) {
|
|
14
|
+
const auto job = uiJobs_.pop();
|
|
15
|
+
job();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
} // namespace worklets
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <worklets/Tools/ThreadSafeQueue.h>
|
|
4
|
+
|
|
5
|
+
#include <ReactCommon/CallInvoker.h>
|
|
6
|
+
|
|
7
|
+
#include <atomic>
|
|
8
|
+
|
|
9
|
+
namespace worklets {
|
|
10
|
+
|
|
11
|
+
class UIScheduler {
|
|
12
|
+
public:
|
|
13
|
+
virtual void scheduleOnUI(std::function<void()> job);
|
|
14
|
+
virtual void triggerUI();
|
|
15
|
+
virtual ~UIScheduler() = default;
|
|
16
|
+
|
|
17
|
+
protected:
|
|
18
|
+
std::atomic<bool> scheduledOnUI_{false};
|
|
19
|
+
ThreadSafeQueue<std::function<void()>> uiJobs_;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
} // namespace worklets
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#include <worklets/Tools/WorkletEventHandler.h>
|
|
2
|
+
|
|
3
|
+
namespace worklets {
|
|
4
|
+
|
|
5
|
+
void WorkletEventHandler::process(
|
|
6
|
+
const std::shared_ptr<WorkletRuntime> &workletRuntime,
|
|
7
|
+
const double eventTimestamp,
|
|
8
|
+
const jsi::Value &eventValue) const {
|
|
9
|
+
workletRuntime->runGuarded(
|
|
10
|
+
handlerFunction_, jsi::Value(eventTimestamp), eventValue);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
uint64_t WorkletEventHandler::getHandlerId() const {
|
|
14
|
+
return handlerId_;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const std::string &WorkletEventHandler::getEventName() const {
|
|
18
|
+
return eventName_;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
uint64_t WorkletEventHandler::getEmitterReactTag() const {
|
|
22
|
+
return emitterReactTag_;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
bool WorkletEventHandler::shouldIgnoreEmitterReactTag() const {
|
|
26
|
+
return emitterReactTag_ == -1;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
} // namespace worklets
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <worklets/SharedItems/Shareables.h>
|
|
4
|
+
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
|
5
|
+
|
|
6
|
+
#include <jsi/jsi.h>
|
|
7
|
+
|
|
8
|
+
#include <memory>
|
|
9
|
+
#include <string>
|
|
10
|
+
|
|
11
|
+
using namespace facebook;
|
|
12
|
+
|
|
13
|
+
namespace worklets {
|
|
14
|
+
|
|
15
|
+
class WorkletEventHandler {
|
|
16
|
+
const uint64_t handlerId_;
|
|
17
|
+
const uint64_t emitterReactTag_;
|
|
18
|
+
const std::string eventName_;
|
|
19
|
+
const std::shared_ptr<ShareableWorklet> handlerFunction_;
|
|
20
|
+
|
|
21
|
+
public:
|
|
22
|
+
WorkletEventHandler(
|
|
23
|
+
const uint64_t handlerId,
|
|
24
|
+
const std::string &eventName,
|
|
25
|
+
const uint64_t emitterReactTag,
|
|
26
|
+
const std::shared_ptr<ShareableWorklet> &handlerFunction)
|
|
27
|
+
: handlerId_(handlerId),
|
|
28
|
+
emitterReactTag_(emitterReactTag),
|
|
29
|
+
eventName_(eventName),
|
|
30
|
+
handlerFunction_(handlerFunction) {}
|
|
31
|
+
void process(
|
|
32
|
+
const std::shared_ptr<WorkletRuntime> &workletRuntime,
|
|
33
|
+
double eventTimestamp,
|
|
34
|
+
const jsi::Value &eventValue) const;
|
|
35
|
+
uint64_t getHandlerId() const;
|
|
36
|
+
const std::string &getEventName() const;
|
|
37
|
+
uint64_t getEmitterReactTag() const;
|
|
38
|
+
bool shouldIgnoreEmitterReactTag() const;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
} // namespace worklets
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#include <worklets/Tools/WorkletsJSIUtils.h>
|
|
2
|
+
#include <vector>
|
|
3
|
+
|
|
4
|
+
using namespace facebook;
|
|
5
|
+
|
|
6
|
+
namespace worklets::jsi_utils {
|
|
7
|
+
|
|
8
|
+
jsi::Array convertStringToArray(
|
|
9
|
+
jsi::Runtime &rt,
|
|
10
|
+
const std::string &value,
|
|
11
|
+
const unsigned int expectedSize) {
|
|
12
|
+
std::vector<float> transformMatrixList;
|
|
13
|
+
std::istringstream stringStream(value);
|
|
14
|
+
std::copy(
|
|
15
|
+
std::istream_iterator<float>(stringStream),
|
|
16
|
+
std::istream_iterator<float>(),
|
|
17
|
+
std::back_inserter(transformMatrixList));
|
|
18
|
+
assert(transformMatrixList.size() == expectedSize);
|
|
19
|
+
jsi::Array matrix(rt, expectedSize);
|
|
20
|
+
for (unsigned int i = 0; i < expectedSize; i++) {
|
|
21
|
+
matrix.setValueAtIndex(rt, i, transformMatrixList[i]);
|
|
22
|
+
}
|
|
23
|
+
return matrix;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
} // namespace worklets::jsi_utils
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
#include <sstream>
|
|
5
|
+
#include <string>
|
|
6
|
+
#include <tuple>
|
|
7
|
+
#include <utility>
|
|
8
|
+
|
|
9
|
+
using namespace facebook;
|
|
10
|
+
|
|
11
|
+
namespace worklets::jsi_utils {
|
|
12
|
+
|
|
13
|
+
// `get` functions take a pointer to `jsi::Value` and
|
|
14
|
+
// call an appropriate method to cast to the native type
|
|
15
|
+
template <typename T>
|
|
16
|
+
inline T get(jsi::Runtime &rt, const jsi::Value *value);
|
|
17
|
+
|
|
18
|
+
template <>
|
|
19
|
+
inline double get<double>(jsi::Runtime &, const jsi::Value *value) {
|
|
20
|
+
return value->asNumber();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
template <>
|
|
24
|
+
inline int get<int>(jsi::Runtime &, const jsi::Value *value) {
|
|
25
|
+
return value->asNumber();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
template <>
|
|
29
|
+
inline bool get<bool>(jsi::Runtime &, const jsi::Value *value) {
|
|
30
|
+
if (!value->isBool()) {
|
|
31
|
+
throw jsi::JSINativeException("[Worklets] Expected a boolean.");
|
|
32
|
+
}
|
|
33
|
+
return value->getBool();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
template <>
|
|
37
|
+
inline jsi::Object get<jsi::Object>(jsi::Runtime &rt, const jsi::Value *value) {
|
|
38
|
+
return value->asObject(rt);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
template <>
|
|
42
|
+
inline jsi::Value const &get<jsi::Value const &>(
|
|
43
|
+
jsi::Runtime &,
|
|
44
|
+
const jsi::Value *value) {
|
|
45
|
+
return *value;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// `convertArgs` functions take a variadic template parameter of target (C++)
|
|
49
|
+
// argument types `Targs` and a `jsi::Value` array `args`, and converts `args`
|
|
50
|
+
// to a tuple of typed C++ arguments to be passed to the native implementation.
|
|
51
|
+
// This is accomplished by dispatching (at compile time) to the correct
|
|
52
|
+
// implementation based on the first type of `Targs`, using SFINAE to select the
|
|
53
|
+
// correct specialization, and concatenating with the result of recursion on the
|
|
54
|
+
// rest of `Targs`
|
|
55
|
+
|
|
56
|
+
// BEGIN implementations for `convertArgs` specializations.
|
|
57
|
+
// specialization for empty `Targs` - returns an empty tuple
|
|
58
|
+
template <typename... Args>
|
|
59
|
+
inline std::enable_if_t<(sizeof...(Args) == 0), std::tuple<>> convertArgs(
|
|
60
|
+
jsi::Runtime &,
|
|
61
|
+
const jsi::Value *) {
|
|
62
|
+
return std::make_tuple();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// calls `get<First>` on the first argument to retrieve the native type,
|
|
66
|
+
// then calls recursively on the rest of `args`
|
|
67
|
+
// and returns the concatenation of results
|
|
68
|
+
template <typename T, typename... Rest>
|
|
69
|
+
inline std::tuple<T, Rest...> convertArgs(
|
|
70
|
+
jsi::Runtime &rt,
|
|
71
|
+
const jsi::Value *args) {
|
|
72
|
+
auto arg = std::tuple<T>(get<T>(rt, args));
|
|
73
|
+
auto rest = convertArgs<Rest...>(rt, std::next(args));
|
|
74
|
+
return std::tuple_cat(std::move(arg), std::move(rest));
|
|
75
|
+
}
|
|
76
|
+
// END implementations for `convertArgs` specializations.
|
|
77
|
+
|
|
78
|
+
// returns a tuple with the result of casting `args` to appropriate
|
|
79
|
+
// native C++ types needed to call `function`
|
|
80
|
+
template <typename Ret, typename... Args>
|
|
81
|
+
std::tuple<Args...> getArgsForFunction(
|
|
82
|
+
std::function<Ret(Args...)>,
|
|
83
|
+
jsi::Runtime &rt,
|
|
84
|
+
const jsi::Value *args,
|
|
85
|
+
const size_t count) {
|
|
86
|
+
assert(sizeof...(Args) == count);
|
|
87
|
+
return convertArgs<Args...>(rt, args);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// returns a tuple with the result of casting `args` to appropriate
|
|
91
|
+
// native C++ types needed to call `function`,
|
|
92
|
+
// passing `rt` as the first argument
|
|
93
|
+
template <typename Ret, typename... Args>
|
|
94
|
+
std::tuple<jsi::Runtime &, Args...> getArgsForFunction(
|
|
95
|
+
std::function<Ret(jsi::Runtime &, Args...)>,
|
|
96
|
+
jsi::Runtime &rt,
|
|
97
|
+
const jsi::Value *args,
|
|
98
|
+
const size_t count) {
|
|
99
|
+
assert(sizeof...(Args) == count);
|
|
100
|
+
return std::tuple_cat(std::tie(rt), convertArgs<Args...>(rt, args));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// calls `function` with `args`
|
|
104
|
+
template <typename Ret, typename... Args>
|
|
105
|
+
inline jsi::Value apply(
|
|
106
|
+
std::function<Ret(Args...)> function,
|
|
107
|
+
std::tuple<Args...> args) {
|
|
108
|
+
return std::apply(function, std::move(args));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// calls string-returning `function` with `args`,
|
|
112
|
+
// and returns the string
|
|
113
|
+
template <typename... Args>
|
|
114
|
+
inline jsi::Value apply(
|
|
115
|
+
jsi::Runtime &rt,
|
|
116
|
+
std::function<std::string(Args...)> function,
|
|
117
|
+
std::tuple<Args...> args) {
|
|
118
|
+
return jsi::String::createFromUtf8(rt, std::apply(function, std::move(args)));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// calls void-returning `function` with `args`,
|
|
122
|
+
// and returns `undefined`
|
|
123
|
+
template <typename... Args>
|
|
124
|
+
inline jsi::Value apply(
|
|
125
|
+
std::function<void(Args...)> function,
|
|
126
|
+
std::tuple<Args...> args) {
|
|
127
|
+
std::apply(function, std::move(args));
|
|
128
|
+
return jsi::Value::undefined();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// returns a function with JSI calling convention
|
|
132
|
+
// from a native function `function`
|
|
133
|
+
template <typename Fun>
|
|
134
|
+
jsi::HostFunctionType createHostFunction(Fun function) {
|
|
135
|
+
return [function](
|
|
136
|
+
jsi::Runtime &rt,
|
|
137
|
+
const jsi::Value &,
|
|
138
|
+
const jsi::Value *args,
|
|
139
|
+
const size_t count) {
|
|
140
|
+
auto argz = getArgsForFunction(function, rt, args, count);
|
|
141
|
+
return apply(function, std::move(argz));
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// returns a function with JSI calling convention
|
|
146
|
+
// from a native function `function` returning a string
|
|
147
|
+
template <typename... Args>
|
|
148
|
+
jsi::HostFunctionType createHostFunction(
|
|
149
|
+
std::function<std::string(Args...)> function) {
|
|
150
|
+
return [function](
|
|
151
|
+
jsi::Runtime &rt,
|
|
152
|
+
const jsi::Value &,
|
|
153
|
+
const jsi::Value *args,
|
|
154
|
+
const size_t count) {
|
|
155
|
+
auto argz = getArgsForFunction(function, rt, args, count);
|
|
156
|
+
return apply(rt, function, std::move(argz));
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// used to determine if `function<Ret(Args...)>`
|
|
161
|
+
// takes `Runtime &` as its first argument
|
|
162
|
+
template <typename... Args>
|
|
163
|
+
struct takes_runtime {
|
|
164
|
+
static constexpr size_t value = 0;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// specialization for `function<Ret(Runtime &, Rest...)`
|
|
168
|
+
template <typename... Rest>
|
|
169
|
+
struct takes_runtime<jsi::Runtime &, Rest...> {
|
|
170
|
+
static constexpr size_t value = 1;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// creates a JSI compatible function from `function`
|
|
174
|
+
// and installs it as a global function named `name`
|
|
175
|
+
// in the `rt` JS runtime
|
|
176
|
+
template <typename Ret, typename... Args>
|
|
177
|
+
void installJsiFunction(
|
|
178
|
+
jsi::Runtime &rt,
|
|
179
|
+
std::string_view name,
|
|
180
|
+
std::function<Ret(Args...)> function) {
|
|
181
|
+
auto clb = createHostFunction(function);
|
|
182
|
+
auto argsCount = sizeof...(Args) - takes_runtime<Args...>::value;
|
|
183
|
+
jsi::Value jsiFunction = jsi::Function::createFromHostFunction(
|
|
184
|
+
rt, jsi::PropNameID::forAscii(rt, name.data()), argsCount, clb);
|
|
185
|
+
rt.global().setProperty(rt, name.data(), jsiFunction);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// this should take care of passing types convertible to `function`
|
|
189
|
+
template <typename Fun>
|
|
190
|
+
void installJsiFunction(jsi::Runtime &rt, std::string_view name, Fun function) {
|
|
191
|
+
installJsiFunction(rt, name, std::function(std::forward<Fun>(function)));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
jsi::Array convertStringToArray(
|
|
195
|
+
jsi::Runtime &rt,
|
|
196
|
+
const std::string &value,
|
|
197
|
+
const unsigned int expectedSize);
|
|
198
|
+
|
|
199
|
+
} // namespace worklets::jsi_utils
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#include <worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h>
|
|
2
|
+
|
|
3
|
+
namespace worklets {
|
|
4
|
+
|
|
5
|
+
void RNRuntimeWorkletDecorator::decorate(
|
|
6
|
+
jsi::Runtime &rnRuntime,
|
|
7
|
+
const std::shared_ptr<WorkletsModuleProxy> &workletsModuleProxy) {
|
|
8
|
+
rnRuntime.global().setProperty(rnRuntime, "_WORKLET", false);
|
|
9
|
+
|
|
10
|
+
// TODO: Remove _IS_FABRIC sometime in the future
|
|
11
|
+
// react-native-screens 4.9.0 depends on it
|
|
12
|
+
rnRuntime.global().setProperty(rnRuntime, "_IS_FABRIC", true);
|
|
13
|
+
|
|
14
|
+
rnRuntime.global().setProperty(
|
|
15
|
+
rnRuntime,
|
|
16
|
+
"__workletsModuleProxy",
|
|
17
|
+
jsi::Object::createFromHostObject(rnRuntime, workletsModuleProxy));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
} // namespace worklets
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
#include <worklets/NativeModules/WorkletsModuleProxy.h>
|
|
5
|
+
#include <memory>
|
|
6
|
+
|
|
7
|
+
using namespace facebook;
|
|
8
|
+
|
|
9
|
+
namespace worklets {
|
|
10
|
+
|
|
11
|
+
class RNRuntimeWorkletDecorator {
|
|
12
|
+
// TODO: Rename to `RNRuntimeWorkletsDecorator` or something more suitable.
|
|
13
|
+
public:
|
|
14
|
+
static void decorate(
|
|
15
|
+
jsi::Runtime &rnRuntime,
|
|
16
|
+
const std::shared_ptr<WorkletsModuleProxy> &workletsModuleProxy);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
} // namespace worklets
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Hermes Runtime initialization
|
|
2
|
+
|
|
3
|
+
_Last updated_: 13/09/2022 by @Kwasow
|
|
4
|
+
|
|
5
|
+
This document describes the current way of initializing Hermes and connecting
|
|
6
|
+
it to the debugger. The work I did was mainly based on
|
|
7
|
+
|
|
8
|
+
[HermesExecutorFactory.cpp](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/hermes/executor/HermesExecutorFactory.cpp)
|
|
9
|
+
from React Native.
|
|
10
|
+
|
|
11
|
+
## Runtime initialization
|
|
12
|
+
|
|
13
|
+
If you take a look at `NativeProxy` (both on Android and iOS) you'll find
|
|
14
|
+
that it only makes a call to `ReanimatedRuntime::make(jsQueue)`. This
|
|
15
|
+
static function will return the correct runtime based on the user's configuration.
|
|
16
|
+
|
|
17
|
+
The initialization process is pretty simple and has only been moved out of
|
|
18
|
+
`NativeProxy` into `ReanimatedRuntime` without any major changes.
|
|
19
|
+
|
|
20
|
+
## Hermes runtime debugging
|
|
21
|
+
|
|
22
|
+
To enable debugging on the Hermes runtime we need to do two things:
|
|
23
|
+
|
|
24
|
+
1. Include source maps in JavaScript files
|
|
25
|
+
|
|
26
|
+
This part is done purely in JavaScript via the Babel plugin. The `makeWorklet`
|
|
27
|
+
function received an AST tree, which is aware of the modifications it made to
|
|
28
|
+
the code and therefore can generate the necessary source maps. It is important
|
|
29
|
+
that when we want to create a string from the AST we use the `generate` function
|
|
30
|
+
and enable source map generation so line mappings are not lost. Then when
|
|
31
|
+
transforming that code (ex. with `transformSync`) we have to pass the source
|
|
32
|
+
map as input so it can be updated.
|
|
33
|
+
|
|
34
|
+
Source map settings should always be set to `inline` so they are automatically
|
|
35
|
+
appended to the source code. The generated source map will be a base64 encoded
|
|
36
|
+
json.
|
|
37
|
+
|
|
38
|
+
A workletized function would look like this (after formattings):
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
function _f(number) {
|
|
42
|
+
console.log(_WORKLET, number);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6IkFBYXNCLFNBQUNBLEVBQUQsQ0FBQ0EsTUFBRCxFQUFvQjtBQUV0Q0MsU0FBTyxDQUFDQyxHQUFSRCxDQUFZRSxRQUFaRixFQUFzQkQsTUFBdEJDO0FBRmtCIiwibmFtZXMiOlsibnVtYmVyIiwiY29uc29sZSIsImxvZyIsIl9XT1JLTEVUIl0sInNvdXJjZXMiOlsiL1VzZXJzL2thcm9sL0dpdC9yZWFjdC1uYXRpdmUtcmVhbmltYXRlZC9GYWJyaWNFeGFtcGxlL3NyYy9Xb3JrbGV0RXhhbXBsZS50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLyogZ2xvYmFsIF9XT1JLTEVUICovXG5pbXBvcnQgeyBCdXR0b24sIFZpZXcsIFN0eWxlU2hlZXQgfSBmcm9tICdyZWFjdC1uYXRpdmUnO1xuaW1wb3J0IHtcbiAgcnVuT25KUyxcbiAgcnVuT25VSSxcbiAgdXNlRGVyaXZlZFZhbHVlLFxuICB1c2VTaGFyZWRWYWx1ZSxcbn0gZnJvbSAncmVhY3QtbmF0aXZlLXJlYW5pbWF0ZWQnO1xuXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBXb3JrbGV0RXhhbXBsZSgpIHtcbiAgLy8gcnVuT25VSSBkZW1vXG4gIGNvbnN0IHNvbWVXb3JrbGV0ID0gKG51bWJlcjogbnVtYmVyKSA9PiB7XG4gICAgJ3dvcmtsZXQnO1xuICAgIGNvbnNvbGUubG9nKF9XT1JLTEVULCBudW1iZXIpOyAvLyBfV09SS0xFVCBzaG91bGQgYmUgdHJ1ZVxuICB9O1xuXG4gIGNvbnN0IGhhbmRsZVByZXNzMSA9ICgpID0+IHtcbiAgICBydW5PblVJKHNvbWVXb3JrbGV0KShNYXRoLnJhbmRvbSgpKTtcbiAgfTtcblxuICAvLyBydW5PbkpTIGRlbW9cbiAgY29uc3QgeCA9IHVzZVNoYXJlZFZhbHVlKDApO1xuXG4gIGNvbnN0IHNvbWVGdW5jdGlvbiA9IChudW1iZXI6IG51bWJlcikgPT4ge1xuICAgIGNvbnNvbGUubG9nKF9XT1JLTEVULCBudW1iZXIpOyAvLyBfV09SS0xFVCBzaG91bGQgYmUgZmFsc2VcbiAgfTtcblxuICB1c2VEZXJpdmVkVmFsdWUoKCkgPT4ge1xuICAgIHJ1bk9uSlMoc29tZUZ1bmN0aW9uKSh4LnZhbHVlKTtcbiAgfSk7XG5cbiAgY29uc3QgaGFuZGxlUHJlc3MyID0gKCkgPT4ge1xuICAgIHgudmFsdWUgPSBNYXRoLnJhbmRvbSgpO1xuICB9O1xuXG4gIHJldHVybiAoXG4gICAgPFZpZXcgc3R5bGU9e3N0eWxlcy5jb250YWluZXJ9PlxuICAgICAgPEJ1dHRvbiBvblByZXNzPXtoYW5kbGVQcmVzczF9IHRpdGxlPVwicnVuT25VSSBkZW1vXCIgLz5cbiAgICAgIDxCdXR0b24gb25QcmVzcz17aGFuZGxlUHJlc3MyfSB0aXRsZT1cInJ1bk9uSlMgZGVtb1wiIC8+XG4gICAgPC9WaWV3PlxuICApO1xufVxuXG5jb25zdCBzdHlsZXMgPSBTdHlsZVNoZWV0LmNyZWF0ZSh7XG4gIGNvbnRhaW5lcjoge1xuICAgIGZsZXg6IDEsXG4gICAgYWxpZ25JdGVtczogJ2NlbnRlcicsXG4gICAganVzdGlmeUNvbnRlbnQ6ICdjZW50ZXInLFxuICB9LFxufSk7XG4iXX0=
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
And the base64 string after decoding is:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"version": 3,
|
|
52
|
+
"mappings": "AAasB,SAACA,EAAD,CAACA,MAAD,EAAoB;AAEtCC,SAAO,CAACC,GAARD,CAAYE,QAAZF,EAAsBD,MAAtBC;AAFkB",
|
|
53
|
+
"names": ["number", "console", "log", "_WORKLET"],
|
|
54
|
+
"sources": [
|
|
55
|
+
"/Users/karol/Git/react-native-reanimated/FabricExample/src/WorkletExample.tsx"
|
|
56
|
+
],
|
|
57
|
+
"sourcesContent": [
|
|
58
|
+
"/* global _WORKLET */\nimport { Button, View, StyleSheet } from 'react-native';\nimport {\n runOnJS,\n runOnUI,\n useDerivedValue,\n useSharedValue,\n} from 'react-native-reanimated';\n\nimport React from 'react';\n\nexport default function WorkletExample() {\n // runOnUI demo\n const someWorklet = (number: number) => {\n 'worklet';\n console.log(_WORKLET, number); // _WORKLET should be true\n };\n\n const handlePress1 = () => {\n runOnUI(someWorklet)(Math.random());\n };\n\n // runOnJS demo\n const x = useSharedValue(0);\n\n const someFunction = (number: number) => {\n console.log(_WORKLET, number); // _WORKLET should be false\n };\n\n useDerivedValue(() => {\n runOnJS(someFunction)(x.value);\n });\n\n const handlePress2 = () => {\n x.value = Math.random();\n };\n\n return (\n <View style={styles.container}>\n <Button onPress={handlePress1} title=\"runOnUI demo\" />\n <Button onPress={handlePress2} title=\"runOnJS demo\" />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n"
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
We run jest tests in release mode, because source maps will contain absolute
|
|
64
|
+
paths, which will be different on every machine and therefore would also alter
|
|
65
|
+
worklet hashes. Running in release mode prevents this.
|
|
66
|
+
|
|
67
|
+
2. Enable debugging on the runtime object
|
|
68
|
+
|
|
69
|
+
This is done by creating an adapter (`HermesExecutorRuntimeAdapter` inside of
|
|
70
|
+
`WorkletHermesRuntime.cpp`) which holds the runtime and allows the debugger
|
|
71
|
+
to communicate with it. The adapter is managed by a `Connection` (`ConnectionDemux`)
|
|
72
|
+
object, but this is not important in our case. We just have to make a call
|
|
73
|
+
to `facebook::hermes::inspector::chrome::enableDebugging()` and pass the adapter
|
|
74
|
+
and runtime name as parameters.
|
|
75
|
+
|
|
76
|
+
It is important to also `disableDebugging()` before the runtime is destroyed.
|
|
77
|
+
Failing to do so will probably crash the app as the debugger will try to
|
|
78
|
+
connect to a non-existent runtime.
|
|
79
|
+
|
|
80
|
+
The runtime should also be destroyed before the Reanimated module, because
|
|
81
|
+
otherwise there might be weird BAD_ACCESS errors when the gc gets it
|
|
82
|
+
hand on the runtime.
|
|
83
|
+
|
|
84
|
+
## Metro endpoint
|
|
85
|
+
|
|
86
|
+
Flipper and Chrome DevTools in general use the `localhost:8081/json` (where `8081`
|
|
87
|
+
is the port metro is running on) endpoint of metro to get the list of debuggable
|
|
88
|
+
targets (runtimes). For a normal React Native app the output would look something
|
|
89
|
+
like this:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
[
|
|
93
|
+
{
|
|
94
|
+
"id": "0-1",
|
|
95
|
+
"description": "org.reactjs.native.example.FabricExample",
|
|
96
|
+
"title": "Hermes React Native",
|
|
97
|
+
"faviconUrl": "https://reactjs.org/favicon.ico",
|
|
98
|
+
"devtoolsFrontendUrl": "devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=%5B%3A%3A1%5D%3A8081%2Finspector%2Fdebug%3Fdevice%3D0%26page%3D1",
|
|
99
|
+
"type": "node",
|
|
100
|
+
"webSocketDebuggerUrl": "ws://[::1]:8081/inspector/debug?device=0&page=1",
|
|
101
|
+
"vm": "Hermes"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"id": "0--1",
|
|
105
|
+
"description": "org.reactjs.native.example.FabricExample",
|
|
106
|
+
"title": "React Native Experimental (Improved Chrome Reloads)",
|
|
107
|
+
"faviconUrl": "https://reactjs.org/favicon.ico",
|
|
108
|
+
"devtoolsFrontendUrl": "devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=%5B%3A%3A1%5D%3A8081%2Finspector%2Fdebug%3Fdevice%3D0%26page%3D-1",
|
|
109
|
+
"type": "node",
|
|
110
|
+
"webSocketDebuggerUrl": "ws://[::1]:8081/inspector/debug?device=0&page=-1",
|
|
111
|
+
"vm": "don't use"
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For an Android app with Reanimated it should include the Reanimated runtime like
|
|
117
|
+
this:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
[
|
|
121
|
+
{
|
|
122
|
+
"id": "0-2",
|
|
123
|
+
"description": "com.fabricexample",
|
|
124
|
+
"title": "Reanimated Runtime",
|
|
125
|
+
"faviconUrl": "https://reactjs.org/favicon.ico",
|
|
126
|
+
"devtoolsFrontendUrl": "devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=%5B%3A%3A1%5D%3A8081%2Finspector%2Fdebug%3Fdevice%3D0%26page%3D3",
|
|
127
|
+
"type": "node",
|
|
128
|
+
"webSocketDebuggerUrl": "ws://[::1]:8081/inspector/debug?device=1&page=2",
|
|
129
|
+
"vm": "Hermes"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"id": "0-1",
|
|
133
|
+
"description": "com.fabricexample",
|
|
134
|
+
"title": "Hermes React Native",
|
|
135
|
+
"faviconUrl": "https://reactjs.org/favicon.ico",
|
|
136
|
+
"devtoolsFrontendUrl": "devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=%5B%3A%3A1%5D%3A8081%2Finspector%2Fdebug%3Fdevice%3D0%26page%3D2",
|
|
137
|
+
"type": "node",
|
|
138
|
+
"webSocketDebuggerUrl": "ws://[::1]:8081/inspector/debug?device=1&page=1",
|
|
139
|
+
"vm": "Hermes"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"id": "0--1",
|
|
143
|
+
"description": "com.fabricexample",
|
|
144
|
+
"title": "React Native Experimental (Improved Chrome Reloads)",
|
|
145
|
+
"faviconUrl": "https://reactjs.org/favicon.ico",
|
|
146
|
+
"devtoolsFrontendUrl": "devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=%5B%3A%3A1%5D%3A8081%2Finspector%2Fdebug%3Fdevice%3D0%26page%3D-1",
|
|
147
|
+
"type": "node",
|
|
148
|
+
"webSocketDebuggerUrl": "ws://[::1]:8081/inspector/debug?device=1&page=-1",
|
|
149
|
+
"vm": "don't use"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"id": "0--2",
|
|
153
|
+
"description": "com.fabricexample",
|
|
154
|
+
"title": "Reanimated Runtime Experimental (Improved Chrome Reloads)",
|
|
155
|
+
"faviconUrl": "https://reactjs.org/favicon.ico",
|
|
156
|
+
"devtoolsFrontendUrl": "devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=%5B%3A%3A1%5D%3A8081%2Finspector%2Fdebug%3Fdevice%3D0%26page%3D-2",
|
|
157
|
+
"type": "node",
|
|
158
|
+
"webSocketDebuggerUrl": "ws://[::1]:8081/inspector/debug?device=1&page=-2",
|
|
159
|
+
"vm": "don't use"
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Runtimes with negative IDs are 'virtual' - they are just references to the real
|
|
165
|
+
runtimes but their IDs don't change after a reload. If we were to connect to
|
|
166
|
+
the normal runtime and reload the app it would crash, as the debugger would try
|
|
167
|
+
to communicate with a non-existent runtime. These 'virtual' runtimes are made
|
|
168
|
+
and managed by metro (PR: [facebook/metro#864](https://github.com/facebook/metro/pull/864)).
|
|
169
|
+
|
|
170
|
+
## Known issues
|
|
171
|
+
|
|
172
|
+
**IFrame sandboxing**
|
|
173
|
+
|
|
174
|
+
Source maps always define a `sources` array, which contain names of files used
|
|
175
|
+
to generate the source map. For Chrome DevTools this is sufficient as it will
|
|
176
|
+
read files from disk, but the `IFrame` interface used by Flipper is sandboxed
|
|
177
|
+
and doesn't allow filesystem access. Therefore we also need to include the files
|
|
178
|
+
content in the `sourcesContent` array.
|
|
179
|
+
|
|
180
|
+
**Chrome version 105.0.5195.102 doesn't load source maps**
|
|
181
|
+
|
|
182
|
+
This version of Chrome introduced a regression into DevTools that broke source
|
|
183
|
+
maps loading for node.js apps. This issue is not caused by Reanimated in any
|
|
184
|
+
way and should be fixed by Chrome developers in later versions.
|
|
185
|
+
|
|
186
|
+
The issue was tracked here: https://bugs.chromium.org/p/chromium/issues/detail?id=1358497
|
|
187
|
+
|
|
188
|
+
**App reloads don't work**
|
|
189
|
+
|
|
190
|
+
On iOS the app will crash on every reload if a debugger is connected to the runtime.
|
|
191
|
+
On Android it will also crash but only after a few reloads.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#include <worklets/Tools/WorkletsJSIUtils.h>
|
|
2
|
+
#include <worklets/WorkletRuntime/UIRuntimeDecorator.h>
|
|
3
|
+
|
|
4
|
+
#include <utility>
|
|
5
|
+
|
|
6
|
+
namespace worklets {
|
|
7
|
+
|
|
8
|
+
void UIRuntimeDecorator::decorate(
|
|
9
|
+
facebook::jsi::Runtime &uiRuntime,
|
|
10
|
+
std::function<
|
|
11
|
+
void(facebook::jsi::Runtime &rt, const facebook::jsi::Value &callback)>
|
|
12
|
+
&&requestAnimationFrame) {
|
|
13
|
+
uiRuntime.global().setProperty(uiRuntime, "_UI", true);
|
|
14
|
+
|
|
15
|
+
jsi_utils::installJsiFunction(
|
|
16
|
+
uiRuntime, "requestAnimationFrame", std::move(requestAnimationFrame));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
} // namespace worklets
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
|
|
5
|
+
namespace worklets {
|
|
6
|
+
|
|
7
|
+
class UIRuntimeDecorator {
|
|
8
|
+
public:
|
|
9
|
+
static void decorate(
|
|
10
|
+
facebook::jsi::Runtime &uiRuntime,
|
|
11
|
+
std::function<void(
|
|
12
|
+
facebook::jsi::Runtime &rt,
|
|
13
|
+
const facebook::jsi::Value &callback)> &&requestAnimationFrame);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
} // namespace worklets
|