basalt-core 0.0.0-rc5
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/LICENSE +21 -0
- package/dist/cli/basalt.d.ts +3 -0
- package/dist/cli/basalt.d.ts.map +1 -0
- package/dist/cli/basalt.js +47 -0
- package/dist/cli/basalt.js.map +1 -0
- package/dist/cli/bundle-cli.d.ts +12 -0
- package/dist/cli/bundle-cli.d.ts.map +1 -0
- package/dist/cli/bundle-cli.js +124 -0
- package/dist/cli/bundle-cli.js.map +1 -0
- package/dist/cli/bundleWithAssets.d.ts +79 -0
- package/dist/cli/bundleWithAssets.d.ts.map +1 -0
- package/dist/cli/bundleWithAssets.js +198 -0
- package/dist/cli/bundleWithAssets.js.map +1 -0
- package/dist/cli/desktop.d.ts +339 -0
- package/dist/cli/desktop.d.ts.map +1 -0
- package/dist/cli/desktop.js +1029 -0
- package/dist/cli/desktop.js.map +1 -0
- package/dist/cli/doctor.d.ts +31 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +283 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.d.ts +77 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +442 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/metro.d.ts +49 -0
- package/dist/cli/metro.d.ts.map +1 -0
- package/dist/cli/metro.js +148 -0
- package/dist/cli/metro.js.map +1 -0
- package/dist/cli/packageApp.d.ts +102 -0
- package/dist/cli/packageApp.d.ts.map +1 -0
- package/dist/cli/packageApp.js +319 -0
- package/dist/cli/packageApp.js.map +1 -0
- package/dist/cli/steps.d.ts +34 -0
- package/dist/cli/steps.d.ts.map +1 -0
- package/dist/cli/steps.js +53 -0
- package/dist/cli/steps.js.map +1 -0
- package/dist/metro-config.d.ts +168 -0
- package/dist/metro-config.d.ts.map +1 -0
- package/dist/metro-config.js +671 -0
- package/dist/metro-config.js.map +1 -0
- package/dist/react-native.config.d.ts +7 -0
- package/dist/react-native.config.d.ts.map +1 -0
- package/dist/react-native.config.js +80 -0
- package/dist/react-native.config.js.map +1 -0
- package/dist/src/DragSource.d.ts +52 -0
- package/dist/src/DragSource.d.ts.map +1 -0
- package/dist/src/DragSource.js +97 -0
- package/dist/src/DragSource.js.map +1 -0
- package/dist/src/DropTarget.d.ts +58 -0
- package/dist/src/DropTarget.d.ts.map +1 -0
- package/dist/src/DropTarget.js +131 -0
- package/dist/src/DropTarget.js.map +1 -0
- package/dist/src/KeyHandler.d.ts +57 -0
- package/dist/src/KeyHandler.d.ts.map +1 -0
- package/dist/src/KeyHandler.js +48 -0
- package/dist/src/KeyHandler.js.map +1 -0
- package/dist/src/Menu.d.ts +72 -0
- package/dist/src/Menu.d.ts.map +1 -0
- package/dist/src/Menu.js +179 -0
- package/dist/src/Menu.js.map +1 -0
- package/dist/src/TitleBar.d.ts +75 -0
- package/dist/src/TitleBar.d.ts.map +1 -0
- package/dist/src/TitleBar.js +236 -0
- package/dist/src/TitleBar.js.map +1 -0
- package/dist/src/Window.d.ts +87 -0
- package/dist/src/Window.d.ts.map +1 -0
- package/dist/src/Window.js +248 -0
- package/dist/src/Window.js.map +1 -0
- package/dist/src/closeRequest.d.ts +55 -0
- package/dist/src/closeRequest.d.ts.map +1 -0
- package/dist/src/closeRequest.js +134 -0
- package/dist/src/closeRequest.js.map +1 -0
- package/dist/src/index.d.ts +45 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +92 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/overrides/Alert.d.ts +69 -0
- package/dist/src/overrides/Alert.d.ts.map +1 -0
- package/dist/src/overrides/Alert.js +112 -0
- package/dist/src/overrides/Alert.js.map +1 -0
- package/dist/src/overrides/BaseViewConfig.d.ts +28 -0
- package/dist/src/overrides/BaseViewConfig.d.ts.map +1 -0
- package/dist/src/overrides/BaseViewConfig.js +72 -0
- package/dist/src/overrides/BaseViewConfig.js.map +1 -0
- package/dist/src/overrides/Platform.linux.d.ts +10 -0
- package/dist/src/overrides/Platform.linux.d.ts.map +1 -0
- package/dist/src/overrides/Platform.linux.js +15 -0
- package/dist/src/overrides/Platform.linux.js.map +1 -0
- package/dist/src/overrides/Platform.macos.d.ts +10 -0
- package/dist/src/overrides/Platform.macos.d.ts.map +1 -0
- package/dist/src/overrides/Platform.macos.js +15 -0
- package/dist/src/overrides/Platform.macos.js.map +1 -0
- package/dist/src/overrides/Platform.windows.d.ts +10 -0
- package/dist/src/overrides/Platform.windows.d.ts.map +1 -0
- package/dist/src/overrides/Platform.windows.js +15 -0
- package/dist/src/overrides/Platform.windows.js.map +1 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts +24 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts.map +1 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.js +30 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.js.map +1 -0
- package/dist/src/overrides/RefreshControl.d.ts +52 -0
- package/dist/src/overrides/RefreshControl.d.ts.map +1 -0
- package/dist/src/overrides/RefreshControl.js +92 -0
- package/dist/src/overrides/RefreshControl.js.map +1 -0
- package/dist/src/overrides/ScrollView.d.ts +39 -0
- package/dist/src/overrides/ScrollView.d.ts.map +1 -0
- package/dist/src/overrides/ScrollView.js +59 -0
- package/dist/src/overrides/ScrollView.js.map +1 -0
- package/dist/src/overrides/Share.d.ts +96 -0
- package/dist/src/overrides/Share.d.ts.map +1 -0
- package/dist/src/overrides/Share.js +97 -0
- package/dist/src/overrides/Share.js.map +1 -0
- package/dist/src/overrides/TextInput.d.ts +81 -0
- package/dist/src/overrides/TextInput.d.ts.map +1 -0
- package/dist/src/overrides/TextInput.js +213 -0
- package/dist/src/overrides/TextInput.js.map +1 -0
- package/dist/src/overrides/View.d.ts +36 -0
- package/dist/src/overrides/View.d.ts.map +1 -0
- package/dist/src/overrides/View.js +99 -0
- package/dist/src/overrides/View.js.map +1 -0
- package/dist/src/overrides/createPlatform.d.ts +32 -0
- package/dist/src/overrides/createPlatform.d.ts.map +1 -0
- package/dist/src/overrides/createPlatform.js +84 -0
- package/dist/src/overrides/createPlatform.js.map +1 -0
- package/dist/src/overrides/setUpDeveloperTools.d.ts +28 -0
- package/dist/src/overrides/setUpDeveloperTools.d.ts.map +1 -0
- package/dist/src/overrides/setUpDeveloperTools.js +84 -0
- package/dist/src/overrides/setUpDeveloperTools.js.map +1 -0
- package/dist/src/overrides/setUpXHR.d.ts +46 -0
- package/dist/src/overrides/setUpXHR.d.ts.map +1 -0
- package/dist/src/overrides/setUpXHR.js +236 -0
- package/dist/src/overrides/setUpXHR.js.map +1 -0
- package/dist/src/quitRequest.d.ts +55 -0
- package/dist/src/quitRequest.d.ts.map +1 -0
- package/dist/src/quitRequest.js +121 -0
- package/dist/src/quitRequest.js.map +1 -0
- package/dist/src/resourcePath.d.ts +18 -0
- package/dist/src/resourcePath.d.ts.map +1 -0
- package/dist/src/resourcePath.js +31 -0
- package/dist/src/resourcePath.js.map +1 -0
- package/dist/src/responseBody.d.ts +76 -0
- package/dist/src/responseBody.d.ts.map +1 -0
- package/dist/src/responseBody.js +94 -0
- package/dist/src/responseBody.js.map +1 -0
- package/dist/src/responseHeaders.d.ts +40 -0
- package/dist/src/responseHeaders.d.ts.map +1 -0
- package/dist/src/responseHeaders.js +75 -0
- package/dist/src/responseHeaders.js.map +1 -0
- package/dist/src/titleBarState.d.ts +43 -0
- package/dist/src/titleBarState.d.ts.map +1 -0
- package/dist/src/titleBarState.js +77 -0
- package/dist/src/titleBarState.js.map +1 -0
- package/dist/src/useContextMenu.d.ts +113 -0
- package/dist/src/useContextMenu.d.ts.map +1 -0
- package/dist/src/useContextMenu.js +109 -0
- package/dist/src/useContextMenu.js.map +1 -0
- package/dist/src/useDialog.d.ts +98 -0
- package/dist/src/useDialog.d.ts.map +1 -0
- package/dist/src/useDialog.js +112 -0
- package/dist/src/useDialog.js.map +1 -0
- package/dist/src/useDisplays.d.ts +70 -0
- package/dist/src/useDisplays.d.ts.map +1 -0
- package/dist/src/useDisplays.js +118 -0
- package/dist/src/useDisplays.js.map +1 -0
- package/dist/src/useHandledKeys.d.ts +38 -0
- package/dist/src/useHandledKeys.d.ts.map +1 -0
- package/dist/src/useHandledKeys.js +70 -0
- package/dist/src/useHandledKeys.js.map +1 -0
- package/dist/src/useWindow.d.ts +140 -0
- package/dist/src/useWindow.d.ts.map +1 -0
- package/dist/src/useWindow.js +233 -0
- package/dist/src/useWindow.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/native/CMakeLists.txt +355 -0
- package/native/bootstrap.sh +613 -0
- package/native/cmake/CompilerFlags.cmake +49 -0
- package/native/cmake/Expo.cmake +125 -0
- package/native/cmake/ReactNativeCore.cmake +612 -0
- package/native/cmake/Reanimated.cmake +108 -0
- package/native/cmake/Skia.cmake +379 -0
- package/native/cmake/ThirdParty.cmake +290 -0
- package/native/cmake/Worklets.cmake +67 -0
- package/native/cmake/codegen/CMakeLists.txt +32 -0
- package/native/core/AppIdentity.cpp +85 -0
- package/native/core/AppIdentity.h +59 -0
- package/native/core/AppPaths.cpp +96 -0
- package/native/core/AppPaths.h +53 -0
- package/native/core/AppearanceModule.cpp +60 -0
- package/native/core/AppearanceModule.h +40 -0
- package/native/core/Backface.h +59 -0
- package/native/core/BlobModule.cpp +283 -0
- package/native/core/BlobModule.h +76 -0
- package/native/core/BlobRegistry.cpp +75 -0
- package/native/core/BlobRegistry.h +44 -0
- package/native/core/ColorScheme.cpp +105 -0
- package/native/core/ColorScheme.h +59 -0
- package/native/core/ComponentRegistry.h +30 -0
- package/native/core/ControlMetrics.h +37 -0
- package/native/core/CoreModules.cpp +592 -0
- package/native/core/CoreModules.h +308 -0
- package/native/core/DebuggingOverlay.cpp +106 -0
- package/native/core/DebuggingOverlay.h +65 -0
- package/native/core/DesktopControls.cpp +232 -0
- package/native/core/DesktopControls.h +170 -0
- package/native/core/DevBundle.cpp +108 -0
- package/native/core/DevBundle.h +69 -0
- package/native/core/DevMenu.cpp +99 -0
- package/native/core/DevMenu.h +75 -0
- package/native/core/DialogModule.cpp +150 -0
- package/native/core/DialogModule.h +51 -0
- package/native/core/DragAndDrop.cpp +45 -0
- package/native/core/DragAndDrop.h +225 -0
- package/native/core/ExpoImageComponent.cpp +79 -0
- package/native/core/ExpoImageComponent.h +80 -0
- package/native/core/ExpoModules.cpp +415 -0
- package/native/core/ExpoModules.h +115 -0
- package/native/core/ExpoRuntime.cpp +366 -0
- package/native/core/ExpoRuntime.h +42 -0
- package/native/core/FocusRing.h +36 -0
- package/native/core/FontRegistry.h +51 -0
- package/native/core/GestureHandlerModule.cpp +136 -0
- package/native/core/GestureHandlerModule.h +71 -0
- package/native/core/Gestures.cpp +533 -0
- package/native/core/Gestures.h +145 -0
- package/native/core/HoverTracker.cpp +69 -0
- package/native/core/HoverTracker.h +109 -0
- package/native/core/HttpClient.cpp +282 -0
- package/native/core/ImageBytes.cpp +205 -0
- package/native/core/ImageBytes.h +29 -0
- package/native/core/ImageCache.cpp +51 -0
- package/native/core/ImageCache.h +89 -0
- package/native/core/JsRuntimeAccess.cpp +70 -0
- package/native/core/JsRuntimeAccess.h +60 -0
- package/native/core/JsiPromise.h +51 -0
- package/native/core/KeyEvents.cpp +116 -0
- package/native/core/KeyEvents.h +144 -0
- package/native/core/LogBoxSurface.cpp +46 -0
- package/native/core/LogBoxSurface.h +68 -0
- package/native/core/MenuModel.h +117 -0
- package/native/core/MenuModule.cpp +209 -0
- package/native/core/MenuModule.h +66 -0
- package/native/core/MountingWalk.h +524 -0
- package/native/core/PackageModules.cpp.in +25 -0
- package/native/core/PackageModules.h +50 -0
- package/native/core/PlatformConstantsModule.cpp +63 -0
- package/native/core/PlatformConstantsModule.h +64 -0
- package/native/core/PlatformServices.h +213 -0
- package/native/core/PointerButtons.h +63 -0
- package/native/core/PullToRefresh.cpp +57 -0
- package/native/core/PullToRefresh.h +73 -0
- package/native/core/ReanimatedCompat.h +47 -0
- package/native/core/ReanimatedModule.cpp +203 -0
- package/native/core/ReanimatedModule.h +55 -0
- package/native/core/ScrollAnimation.cpp +59 -0
- package/native/core/ScrollAnimation.h +70 -0
- package/native/core/ScrollBounds.cpp +26 -0
- package/native/core/ScrollBounds.h +68 -0
- package/native/core/ScrollIndicator.cpp +50 -0
- package/native/core/ScrollIndicator.h +69 -0
- package/native/core/ScrollMomentum.cpp +71 -0
- package/native/core/ScrollMomentum.h +73 -0
- package/native/core/ScrollSnap.cpp +123 -0
- package/native/core/ScrollSnap.h +80 -0
- package/native/core/ShareFallback.cpp +101 -0
- package/native/core/ShareFallback.h +45 -0
- package/native/core/SkiaPictureViewComponent.cpp +11 -0
- package/native/core/SkiaPictureViewComponent.h +47 -0
- package/native/core/SourceCodeModule.cpp +55 -0
- package/native/core/SourceCodeModule.h +53 -0
- package/native/core/StatusBarModule.cpp +23 -0
- package/native/core/StatusBarModule.h +42 -0
- package/native/core/TestDialog.cpp +148 -0
- package/native/core/TestDialog.h +96 -0
- package/native/core/TestKeys.cpp +78 -0
- package/native/core/TestKeys.h +50 -0
- package/native/core/TestQuitFile.cpp +33 -0
- package/native/core/TestQuitFile.h +60 -0
- package/native/core/TestSettle.h +192 -0
- package/native/core/TitleBarRegions.h +31 -0
- package/native/core/TurboModuleProxy.cpp +51 -0
- package/native/core/TurboModuleProxy.h +46 -0
- package/native/core/UIManagerAccess.cpp +43 -0
- package/native/core/UIManagerAccess.h +43 -0
- package/native/core/WindowBoundsCache.cpp +319 -0
- package/native/core/WindowControl.h +235 -0
- package/native/core/WindowHost.h +158 -0
- package/native/core/WindowMethods.cpp +167 -0
- package/native/core/WindowMethods.h +84 -0
- package/native/core/WindowsModule.cpp +448 -0
- package/native/core/WindowsModule.h +133 -0
- package/native/core/WorkletsModule.cpp +199 -0
- package/native/core/WorkletsModule.h +57 -0
- package/native/core/portability_probe.cpp +210 -0
- package/native/tests/EventRecorder.h +124 -0
- package/native/tests/TestHarness.cpp +109 -0
- package/native/tests/TestHarness.h +89 -0
- package/native/tests/TreeDump.h +49 -0
- package/native/tests/test_app_identity.cpp +114 -0
- package/native/tests/test_app_paths.cpp +48 -0
- package/native/tests/test_appearance.cpp +107 -0
- package/native/tests/test_backface.cpp +79 -0
- package/native/tests/test_blobs.cpp +157 -0
- package/native/tests/test_controls.cpp +185 -0
- package/native/tests/test_devbundle.cpp +103 -0
- package/native/tests/test_drag_and_drop.cpp +143 -0
- package/native/tests/test_gestures.cpp +331 -0
- package/native/tests/test_hover.cpp +92 -0
- package/native/tests/test_image_cache.cpp +109 -0
- package/native/tests/test_js_runtime_access.cpp +137 -0
- package/native/tests/test_key_events.cpp +235 -0
- package/native/tests/test_momentum.cpp +138 -0
- package/native/tests/test_quit_file.cpp +104 -0
- package/native/tests/test_scroll_animation.cpp +120 -0
- package/native/tests/test_scroll_bounds.cpp +66 -0
- package/native/tests/test_scroll_indicator.cpp +149 -0
- package/native/tests/test_scroll_snap.cpp +112 -0
- package/native/tests/test_settle.cpp +115 -0
- package/native/tests/test_share.cpp +75 -0
- package/native/tests/test_sourcecode.cpp +62 -0
- package/native/tests/test_window_close.cpp +119 -0
- package/native/tests/test_window_limits.cpp +123 -0
- package/package.json +43 -0
- package/react-native.config.js +86 -0
- package/supported-versions.json +66 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#include "WorkletsModule.h"
|
|
2
|
+
|
|
3
|
+
#include "Gestures.h"
|
|
4
|
+
#include "PlatformServices.h"
|
|
5
|
+
|
|
6
|
+
#include <glog/logging.h>
|
|
7
|
+
|
|
8
|
+
#ifdef BASALT_HAS_WORKLETS
|
|
9
|
+
#include <worklets/NativeModules/WorkletsModuleProxy.h>
|
|
10
|
+
#include <worklets/Tools/PlatformLogger.h>
|
|
11
|
+
#include <worklets/Tools/RNRuntimeStatus.h>
|
|
12
|
+
#include <worklets/Tools/UIScheduler.h>
|
|
13
|
+
#include <worklets/WorkletRuntime/RuntimeBindings.h>
|
|
14
|
+
|
|
15
|
+
#include <thread>
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
namespace basalt {
|
|
19
|
+
|
|
20
|
+
bool hasWorklets() {
|
|
21
|
+
#ifdef BASALT_HAS_WORKLETS
|
|
22
|
+
return true;
|
|
23
|
+
#else
|
|
24
|
+
return false;
|
|
25
|
+
#endif
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#ifdef BASALT_HAS_WORKLETS
|
|
29
|
+
|
|
30
|
+
namespace {
|
|
31
|
+
|
|
32
|
+
using facebook::jsi::Runtime;
|
|
33
|
+
using facebook::jsi::Value;
|
|
34
|
+
using facebook::react::TurboModule;
|
|
35
|
+
|
|
36
|
+
// The thread the bundle runs on, learned at install time -- which happens from
|
|
37
|
+
// JavaScript, so whichever thread that is, is the one. Worklets asks about it
|
|
38
|
+
// to decide whether a job can run now or has to be scheduled.
|
|
39
|
+
std::thread::id &javaScriptThread() {
|
|
40
|
+
static std::thread::id id;
|
|
41
|
+
return id;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The UI thread's scheduler. `postToUiThread` is the platform's, and the base
|
|
45
|
+
// class does the queueing; this only has to get `triggerUI` called over there.
|
|
46
|
+
class DesktopUIScheduler final : public worklets::UIScheduler,
|
|
47
|
+
public std::enable_shared_from_this<DesktopUIScheduler> {
|
|
48
|
+
public:
|
|
49
|
+
void scheduleOnUI(std::function<void()> job) override {
|
|
50
|
+
// Already on the UI thread: run it now rather than a frame later, which is
|
|
51
|
+
// what makes a gesture handler's worklet feel immediate.
|
|
52
|
+
if (std::this_thread::get_id() != javaScriptThread()) {
|
|
53
|
+
job();
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
UIScheduler::scheduleOnUI(std::move(job));
|
|
58
|
+
if (!scheduledOnUI_) {
|
|
59
|
+
postToUiThread([weakThis = weak_from_this()]() {
|
|
60
|
+
// The scheduler can be gone by the time this runs -- the runtime it
|
|
61
|
+
// belongs to is torn down on reload.
|
|
62
|
+
if (auto self = weakThis.lock()) {
|
|
63
|
+
self->triggerUI();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Held for reanimated, which needs the same proxy rather than a second one, and
|
|
71
|
+
// so that `start()` can reach what `installTurboModule()` made. Weak, because
|
|
72
|
+
// the module owns it and the module goes away with the runtime.
|
|
73
|
+
std::weak_ptr<worklets::WorkletsModuleProxy> &installedProxy() {
|
|
74
|
+
static std::weak_ptr<worklets::WorkletsModuleProxy> proxy;
|
|
75
|
+
return proxy;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
std::shared_ptr<worklets::WorkletsModuleProxy> &heldProxy() {
|
|
79
|
+
static std::shared_ptr<worklets::WorkletsModuleProxy> proxy;
|
|
80
|
+
return proxy;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
std::shared_ptr<worklets::RNRuntimeStatus> &runtimeStatus() {
|
|
84
|
+
static std::shared_ptr<worklets::RNRuntimeStatus> status;
|
|
85
|
+
return status;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
} // namespace
|
|
89
|
+
|
|
90
|
+
DesktopWorkletsModule::DesktopWorkletsModule(
|
|
91
|
+
std::shared_ptr<facebook::react::CallInvoker> jsInvoker)
|
|
92
|
+
: TurboModule(kModuleName, std::move(jsInvoker)) {
|
|
93
|
+
methodMap_["installTurboModule"] = MethodMetadata{1, installTurboModule};
|
|
94
|
+
methodMap_["start"] = MethodMetadata{0, start};
|
|
95
|
+
methodMap_["toggleSlowAnimationsOnUIRuntime"] = MethodMetadata{0, toggleSlowAnimations};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
DesktopWorkletsModule::~DesktopWorkletsModule() {
|
|
99
|
+
if (runtimeStatus() != nullptr) {
|
|
100
|
+
// Tells the worklet runtime that the runtime it was talking to is gone, so
|
|
101
|
+
// that a job still in flight stops rather than reaching into it.
|
|
102
|
+
runtimeStatus()->setDead();
|
|
103
|
+
}
|
|
104
|
+
heldProxy().reset();
|
|
105
|
+
installedProxy().reset();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
Value DesktopWorkletsModule::installTurboModule(Runtime &runtime,
|
|
109
|
+
TurboModule &module,
|
|
110
|
+
const Value * /*args*/,
|
|
111
|
+
size_t /*count*/) {
|
|
112
|
+
javaScriptThread() = std::this_thread::get_id();
|
|
113
|
+
|
|
114
|
+
auto &self = static_cast<DesktopWorkletsModule &>(module);
|
|
115
|
+
auto uiScheduler = std::make_shared<DesktopUIScheduler>();
|
|
116
|
+
runtimeStatus() = std::make_shared<worklets::RNRuntimeStatus>();
|
|
117
|
+
|
|
118
|
+
auto runtimeBindings = std::make_shared<worklets::RuntimeBindings>(worklets::RuntimeBindings{
|
|
119
|
+
// A timer rather than the display's refresh. The display link on each
|
|
120
|
+
// platform belongs to React Native's own AnimationChoreographer, which
|
|
121
|
+
// pauses whenever React Native has no animation running -- exactly when a
|
|
122
|
+
// Reanimated one might be. Sixteen milliseconds is the honest
|
|
123
|
+
// approximation until there is a frame source both can share; see
|
|
124
|
+
.requestAnimationFrame =
|
|
125
|
+
[](std::function<void(const double)> callback) {
|
|
126
|
+
postDelayed(16, [callback = std::move(callback)]() {
|
|
127
|
+
callback(monotonicMilliseconds());
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
// Only used in bundle mode, which this is not.
|
|
131
|
+
.nativeLoggingHook = {},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
auto proxy = std::make_shared<worklets::WorkletsModuleProxy>(
|
|
135
|
+
runtime,
|
|
136
|
+
self.jsInvoker_,
|
|
137
|
+
uiScheduler,
|
|
138
|
+
[]() -> bool { return std::this_thread::get_id() == javaScriptThread(); },
|
|
139
|
+
runtimeBindings,
|
|
140
|
+
worklets::BundleModeConfig{.enabled = false, .script = nullptr, .sourceURL = ""},
|
|
141
|
+
runtimeStatus());
|
|
142
|
+
|
|
143
|
+
heldProxy() = proxy;
|
|
144
|
+
installedProxy() = proxy;
|
|
145
|
+
return Value(true);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
Value DesktopWorkletsModule::start(Runtime & /*runtime*/,
|
|
149
|
+
TurboModule & /*module*/,
|
|
150
|
+
const Value * /*args*/,
|
|
151
|
+
size_t /*count*/) {
|
|
152
|
+
if (auto proxy = installedProxy().lock()) {
|
|
153
|
+
proxy->start();
|
|
154
|
+
return Value(true);
|
|
155
|
+
}
|
|
156
|
+
return Value(false);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
Value DesktopWorkletsModule::toggleSlowAnimations(Runtime & /*runtime*/,
|
|
160
|
+
TurboModule & /*module*/,
|
|
161
|
+
const Value * /*args*/,
|
|
162
|
+
size_t /*count*/) {
|
|
163
|
+
// A developer-menu affordance; iOS throws here for the same reason.
|
|
164
|
+
LOG(WARNING) << "worklets: slow animations are not supported on this platform";
|
|
165
|
+
return Value(false);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
#endif
|
|
169
|
+
|
|
170
|
+
} // namespace basalt
|
|
171
|
+
|
|
172
|
+
#ifdef BASALT_HAS_WORKLETS
|
|
173
|
+
// The logging seam worklets' C++ declares and leaves to each platform: Android
|
|
174
|
+
// writes to logcat, Apple to os_log, and this to the same place every other log
|
|
175
|
+
// line in this project goes.
|
|
176
|
+
namespace worklets {
|
|
177
|
+
|
|
178
|
+
void PlatformLogger::log(const char *str) {
|
|
179
|
+
LOG(INFO) << "[worklets] " << str;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
void PlatformLogger::log(const std::string &str) {
|
|
183
|
+
LOG(INFO) << "[worklets] " << str;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
void PlatformLogger::log(const double d) {
|
|
187
|
+
LOG(INFO) << "[worklets] " << d;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
void PlatformLogger::log(const int i) {
|
|
191
|
+
LOG(INFO) << "[worklets] " << i;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
void PlatformLogger::log(const bool b) {
|
|
195
|
+
LOG(INFO) << "[worklets] " << (b ? "true" : "false");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
} // namespace worklets
|
|
199
|
+
#endif
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// react-native-worklets, which is what Reanimated 4 is built on.
|
|
2
|
+
//
|
|
3
|
+
// The package ships its portable half as C++ in `Common/cpp` -- a second
|
|
4
|
+
// JavaScript runtime for the UI thread, the serialisation that gets a function
|
|
5
|
+
// into it, the schedulers between the two -- depending on jsi, Hermes, a call
|
|
6
|
+
// invoker and nothing else. So it compiles here unmodified, at the app's own
|
|
7
|
+
// version, the same arrangement expo-modules-core has. See cmake/Worklets.cmake.
|
|
8
|
+
//
|
|
9
|
+
// What the package does not ship for a desktop is the host half, and this is
|
|
10
|
+
// it: the TurboModule its JavaScript looks up, a UI scheduler, a frame source,
|
|
11
|
+
// and the platform logger its C++ declares and leaves to each platform.
|
|
12
|
+
//
|
|
13
|
+
// The whole of the port is those four things, which is worth saying plainly:
|
|
14
|
+
// the hard part of worklets -- a separate Hermes runtime, capturing a closure
|
|
15
|
+
// across it, keeping shared values coherent between two runtimes -- is written
|
|
16
|
+
// once, portably, by the people who wrote it. A platform contributes a thread
|
|
17
|
+
// to run on and a heartbeat.
|
|
18
|
+
|
|
19
|
+
#pragma once
|
|
20
|
+
|
|
21
|
+
#include <ReactCommon/TurboModule.h>
|
|
22
|
+
|
|
23
|
+
#include <memory>
|
|
24
|
+
|
|
25
|
+
namespace basalt {
|
|
26
|
+
|
|
27
|
+
// Whether this build has react-native-worklets compiled into it, for the log
|
|
28
|
+
// line that tells a developer which of the two situations they are in.
|
|
29
|
+
bool hasWorklets();
|
|
30
|
+
|
|
31
|
+
#ifdef BASALT_HAS_WORKLETS
|
|
32
|
+
|
|
33
|
+
class DesktopWorkletsModule : public facebook::react::TurboModule {
|
|
34
|
+
public:
|
|
35
|
+
static constexpr const char *kModuleName = "WorkletsModule";
|
|
36
|
+
|
|
37
|
+
explicit DesktopWorkletsModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker);
|
|
38
|
+
~DesktopWorkletsModule() override;
|
|
39
|
+
|
|
40
|
+
private:
|
|
41
|
+
static facebook::jsi::Value installTurboModule(facebook::jsi::Runtime &runtime,
|
|
42
|
+
facebook::react::TurboModule &module,
|
|
43
|
+
const facebook::jsi::Value *args,
|
|
44
|
+
size_t count);
|
|
45
|
+
static facebook::jsi::Value start(facebook::jsi::Runtime &runtime,
|
|
46
|
+
facebook::react::TurboModule &module,
|
|
47
|
+
const facebook::jsi::Value *args,
|
|
48
|
+
size_t count);
|
|
49
|
+
static facebook::jsi::Value toggleSlowAnimations(facebook::jsi::Runtime &runtime,
|
|
50
|
+
facebook::react::TurboModule &module,
|
|
51
|
+
const facebook::jsi::Value *args,
|
|
52
|
+
size_t count);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
#endif
|
|
56
|
+
|
|
57
|
+
} // namespace basalt
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// Does the shared core actually stand on its own?
|
|
2
|
+
//
|
|
3
|
+
// `basalt_core` compiles without a toolkit on the include path, which says
|
|
4
|
+
// nothing about whether it *links* without one. A header that is never included
|
|
5
|
+
// cannot betray you; an undefined symbol at link time can.
|
|
6
|
+
//
|
|
7
|
+
// So this is a program that links the core and nothing platform-specific, and
|
|
8
|
+
// touches each module the core provides. If it links, a new desktop platform
|
|
9
|
+
// can build the core as-is. If it does not, the missing symbols are exactly the
|
|
10
|
+
// list of what that platform has to implement -- which is the more useful
|
|
11
|
+
// outcome of the two, and the reason this prints them rather than asserting.
|
|
12
|
+
//
|
|
13
|
+
// It is not a test of behaviour. It never constructs a runtime and never
|
|
14
|
+
// renders anything. It answers one question: what does a second platform owe?
|
|
15
|
+
//
|
|
16
|
+
// What it deliberately does not include is any capability package's header.
|
|
17
|
+
// A package's core half is compiled into `basalt_core`, so its seam is a
|
|
18
|
+
// symbol this has to satisfy -- but an app installs the packages it wants and
|
|
19
|
+
// core has to compile in one that installed none. So a package brings its own
|
|
20
|
+
// stub, through BASALT_PACKAGE_PROBE_SOURCES; see
|
|
21
|
+
// packages/basalt-notifications/native/probe_stub.cpp. Including
|
|
22
|
+
// one here made core fail to compile in an app without that package, and the
|
|
23
|
+
// failure read as a missing file in core rather than as a dependency core
|
|
24
|
+
// should never have had.
|
|
25
|
+
|
|
26
|
+
#include "AppearanceModule.h"
|
|
27
|
+
#include "ColorScheme.h"
|
|
28
|
+
#include "CoreModules.h"
|
|
29
|
+
#include "ComponentRegistry.h"
|
|
30
|
+
#include "ExpoRuntime.h"
|
|
31
|
+
#include "FontRegistry.h"
|
|
32
|
+
#include "PlatformConstantsModule.h"
|
|
33
|
+
#include "SourceCodeModule.h"
|
|
34
|
+
#include "PlatformServices.h"
|
|
35
|
+
#include "MenuModel.h"
|
|
36
|
+
#include "WindowControl.h"
|
|
37
|
+
#include "WindowHost.h"
|
|
38
|
+
#include "StatusBarModule.h"
|
|
39
|
+
#include "WorkletsModule.h"
|
|
40
|
+
|
|
41
|
+
#include <cstdio>
|
|
42
|
+
#include <string>
|
|
43
|
+
#include <vector>
|
|
44
|
+
|
|
45
|
+
// The seam, stubbed, so that the link answers the question fully rather than
|
|
46
|
+
// stopping at the first thing missing. A real platform implements these against
|
|
47
|
+
// fontconfig, Core Text or DirectWrite; a platform that has not yet gets this
|
|
48
|
+
// far and no further, which is the point.
|
|
49
|
+
namespace basalt {
|
|
50
|
+
bool registerFont(const std::string &, const std::string &) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
std::string resolveFontFamily(const std::string &name) {
|
|
54
|
+
return name;
|
|
55
|
+
}
|
|
56
|
+
bool isFontRegistered(const std::string &) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
unsigned long fontGeneration() {
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
std::string registeredFontNamesJoined(char) {
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// The colour-scheme seam, stubbed the same way. A real platform answers from
|
|
67
|
+
// NSAppearance, GtkSettings or the Windows registry; one that has not yet gets
|
|
68
|
+
// this far and no further.
|
|
69
|
+
ColorScheme systemColorScheme() {
|
|
70
|
+
return ColorScheme::Light;
|
|
71
|
+
}
|
|
72
|
+
void startObservingColorScheme() {}
|
|
73
|
+
|
|
74
|
+
// The platform-services seam, stubbed the same way: clipboard, opening a URL
|
|
75
|
+
// and showing a dialog are the three things a core module cannot do alone.
|
|
76
|
+
std::string clipboardText() {
|
|
77
|
+
return {};
|
|
78
|
+
}
|
|
79
|
+
void setClipboardText(const std::string &) {}
|
|
80
|
+
bool canOpenUrl(const std::string &) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
bool openUrl(const std::string &) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
void showAlert(const AlertRequest &, AlertCallback) {}
|
|
87
|
+
// A file dialog and a share sheet, stubbed the same way. Both answer "the person
|
|
88
|
+
// cancelled", which is what a platform that cannot ask them should say.
|
|
89
|
+
//
|
|
90
|
+
// Missing here until a capability package called one. The probe only ever sees
|
|
91
|
+
// the symbols something in core's link closure *references*, and nothing in core
|
|
92
|
+
// reached these two -- the dialog module and the share module are both only
|
|
93
|
+
// reachable from a host. So the seam was one a new port owed and the probe did
|
|
94
|
+
// not say so, which is the one thing this file exists to prevent.
|
|
95
|
+
void showFileDialog(const FileDialogRequest &, FileDialogCallback onDone) {
|
|
96
|
+
if (onDone) {
|
|
97
|
+
onDone(true, {});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
void shareContent(const ShareRequest &, ShareCallback onDone) {
|
|
101
|
+
if (onDone) {
|
|
102
|
+
onDone(ShareOutcome::Dismissed, {});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// A popup menu, stubbed the same way. Answering -1 is the seam's "dismissed",
|
|
106
|
+
// which is the honest reply from a platform that cannot show one.
|
|
107
|
+
void showMenu(const MenuRequest &, MenuCallback onChosen) {
|
|
108
|
+
if (onChosen) {
|
|
109
|
+
onChosen(-1);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Added when the gesture recognisers arrived: "run this on the UI thread", now
|
|
113
|
+
// and later. A platform with a run loop has both already; this one has neither
|
|
114
|
+
// and says so.
|
|
115
|
+
// The window seam, stubbed the same way. A real platform answers from a
|
|
116
|
+
// GtkWindow, an NSWindow or an HWND; one that has not yet reports a window of
|
|
117
|
+
// no size, which is what an app reading bounds before there is one sees.
|
|
118
|
+
WindowBounds windowBounds() {
|
|
119
|
+
return {};
|
|
120
|
+
}
|
|
121
|
+
void setWindowSize(double, double) {}
|
|
122
|
+
void setWindowPosition(double, double) {}
|
|
123
|
+
void centerWindow() {}
|
|
124
|
+
void setWindowFullScreen(bool) {}
|
|
125
|
+
void applyWindowSizeLimits() {}
|
|
126
|
+
void setWindowResizable(bool) {}
|
|
127
|
+
void setWindowAlwaysOnTop(bool) {}
|
|
128
|
+
WindowCapabilities windowCapabilities() {
|
|
129
|
+
// A platform with no window manager does none of them, which is the honest
|
|
130
|
+
// answer rather than a convenient one: this probe exists to say what a new
|
|
131
|
+
// port owes, and four falses is the starting position.
|
|
132
|
+
return WindowCapabilities{};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// The application menu, stubbed the same way. A platform with no menu bar
|
|
136
|
+
// answers exactly this, which is also what GTK answers for real.
|
|
137
|
+
bool applicationMenuSupported() {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
void setApplicationMenu(const MenuModel &, std::function<void(int)>) {}
|
|
141
|
+
std::string describeApplicationMenu() {
|
|
142
|
+
return {};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// The window seam's other half: opening one. A platform that cannot answers
|
|
146
|
+
// zero, which every caller reads as "no window was opened".
|
|
147
|
+
facebook::react::SurfaceId openHostWindow(const NewWindowOptions &) {
|
|
148
|
+
return 0;
|
|
149
|
+
}
|
|
150
|
+
void closeHostWindow(facebook::react::SurfaceId) {}
|
|
151
|
+
std::vector<facebook::react::SurfaceId> hostWindows() {
|
|
152
|
+
return {};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
void postDelayed(double, std::function<void()>) {}
|
|
156
|
+
void postToUiThread(std::function<void()>) {}
|
|
157
|
+
bool isUiThread() {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
} // namespace basalt
|
|
161
|
+
|
|
162
|
+
int main() {
|
|
163
|
+
using basalt::DesktopPlatformConstantsModule;
|
|
164
|
+
using basalt::DesktopAccessibilityInfoModule;
|
|
165
|
+
using basalt::DesktopAlertModule;
|
|
166
|
+
using basalt::DesktopAppearanceModule;
|
|
167
|
+
using basalt::DesktopClipboardModule;
|
|
168
|
+
using basalt::DesktopI18nManagerModule;
|
|
169
|
+
using basalt::DesktopLinkingModule;
|
|
170
|
+
using basalt::DesktopSourceCodeModule;
|
|
171
|
+
using basalt::DesktopStatusBarModule;
|
|
172
|
+
|
|
173
|
+
// Each of these is a symbol the linker must find in the core alone.
|
|
174
|
+
const std::string url =
|
|
175
|
+
basalt::scriptURLFor("bundle.js", false, "localhost", 8081, "index", "probe");
|
|
176
|
+
const bool expo = basalt::hasExpoRuntime();
|
|
177
|
+
const bool worklets = basalt::hasWorklets();
|
|
178
|
+
|
|
179
|
+
// The seams: declared by the core, implemented by a platform. On a platform
|
|
180
|
+
// that has not implemented them, the link fails here and names them.
|
|
181
|
+
const bool registered = basalt::isFontRegistered("nothing");
|
|
182
|
+
const unsigned long generation = basalt::fontGeneration();
|
|
183
|
+
const char *scheme = basalt::colorSchemeName(basalt::effectiveColorScheme());
|
|
184
|
+
|
|
185
|
+
// Named so the link has to find each module the core claims to provide.
|
|
186
|
+
std::printf("core links.\n");
|
|
187
|
+
// Named so the link has to find each module the core claims to provide.
|
|
188
|
+
std::printf(" modules %s, %s, %s, %s,\n",
|
|
189
|
+
std::string(DesktopPlatformConstantsModule::kModuleName).c_str(),
|
|
190
|
+
std::string(DesktopSourceCodeModule::kModuleName).c_str(),
|
|
191
|
+
std::string(DesktopStatusBarModule::kModuleName).c_str(),
|
|
192
|
+
std::string(DesktopAppearanceModule::kModuleName).c_str());
|
|
193
|
+
std::printf(" %s, %s, %s, %s, %s\n",
|
|
194
|
+
std::string(DesktopClipboardModule::kModuleName).c_str(),
|
|
195
|
+
std::string(DesktopAlertModule::kModuleName).c_str(),
|
|
196
|
+
std::string(DesktopLinkingModule::kModuleName).c_str(),
|
|
197
|
+
std::string(DesktopI18nManagerModule::kModuleName).c_str(),
|
|
198
|
+
std::string(DesktopAccessibilityInfoModule::kModuleName).c_str());
|
|
199
|
+
std::printf(" scriptURLFor %s\n", url.c_str());
|
|
200
|
+
std::printf(" expo runtime %s\n", expo ? "compiled in" : "not compiled in");
|
|
201
|
+
std::printf(" worklets %s\n", worklets ? "compiled in" : "not compiled in");
|
|
202
|
+
std::printf(" font seam isFontRegistered=%d generation=%lu\n",
|
|
203
|
+
registered ? 1 : 0,
|
|
204
|
+
generation);
|
|
205
|
+
std::printf(" colour scheme %s\n", scheme);
|
|
206
|
+
std::printf(" services seam canOpenUrl=%d clipboard=\"%s\"\n",
|
|
207
|
+
basalt::canOpenUrl("https://example.com") ? 1 : 0,
|
|
208
|
+
basalt::clipboardText().c_str());
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// A place for a unit test to watch events arrive.
|
|
2
|
+
//
|
|
3
|
+
// Neither host suite could see an event. The managers ask
|
|
4
|
+
// `eventEmitterForTag` for an emitter and call `onChange`, `onFocus`,
|
|
5
|
+
// `onKeyPress` on it, and the shadow views the tests hand-build carry no
|
|
6
|
+
// emitter at all -- so `test_appkit_textinput.mm` says, accurately, that what
|
|
7
|
+
// it pins is "that the round trip did not throw". Nothing below the
|
|
8
|
+
// end-to-end suite knew whether an event fired, let alone in what order.
|
|
9
|
+
//
|
|
10
|
+
// ## Why there is no stub emitter here
|
|
11
|
+
//
|
|
12
|
+
// The obvious fix is a fake emitter handed back through the lookup, and it
|
|
13
|
+
// cannot work: `TextInputEventEmitter` contains the word `virtual` zero
|
|
14
|
+
// times, so there is nothing to override. Every `onX` calls the non-virtual
|
|
15
|
+
// `EventEmitter::dispatchEvent`, which locks a `weak_ptr<const
|
|
16
|
+
// EventDispatcher>` and returns quietly when it is empty. That empty weak
|
|
17
|
+
// pointer is exactly the state the suites were in.
|
|
18
|
+
//
|
|
19
|
+
// ## So this builds the real thing instead
|
|
20
|
+
//
|
|
21
|
+
// `EventDispatcher` offers a listener -- `std::function<bool(const RawEvent
|
|
22
|
+
// &)>` -- and consults it at the top of `dispatchEvent`, before the logger and
|
|
23
|
+
// before the queue. Returning true says the event was handled and stops the
|
|
24
|
+
// default dispatch, so nothing downstream ever runs and no beat is needed to
|
|
25
|
+
// flush anything.
|
|
26
|
+
//
|
|
27
|
+
// The one awkward piece is that `EventQueue`'s constructor calls
|
|
28
|
+
// `setBeatCallback` on the beat immediately, so it cannot be null, and
|
|
29
|
+
// `EventBeat` holds a `RuntimeScheduler &`. That sounds like the whole JS
|
|
30
|
+
// machinery and is not: `RuntimeScheduler` takes a `RuntimeExecutor`, which is
|
|
31
|
+
// a `std::function`, and a runtime only appears when something invokes it.
|
|
32
|
+
// Nothing here does.
|
|
33
|
+
//
|
|
34
|
+
// ## What can be asserted, and what cannot
|
|
35
|
+
//
|
|
36
|
+
// Event *types* and their *order*, which is what the payload-free half of an
|
|
37
|
+
// event is. Payload values cannot: `TextInputEventEmitter` builds a
|
|
38
|
+
// `jsi::Object` through a `ValueFactory`, and reading one back needs a
|
|
39
|
+
// `jsi::Runtime` -- which is the machinery these suites exist to avoid. What
|
|
40
|
+
// a value ends up as is the end-to-end suite's to check; that the event fired
|
|
41
|
+
// at all, and before or after its neighbour, is this one's.
|
|
42
|
+
|
|
43
|
+
#pragma once
|
|
44
|
+
|
|
45
|
+
#include <react/renderer/core/EventDispatcher.h>
|
|
46
|
+
#include <react/renderer/core/EventEmitter.h>
|
|
47
|
+
#include <react/renderer/core/EventListener.h>
|
|
48
|
+
#include <react/renderer/core/EventQueueProcessor.h>
|
|
49
|
+
#include <react/renderer/core/RawEvent.h>
|
|
50
|
+
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
|
51
|
+
|
|
52
|
+
#include <functional>
|
|
53
|
+
#include <memory>
|
|
54
|
+
#include <mutex>
|
|
55
|
+
#include <string>
|
|
56
|
+
#include <utility>
|
|
57
|
+
#include <vector>
|
|
58
|
+
|
|
59
|
+
namespace basalt::testing {
|
|
60
|
+
|
|
61
|
+
// An EventBeat that never beats. `EventQueue` requires one and this test never
|
|
62
|
+
// reaches the queue, so what matters is that it exists and does nothing.
|
|
63
|
+
class IdleEventBeat : public facebook::react::EventBeat {
|
|
64
|
+
public:
|
|
65
|
+
IdleEventBeat(std::shared_ptr<OwnerBox> ownerBox,
|
|
66
|
+
facebook::react::RuntimeScheduler &scheduler)
|
|
67
|
+
: EventBeat(std::move(ownerBox), scheduler) {}
|
|
68
|
+
|
|
69
|
+
void request() const override {}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
class EventRecorder {
|
|
73
|
+
public:
|
|
74
|
+
EventRecorder()
|
|
75
|
+
: scheduler_([](std::function<void(facebook::jsi::Runtime &)> &&) {}),
|
|
76
|
+
dispatcher_(std::make_shared<const facebook::react::EventDispatcher>(
|
|
77
|
+
facebook::react::EventQueueProcessor(nullptr, nullptr, nullptr, {}),
|
|
78
|
+
std::make_unique<IdleEventBeat>(
|
|
79
|
+
std::make_shared<facebook::react::EventBeat::OwnerBox>(), scheduler_),
|
|
80
|
+
[](const facebook::react::StateUpdate &) {},
|
|
81
|
+
std::weak_ptr<facebook::react::EventLogger>{})),
|
|
82
|
+
listener_(std::make_shared<const facebook::react::EventListener>(
|
|
83
|
+
[this](const facebook::react::RawEvent &event) {
|
|
84
|
+
std::scoped_lock lock(mutex_);
|
|
85
|
+
seen_.push_back(event.type);
|
|
86
|
+
// Handled: the event stops here rather than going on to a queue
|
|
87
|
+
// that would need a JavaScript thread to drain it.
|
|
88
|
+
return true;
|
|
89
|
+
})) {
|
|
90
|
+
dispatcher_->addListener(listener_);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// An emitter of the kind a manager will look for. The event target is null,
|
|
94
|
+
// which `EventEmitter::dispatchEvent` moves into the `RawEvent` without
|
|
95
|
+
// touching -- a tag is not what is being asserted here.
|
|
96
|
+
// Non-const, because that is what `ShadowView::eventEmitter` is at this
|
|
97
|
+
// React Native. Every `onX` is a const method, so it makes no difference to
|
|
98
|
+
// the caller.
|
|
99
|
+
template <typename Emitter>
|
|
100
|
+
std::shared_ptr<Emitter> emitter() const {
|
|
101
|
+
return std::make_shared<Emitter>(nullptr, dispatcher_);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// The event types seen so far, in the order they were dispatched. Names are
|
|
105
|
+
// React Native's own normalised spelling: see `normalizeEventType`.
|
|
106
|
+
std::vector<std::string> seen() const {
|
|
107
|
+
std::scoped_lock lock(mutex_);
|
|
108
|
+
return seen_;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void clear() {
|
|
112
|
+
std::scoped_lock lock(mutex_);
|
|
113
|
+
seen_.clear();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private:
|
|
117
|
+
facebook::react::RuntimeScheduler scheduler_;
|
|
118
|
+
std::shared_ptr<const facebook::react::EventDispatcher> dispatcher_;
|
|
119
|
+
std::shared_ptr<const facebook::react::EventListener> listener_;
|
|
120
|
+
mutable std::mutex mutex_;
|
|
121
|
+
std::vector<std::string> seen_;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
} // namespace basalt::testing
|