Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bridgeless for [email protected] #5901

Merged
merged 4 commits into from
Apr 18, 2024
Merged

Conversation

piaskowyk
Copy link
Member

Summary

This pull request adjusts the Reanimated initialisation process to changes in React Native versions between 0.74.0-rc.4 and 0.74.0-rc.8. Now, the method setBridge is called in both bridgeless and bridgefull modes.

[super setBridge:bridge];

[bridge.uiManager.observerCoordinator addObserver:self];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use it on the new architecture

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I was wondering if we use it in RNGH to pass events to Reanimated but turns out we don't (in RNGH there's a function sendEventForReanimated that on new arch calls reanimatedEventDispatcher.sendEvent() which in turn calls reanimatedModule?.nodesManager?.onEventDispatch(event) so I guess that's okay).
  2. If it's not needed on the new architecture, let's wrap <RCTEventDispatcherObserver> in header file and eventDispatcherWillDispatchEvent: method inside #ifdef RCT_NEW_ARCH_ENABLED, what do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed offline, we refactor the whole initialization process in the following PR.

Copy link
Member

@WoLewicki WoLewicki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope it works now 🎉

[super setBridge:bridge];

[bridge.uiManager.observerCoordinator addObserver:self];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I was wondering if we use it in RNGH to pass events to Reanimated but turns out we don't (in RNGH there's a function sendEventForReanimated that on new arch calls reanimatedEventDispatcher.sendEvent() which in turn calls reanimatedModule?.nodesManager?.onEventDispatch(event) so I guess that's okay).
  2. If it's not needed on the new architecture, let's wrap <RCTEventDispatcherObserver> in header file and eventDispatcherWillDispatchEvent: method inside #ifdef RCT_NEW_ARCH_ENABLED, what do you think?

*/
- (void)setSurfacePresenter:(id<RCTSurfacePresenterStub>)surfacePresenter
{
_surfacePresenter = surfacePresenter;
_isBridgeless = true;
}

- (void)setBridge:(RCTBridge *)bridge
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit confusing that we have two separate places where we define setBridge: method (line 170 and line 207). I know it was like that prior to this PR. It's definitely not a blocker but we should do something about it in a separate PR.

Comment on lines -197 to -199
#ifndef NDEBUG
[self setReaSurfacePresenter];
#endif // NDEBUG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why is this code DEBUG-only? It was like that before, just curious to know if that's right.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be 🫣 I fixed it in 3e54ad0. Also. We still need REAInitializerRCTFabricSurface class for the Fabric with bridge :/

@@ -295,7 +279,7 @@ - (void)sendEventWithName:(NSString *)eventName body:(id)body

RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(installTurboModule : (nonnull NSString *)valueUnpackerCode)
{
if (!self.bridge) {
if (_isBridgeless) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need a separate implementation for bridgeless here?

The implementation for non-bridgeless looks good to me, just don't use [self.bridge respondsToSelector:@selector(runtime)] check – it no longer returns YES even if the runtime is there. The reason is that the bridge is now an instance of RCTBridgeProxy that inherits from NSProxy which probably has a custom implementation for respondsToSelector, different than NSObject.
We know that bridge.runtime has been available (as long as you have a category interface) for many RN versions back, so it seems to be safe to call it.

Two more nitpicks regarding the implementation for bridgeless:

  • Using [RCTBridge currentBridge] is very risky and I guess pretty easy to break in an app with multiple bridges (or now React instances).
  • bridge.jsCallInvoker was initially not available in the bridge proxy, but it is now. I think there is no need to use the runtime executor in its current shape (call invoker, runtime executor and runtime scheduler might be unified in the next RN versions).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bridge.jsCallInvoker was initially not available in the bridge proxy, but it is now. I think there is no need to use the runtime executor in its current shape (call invoker, runtime executor and runtime scheduler might be unified in the next RN versions).

Are you telling me that all our work on refactoring Reanimated initialization pipeline to be able to dynamically utilize either jsCallInvoker or runtimeExecutor was mostly pointless? 💀

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes xD

Maybe not entirely pointless, because the runtime executor might become the recommended way when the RN team figures out the final API for libraries. Right now we have two ways and both are lacking of features (e.g. synchronous executions), so I would recommend to use the call invoker and don't complicate the code too much until then.

Copy link
Collaborator

@tjzel tjzel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏

@piaskowyk piaskowyk enabled auto-merge April 18, 2024 09:43
@piaskowyk piaskowyk disabled auto-merge April 18, 2024 09:45
@piaskowyk piaskowyk merged commit 25bd0b9 into main Apr 18, 2024
14 checks passed
@piaskowyk piaskowyk deleted the @piaskowyk/[email protected] branch April 18, 2024 09:45
@piaskowyk piaskowyk mentioned this pull request Apr 22, 2024
github-merge-queue bot pushed a commit that referenced this pull request Apr 23, 2024
## Summary

This PR fixes production build for iOS. In
#5901 I
called `setReaSurfacePresenter` method but this one was defined only on
debug build.

Fixes
#5912

## Test plan

Run production build for iOS
github-merge-queue bot pushed a commit that referenced this pull request Apr 26, 2024
## Summary

This PR adds missing registration for platform events such as scroll
events on Bridgeless mode. In the previous PR
(#5901)
I checked support for Gesture Handler events, I forgot about platform
events

## Test plan

| before | after |
| --- | --- |
| <video
src="https://github.com/software-mansion/react-native-reanimated/assets/36106620/0d83f08a-16d4-4669-bfea-a630ded6451f"
/> | <video
src="https://github.com/software-mansion/react-native-reanimated/assets/36106620/2819b8b8-8c0a-4160-80d1-c5488ea9b0a5"
/> |
piaskowyk added a commit that referenced this pull request Apr 26, 2024
## Summary

This PR fixes production build for iOS. In
#5901 I
called `setReaSurfacePresenter` method but this one was defined only on
debug build.

Fixes
#5912

## Test plan

Run production build for iOS
piaskowyk added a commit that referenced this pull request Apr 26, 2024
## Summary

This PR adds missing registration for platform events such as scroll
events on Bridgeless mode. In the previous PR
(#5901)
I checked support for Gesture Handler events, I forgot about platform
events

## Test plan

| before | after |
| --- | --- |
| <video
src="https://github.com/software-mansion/react-native-reanimated/assets/36106620/0d83f08a-16d4-4669-bfea-a630ded6451f"
/> | <video
src="https://github.com/software-mansion/react-native-reanimated/assets/36106620/2819b8b8-8c0a-4160-80d1-c5488ea9b0a5"
/> |
github-merge-queue bot pushed a commit that referenced this pull request Apr 30, 2024
…5953)

## Summary

As I pointed out
[here](#5901 (comment)),
using `[RCTBridge currentBridge]` may lead to the wrong bridge in apps
that have multiple React instances, as is the case for expo-dev-client.


https://github.com/software-mansion/react-native-reanimated/blob/7e1a19ed8190763456e96939eec71c2528c1eed4/apple/REAModule.mm#L284

Fixes #5497 

Instead of using `[RCTBridge currentBridge]` we can just call
`self.bridge` and ensure the correct bridge is always used

## Test plan

Run FabricExample app on iOS

Co-authored-by: Krzysztof Piaskowy <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants