diff --git a/FabricExample/android/app/src/main/java/com/fabricexample/MainApplication.kt b/FabricExample/android/app/src/main/java/com/fabricexample/MainApplication.kt index 6965a5b9aa..6ec720cd7d 100644 --- a/FabricExample/android/app/src/main/java/com/fabricexample/MainApplication.kt +++ b/FabricExample/android/app/src/main/java/com/fabricexample/MainApplication.kt @@ -38,7 +38,7 @@ class MainApplication : Application(), ReactApplication { SoLoader.init(this, false) if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { // If you opted-in for the New Architecture, we load the native entry point for this app. - load() + load(bridgelessEnabled = true) } ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager) } diff --git a/FabricExample/android/settings.gradle b/FabricExample/android/settings.gradle index e5ed5d29b3..dc9f27834f 100644 --- a/FabricExample/android/settings.gradle +++ b/FabricExample/android/settings.gradle @@ -2,3 +2,12 @@ rootProject.name = 'FabricExample' apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' includeBuild('../node_modules/@react-native/gradle-plugin') + +includeBuild('../node_modules/react-native') { + dependencySubstitution { + substitute(module("com.facebook.react:react-android")).using(project(":packages:react-native:ReactAndroid")) + substitute(module("com.facebook.react:react-native")).using(project(":packages:react-native:ReactAndroid")) + substitute(module("com.facebook.react:hermes-android")).using(project(":packages:react-native:ReactAndroid:hermes-engine")) + substitute(module("com.facebook.react:hermes-engine")).using(project(":packages:react-native:ReactAndroid:hermes-engine")) + } +} diff --git a/FabricExample/ios/FabricExample.xcodeproj/project.pbxproj b/FabricExample/ios/FabricExample.xcodeproj/project.pbxproj index a748eb43be..d0d8605086 100644 --- a/FabricExample/ios/FabricExample.xcodeproj/project.pbxproj +++ b/FabricExample/ios/FabricExample.xcodeproj/project.pbxproj @@ -605,7 +605,8 @@ ); OTHER_LDFLAGS = ( "$(inherited)", - " ", + "-Wl", + "-ld_classic", ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; @@ -679,7 +680,8 @@ ); OTHER_LDFLAGS = ( "$(inherited)", - " ", + "-Wl", + "-ld_classic", ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; diff --git a/FabricExample/ios/FabricExample/AppDelegate.mm b/FabricExample/ios/FabricExample/AppDelegate.mm index 04f5ea2dbc..514b94d70d 100644 --- a/FabricExample/ios/FabricExample/AppDelegate.mm +++ b/FabricExample/ios/FabricExample/AppDelegate.mm @@ -1,6 +1,12 @@ #import "AppDelegate.h" #import +#import +#import +#import + +@interface AppDelegate () {} +@end @implementation AppDelegate @@ -19,6 +25,22 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge return [self getBundleURL]; } +- (BOOL)bridgelessEnabled +{ + return YES; +} + +#pragma mark RCTTurboModuleManagerDelegate + +- (std::shared_ptr)getTurboModule:(const std::string &)name + jsInvoker:(std::shared_ptr)jsInvoker +{ + if (name == "RNGHTurboCppModule") { + return std::make_shared(jsInvoker); + } + return nullptr; +} + - (NSURL *)getBundleURL { #if DEBUG diff --git a/FabricExample/ios/Podfile.lock b/FabricExample/ios/Podfile.lock index 3e351a0688..6bf86c5ab2 100644 --- a/FabricExample/ios/Podfile.lock +++ b/FabricExample/ios/Podfile.lock @@ -1439,9 +1439,9 @@ SPEC CHECKSUMS: React-runtimescheduler: df8945a656356ff10f58f65a70820478bfcf33ad React-utils: f5bc61e7ea3325c0732ae2d755f4441940163b85 ReactCommon: 45b5d4f784e869c44a6f5a8fad5b114ca8f78c53 - RNGestureHandler: b028dd5cade762010a72ee9be3afac17a0f72787 + RNGestureHandler: 76cb9f767ff56c3e77bcbbbc5ed9c1cc069bbe56 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - Yoga: e64aa65de36c0832d04e8c7bd614396c77a80047 + Yoga: 13c8ef87792450193e117976337b8527b49e8c03 PODFILE CHECKSUM: 792f7d0ed591c328474645afc856de4fd1732c31 diff --git a/RNGestureHandler.podspec b/RNGestureHandler.podspec index 8d4a06c621..96c8a20587 100644 --- a/RNGestureHandler.podspec +++ b/RNGestureHandler.podspec @@ -14,7 +14,11 @@ Pod::Spec.new do |s| s.license = "MIT" s.author = { package["author"]["name"] => package["author"]["email"] } s.source = { :git => "https://github.com/software-mansion/react-native-gesture-handler", :tag => "#{s.version}" } - s.source_files = "apple/**/*.{h,m,mm}" + if new_arch_enabled + s.source_files = ["apple/**/*.{h,m,mm}", "common/cpp/**/*.{cpp,h}"] + else + s.source_files = ["apple/**/*.{h,m,mm}"] + end s.requires_arc = true s.platforms = { ios: apple_platform, tvos: apple_platform, osx: '10.15' } diff --git a/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt b/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt index c8aa3122d3..f0bd995f08 100644 --- a/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +++ b/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt @@ -442,17 +442,20 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) : @ReactMethod(isBlockingSynchronousMethod = true) override fun install(): Boolean { - reactApplicationContext.runOnJSQueueThread { - try { + return try { + if (reactApplicationContext.javaScriptContextHolder == null) { + return false + } + reactApplicationContext.runOnJSQueueThread { SoLoader.loadLibrary("gesturehandler") val jsContext = reactApplicationContext.javaScriptContextHolder!! decorateRuntime(jsContext.get()) - } catch (exception: Exception) { - Log.w("[RNGestureHandler]", "Could not install JSI bindings.") } + true + } catch (exception: Exception) { + Log.w("[RNGestureHandler]", "Could not install JSI bindings.") + false } - - return true } private external fun decorateRuntime(jsiPtr: Long) @@ -645,6 +648,12 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) : } companion object { + init { + if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { + // we need here so it is called before cpp turbo module is requested + SoLoader.loadLibrary("gesturehandler") + } + } const val MODULE_NAME = "RNGestureHandlerModule" private const val KEY_SHOULD_CANCEL_WHEN_OUTSIDE = "shouldCancelWhenOutside" private const val KEY_ENABLED = "enabled" diff --git a/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt b/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt index f6ea6a107f..e047cec9f9 100644 --- a/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +++ b/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt @@ -10,8 +10,10 @@ import com.facebook.react.bridge.ReactContext import com.facebook.react.bridge.UiThreadUtil import com.facebook.react.common.ReactConstants import com.facebook.react.uimanager.RootView +import com.facebook.react.uimanager.ThemedReactContext import com.swmansion.gesturehandler.core.GestureHandler import com.swmansion.gesturehandler.core.GestureHandlerOrchestrator +import java.lang.Exception class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView: ViewGroup) { private val orchestrator: GestureHandlerOrchestrator? @@ -24,7 +26,12 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView: UiThreadUtil.assertOnUiThread() val wrappedViewTag = wrappedView.id check(wrappedViewTag >= 1) { "Expect view tag to be set for $wrappedView" } - val module = context.getNativeModule(RNGestureHandlerModule::class.java)!! + + val module = try { + context.getNativeModule(RNGestureHandlerModule::class.java)!! + } catch (e: Exception) { + (context as ThemedReactContext).reactApplicationContext.getNativeModule(RNGestureHandlerModule::class.java)!! + } val registry = module.registry rootView = findRootViewTag(wrappedView) Log.i( @@ -49,7 +56,11 @@ class RNGestureHandlerRootHelper(private val context: ReactContext, wrappedView: ReactConstants.TAG, "[GESTURE HANDLER] Tearing down gesture handler registered for root view $rootView" ) - val module = context.getNativeModule(RNGestureHandlerModule::class.java)!! + val module = try { + context.getNativeModule(RNGestureHandlerModule::class.java)!! + } catch (e: Exception) { + (context as ThemedReactContext).reactApplicationContext.getNativeModule(RNGestureHandlerModule::class.java)!! + } with(module) { registry.dropHandler(jsGestureHandler!!.tag) unregisterRootHelper(this@RNGestureHandlerRootHelper) diff --git a/android/src/main/jni/CMakeLists.txt b/android/src/main/jni/CMakeLists.txt index 74dd773ab3..3ed088449a 100644 --- a/android/src/main/jni/CMakeLists.txt +++ b/android/src/main/jni/CMakeLists.txt @@ -14,18 +14,26 @@ set(REACT_ANDROID_DIR "${REACT_NATIVE_DIR}/ReactAndroid") include(${REACT_ANDROID_DIR}/cmake-utils/folly-flags.cmake) add_compile_options(${folly_FLAGS}) +file(GLOB tm_SRC CONFIGURE_DEPENDS ${REACT_ANDROID_DIR}/../../../node_modules/react-native-gesture-handler/common/cpp/*.cpp) +file(GLOB tm_generated_SRC CONFIGURE_DEPENDS *.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../../build/generated/source/codegen/jni/react/renderer/components/rngesturehandler_codegen/rngesturehandler_codegenJSI-generated.cpp) + add_library(${PACKAGE_NAME} SHARED cpp-adapter.cpp + ${tm_SRC} + ${tm_generated_SRC} ) target_include_directories( ${PACKAGE_NAME} - PRIVATE + PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/../../../../common/cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/../../../build/generated/source/codegen/jni/react/renderer/components/rngesturehandler_codegen" "${REACT_NATIVE_DIR}/ReactCommon" ) find_package(ReactAndroid REQUIRED CONFIG) +find_package(fbjni REQUIRED CONFIG) target_link_libraries( gesturehandler @@ -34,4 +42,7 @@ target_link_libraries( ReactAndroid::react_render_graphics ReactAndroid::jsi ReactAndroid::react_nativemodule_core + fbjni::fbjni + ReactAndroid::turbomodulejsijni + ReactAndroid::react_newarchdefaults ) diff --git a/android/src/main/jni/cpp-adapter.cpp b/android/src/main/jni/cpp-adapter.cpp index 6b1d41780d..3a0ecd20ce 100644 --- a/android/src/main/jni/cpp-adapter.cpp +++ b/android/src/main/jni/cpp-adapter.cpp @@ -1,44 +1,42 @@ #include #include +#include "RNGHTurboCppModule.h" +#include +#include -#include +std::function( + const std::string&, + const std::shared_ptr&)> cxxModuleProviderHolder; -using namespace facebook; -using namespace react; +namespace facebook::react { -void decorateRuntime(jsi::Runtime &runtime) { - auto isFormsStackingContext = jsi::Function::createFromHostFunction( - runtime, - jsi::PropNameID::forAscii(runtime, "isFormsStackingContext"), - 1, - [](jsi::Runtime &runtime, - const jsi::Value &thisValue, - const jsi::Value *arguments, - size_t count) -> jsi::Value { - if (!arguments[0].isObject()) { - return jsi::Value::null(); - } - auto shadowNode = arguments[0] - .asObject(runtime) - .getHostObject(runtime) - ->shadowNode; - bool isFormsStackingContext = shadowNode->getTraits().check( - ShadowNodeTraits::FormsStackingContext); +extern "C" JNIEXPORT void JNICALL +Java_com_swmansion_gesturehandler_react_RNGestureHandlerModule_decorateRuntime( + JNIEnv *env, + jobject clazz, + jlong jsiPtr) { + jsi::Runtime *runtime = reinterpret_cast(jsiPtr); + if (runtime) { + RNGHDecorateRuntime(*runtime); + } +} - return jsi::Value(isFormsStackingContext); - }); - runtime.global().setProperty( - runtime, "isFormsStackingContext", std::move(isFormsStackingContext)); +std::shared_ptr cxxModuleProvider( + const std::string& name, + const std::shared_ptr& jsInvoker) { + if (name == "RNGHTurboCppModule") { + return std::make_shared(jsInvoker); + } + return cxxModuleProviderHolder(name, jsInvoker); } -extern "C" JNIEXPORT void JNICALL -Java_com_swmansion_gesturehandler_react_RNGestureHandlerModule_decorateRuntime( - JNIEnv *env, - jobject clazz, - jlong jsiPtr) { - jsi::Runtime *runtime = reinterpret_cast(jsiPtr); - if (runtime) { - decorateRuntime(*runtime); - } +} // namespace facebook::react + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { + cxxModuleProviderHolder = facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider; + return facebook::jni::initialize(vm, [] { + facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider = + &facebook::react::cxxModuleProvider; + }); } diff --git a/apple/RNGestureHandlerManager.h b/apple/RNGestureHandlerManager.h index 59334d6459..a191817419 100644 --- a/apple/RNGestureHandlerManager.h +++ b/apple/RNGestureHandlerManager.h @@ -9,8 +9,13 @@ @interface RNGestureHandlerManager : NSObject +#ifdef RCT_NEW_ARCH_ENABLED +- (nonnull instancetype)initWithModuleRegistry:(nonnull RCTModuleRegistry *)moduleRegistry + viewRegistry:(nonnull RCTViewRegistry *)viewRegistry; +#else - (nonnull instancetype)initWithUIManager:(nonnull RCTUIManager *)uiManager eventDispatcher:(nonnull id)eventDispatcher; +#endif // RCT_NEW_ARCH_ENABLED - (void)createGestureHandler:(nonnull NSString *)handlerName tag:(nonnull NSNumber *)handlerTag diff --git a/apple/RNGestureHandlerManager.mm b/apple/RNGestureHandlerManager.mm index 7754cc1e68..7983c49477 100644 --- a/apple/RNGestureHandlerManager.mm +++ b/apple/RNGestureHandlerManager.mm @@ -49,26 +49,48 @@ @interface RNGestureHandlerManager () *_rootViewGestureRecognizers; NSMutableDictionary *_attachRetryCounter; +#ifdef RCT_NEW_ARCH_ENABLED + RCTModuleRegistry *_moduleRegistry; + RCTViewRegistry *_viewRegistry; +#else + RCTUIManager *_uiManager; +#endif // RCT_NEW_ARCH_ENABLED id _eventDispatcher; id _reanimatedModule; } +#ifdef RCT_NEW_ARCH_ENABLED +- (instancetype)initWithModuleRegistry:(RCTModuleRegistry *)moduleRegistry viewRegistry:(RCTViewRegistry *)viewRegistry +{ + if ((self = [super init])) { + _moduleRegistry = moduleRegistry; + _viewRegistry = viewRegistry; + _eventDispatcher = [_moduleRegistry moduleForName:"EventDispatcher"]; + [self initCommonProps]; + } + return self; +} +#else - (instancetype)initWithUIManager:(RCTUIManager *)uiManager eventDispatcher:(id)eventDispatcher { if ((self = [super init])) { _uiManager = uiManager; _eventDispatcher = eventDispatcher; - _registry = [RNGestureHandlerRegistry new]; - _rootViewGestureRecognizers = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]; - _attachRetryCounter = [[NSMutableDictionary alloc] init]; - _reanimatedModule = nil; + [self initCommonProps]; } return self; } +#endif // RCT_NEW_ARCH_ENABLED + +- (void)initCommonProps +{ + _registry = [RNGestureHandlerRegistry new]; + _rootViewGestureRecognizers = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]; + _attachRetryCounter = [[NSMutableDictionary alloc] init]; +} - (void)createGestureHandler:(NSString *)handlerName tag:(NSNumber *)handlerTag config:(NSDictionary *)config { @@ -115,7 +137,11 @@ - (void)attachGestureHandler:(nonnull NSNumber *)handlerTag toViewWithTag:(nonnull NSNumber *)viewTag withActionType:(RNGestureHandlerActionType)actionType { +#ifdef RCT_NEW_ARCH_ENABLED + RNGHUIView *view = [_viewRegistry viewForReactTag:viewTag]; +#else RNGHUIView *view = [_uiManager viewForReactTag:viewTag]; +#endif // RCT_NEW_ARCH_ENABLED #ifdef RCT_NEW_ARCH_ENABLED if (view == nil || view.superview == nil) { @@ -350,7 +376,7 @@ - (void)sendEventForReanimated:(RNGestureHandlerStateChange *)event #ifdef RCT_NEW_ARCH_ENABLED // Send event directly to Reanimated if (_reanimatedModule == nil) { - _reanimatedModule = [_uiManager.bridge moduleForName:@"ReanimatedModule"]; + _reanimatedModule = [_moduleRegistry moduleForName:"ReanimatedModule"]; } [_reanimatedModule eventDispatcherWillDispatchEvent:event]; diff --git a/apple/RNGestureHandlerModule.h b/apple/RNGestureHandlerModule.h index cbd599c308..703570d9d1 100644 --- a/apple/RNGestureHandlerModule.h +++ b/apple/RNGestureHandlerModule.h @@ -2,6 +2,7 @@ #import #ifdef RN_FABRIC_ENABLED +#import #import #else #import @@ -9,7 +10,7 @@ @interface RNGestureHandlerModule : RCTEventEmitter #ifdef RN_FABRIC_ENABLED - + #else #endif diff --git a/apple/RNGestureHandlerModule.mm b/apple/RNGestureHandlerModule.mm index 2d93938aea..740d735de6 100644 --- a/apple/RNGestureHandlerModule.mm +++ b/apple/RNGestureHandlerModule.mm @@ -12,9 +12,9 @@ #import #import #import -#import #import +#import "RNGHTurboCppModule.h" #endif // RCT_NEW_ARCH_ENABLED #import "RNGestureHandler.h" @@ -51,6 +51,10 @@ @implementation RNGestureHandlerModule { NSMutableArray *_operations; } +#ifdef RCT_NEW_ARCH_ENABLED +@synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED; +#endif // RCT_NEW_ARCH_ENABLED + RCT_EXPORT_MODULE() + (BOOL)requiresMainQueueSetup @@ -84,32 +88,24 @@ - (dispatch_queue_t)methodQueue } #ifdef RCT_NEW_ARCH_ENABLED -void decorateRuntime(jsi::Runtime &runtime) +- (void)initialize { - auto isFormsStackingContext = jsi::Function::createFromHostFunction( - runtime, - jsi::PropNameID::forAscii(runtime, "isFormsStackingContext"), - 1, - [](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *arguments, size_t count) -> jsi::Value { - if (!arguments[0].isObject()) { - return jsi::Value::null(); - } - - auto shadowNode = arguments[0].asObject(runtime).getHostObject(runtime)->shadowNode; - bool isFormsStackingContext = shadowNode->getTraits().check(ShadowNodeTraits::FormsStackingContext); - - return jsi::Value(isFormsStackingContext); - }); - runtime.global().setProperty(runtime, "isFormsStackingContext", std::move(isFormsStackingContext)); + _manager = [[RNGestureHandlerManager alloc] initWithModuleRegistry:self.moduleRegistry + viewRegistry:_viewRegistry_DEPRECATED]; + _operations = [NSMutableArray new]; } #endif // RCT_NEW_ARCH_ENABLED - (void)setBridge:(RCTBridge *)bridge { [super setBridge:bridge]; - +#ifdef RCT_NEW_ARCH_ENABLED + _manager = [[RNGestureHandlerManager alloc] initWithModuleRegistry:self.moduleRegistry + viewRegistry:_viewRegistry_DEPRECATED]; +#else _manager = [[RNGestureHandlerManager alloc] initWithUIManager:bridge.uiManager eventDispatcher:bridge.eventDispatcher]; +#endif // RCT_NEW_ARCH_ENABLED _operations = [NSMutableArray new]; #ifndef RCT_NEW_ARCH_ENABLED @@ -120,11 +116,14 @@ - (void)setBridge:(RCTBridge *)bridge #ifdef RCT_NEW_ARCH_ENABLED RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) { + if (!self.bridge) { + return @false; + } [self.bridge dispatchBlock:^{ RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge; auto runtime = (jsi::Runtime *)cxxBridge.runtime; - decorateRuntime(*runtime); + RNGHDecorateRuntime(*runtime); } queue:RCTJSThread]; @@ -190,13 +189,11 @@ - (void)setBridge:(RCTBridge *)bridge NSArray *operations = _operations; _operations = [NSMutableArray new]; - - [self.bridge.uiManager - addUIBlock:^(__unused RCTUIManager *manager, __unused NSDictionary *viewRegistry) { - for (GestureHandlerOperation operation in operations) { - operation(self->_manager); - } - }]; + [self.viewRegistry_DEPRECATED addUIBlock:^(RCTViewRegistry *viewRegistry) { + for (GestureHandlerOperation operation in operations) { + operation(self->_manager); + } + }]; #endif // RCT_NEW_ARCH_ENABLED } diff --git a/common/cpp/RNGHTurboCppModule.cpp b/common/cpp/RNGHTurboCppModule.cpp new file mode 100644 index 0000000000..cc62c67667 --- /dev/null +++ b/common/cpp/RNGHTurboCppModule.cpp @@ -0,0 +1,40 @@ +#include "RNGHTurboCppModule.h" +#include + +namespace facebook::react { + +void RNGHDecorateRuntime(jsi::Runtime &runtime) { + auto isFormsStackingContext = jsi::Function::createFromHostFunction( + runtime, + jsi::PropNameID::forAscii(runtime, "isFormsStackingContext"), + 1, + [](jsi::Runtime &runtime, + const jsi::Value &thisValue, + const jsi::Value *arguments, + size_t count) -> jsi::Value { + if (!arguments[0].isObject()) { + return jsi::Value::null(); + } + + auto shadowNode = arguments[0] + .asObject(runtime) + .getHostObject(runtime) + ->shadowNode; + bool isFormsStackingContext = shadowNode->getTraits().check( + ShadowNodeTraits::FormsStackingContext); + + return jsi::Value(isFormsStackingContext); + }); + runtime.global().setProperty( + runtime, "isFormsStackingContext", std::move(isFormsStackingContext)); +} + +RNGHTurboCppModule::RNGHTurboCppModule(std::shared_ptr jsInvoker) + : NativeRNGHTurboCppModuleCxxSpec(std::move(jsInvoker)) {} + +bool RNGHTurboCppModule::installBridgeless(jsi::Runtime& runtime) { + RNGHDecorateRuntime(runtime); + return true; +} + +} // namespace facebook::react diff --git a/common/cpp/RNGHTurboCppModule.h b/common/cpp/RNGHTurboCppModule.h new file mode 100644 index 0000000000..c6d2fe8cba --- /dev/null +++ b/common/cpp/RNGHTurboCppModule.h @@ -0,0 +1,22 @@ +#pragma once + +#if __has_include() // CocoaPod headers on Apple +#include +#elif __has_include("rngesturehandler_codegenJSI.h") // CMake headers on Android +#include "rngesturehandler_codegenJSI.h" +#endif +#include +#include + +namespace facebook::react { + +void RNGHDecorateRuntime(jsi::Runtime &runtime); + +class RNGHTurboCppModule : public NativeRNGHTurboCppModuleCxxSpec { + public: + RNGHTurboCppModule(std::shared_ptr jsInvoker); + + bool installBridgeless(jsi::Runtime& rt); +}; + +} // namespace facebook::react diff --git a/src/handlers/createHandler.tsx b/src/handlers/createHandler.tsx index 7f991fed1c..89fd977024 100644 --- a/src/handlers/createHandler.tsx +++ b/src/handlers/createHandler.tsx @@ -5,6 +5,8 @@ import { DeviceEventEmitter, EmitterSubscription, } from 'react-native'; +// @ts-ignore - its taken straight from RN +import { customDirectEventTypes } from 'react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry'; // @ts-ignore - it isn't typed by TS & don't have definitelyTyped types import deepEqual from 'lodash/isEqual'; import RNGestureHandlerModule from '../RNGestureHandlerModule'; @@ -33,6 +35,10 @@ import { ghQueueMicrotask } from '../ghQueueMicrotask'; const UIManagerAny = UIManager as any; +customDirectEventTypes.topOnGestureHandlerEvent = { + registrationName: 'onGestureHandlerEvent', +}; + const customGHEventsConfigFabricAndroid = { topOnGestureHandlerEvent: { registrationName: 'onGestureHandlerEvent' }, topOnGestureHandlerStateChange: { diff --git a/src/init.ts b/src/init.ts index 3f753cd72f..c0da4c4811 100644 --- a/src/init.ts +++ b/src/init.ts @@ -1,6 +1,7 @@ import { startListening } from './handlers/gestures/eventReceiver'; import RNGestureHandlerModule from './RNGestureHandlerModule'; import { isFabric } from './utils'; +import RNGHTurboCppModule from './specs/NativeRNGHTurboCppModule'; let fabricInitialized = false; @@ -12,7 +13,9 @@ export function initialize() { // method during render of GestureHandlerRootView export function maybeInitializeFabric() { if (isFabric() && !fabricInitialized) { - RNGestureHandlerModule.install(); - fabricInitialized = true; + fabricInitialized = RNGestureHandlerModule.install(); + if (!fabricInitialized) { + fabricInitialized = RNGHTurboCppModule?.installBridgeless() || false; + } } } diff --git a/src/specs/NativeRNGHTurboCppModule.ts b/src/specs/NativeRNGHTurboCppModule.ts new file mode 100644 index 0000000000..bc634dfd23 --- /dev/null +++ b/src/specs/NativeRNGHTurboCppModule.ts @@ -0,0 +1,7 @@ +import { TurboModule, TurboModuleRegistry } from 'react-native'; + +export interface Spec extends TurboModule { + readonly installBridgeless: () => boolean; +} + +export default TurboModuleRegistry.get('RNGHTurboCppModule');