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

Expose UIManager from Scheduler #33545

Closed
wants to merge 4 commits into from
Closed

Conversation

ShikaSD
Copy link
Contributor

@ShikaSD ShikaSD commented Apr 1, 2022

Differential Revision: D35314058

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported labels Apr 1, 2022
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D35314058

@pull-bot
Copy link

pull-bot commented Apr 1, 2022

Fails
🚫

❔ This pull request needs a description.

Messages
📖

📋 Missing Changelog - Can you add a Changelog? To do so, add a "## Changelog" section to your PR description. A changelog entry has the following format: [CATEGORY] [TYPE] - Message.

CATEGORY may be:
  • General
  • iOS
  • Android
  • JavaScript
  • Internal (for changes that do not need to be called out in the release notes)

TYPE may be:

  • Added, for new features.
  • Changed, for changes in existing functionality.
  • Deprecated, for soon-to-be removed features.
  • Removed, for now removed features.
  • Fixed, for any bug fixes.
  • Security, in case of vulnerabilities.

MESSAGE may answer "what and why" on a feature level. Use this to briefly tell React Native users about notable changes.

Generated by 🚫 dangerJS against 2c6211c

@analysis-bot
Copy link

analysis-bot commented Apr 1, 2022

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: aeac6ab
Branch: main

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D35314058

ShikaSD pushed a commit to ShikaSD/react-native that referenced this pull request Apr 1, 2022
Summary: Pull Request resolved: facebook#33545

Differential Revision: D35314058

fbshipit-source-id: fe7a0feb37da3a691735c4315c64c7bc11c0a89d
Copy link
Contributor

@tomekzaw tomekzaw left a comment

Choose a reason for hiding this comment

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

Thanks for this PR! I've left a couple of comments regarding some details.

void removeListener(std::shared_ptr<EventListener const> listener);

private:
butter::shared_mutex lock_;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
butter::shared_mutex lock_;
butter::shared_mutex mutex_;

I would like to suggest renaming this field to mutex_ so it is consistent with naming in ComponentDescriptorRegistry, EventQueue, ShadowNodeFamily etc. and can be used as std::unique_lock<butter::shared_mutex> lock(mutex_);.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, must be a typo on my end :)

jsi::Runtime &runtime,
const EventTarget *eventTarget,
const std::string &type,
ReactEventPriority priority,
const ValueFactory &payloadFactory) {
if (!eventListeners_.callListeners(
eventTarget, type, priority, payloadFactory)) {
return;
Copy link
Contributor

Choose a reason for hiding this comment

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

I would like to suggest adding a short comment here for future visitors why we return here (because event listeners not only intercept events but can also prevent them from being passed to JS).

const EventTarget *eventTarget,
const std::string &type,
ReactEventPriority priority,
const ValueFactory &payloadFactory)>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to make sure, I would like to ask whether it is safe for event listener to invoke payloadFactory even if it will decide to pass the event to JS?

In such case payloadFactory may be called twice – first time in event listener and then one more time in UIManagerBinding::dispatchEvent. (In fact, each event listener may want to call payloadFactory arbitrary number of times.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess it depends on implementations of payload factory, e.g. if it decides to std::move some memory
From the implementations I saw in the core, it should be safe (usually we just create the value from struct ref or folly::dynamic)

Comment on lines 19 to 24
bool result = true;
for (auto const &listener : eventListeners_) {
result =
result && listener->operator()(eventTarget, type, priority, payloadFactory);
}
return result;
Copy link
Contributor

@tomekzaw tomekzaw Apr 2, 2022

Choose a reason for hiding this comment

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

If I understand it correctly, all event listeners intercept the event (in the order of registration) and each one of them individually returns a boolean value whether the event should be passed to JS or not. If any of the event listeners returns false, the event will not be passed to JS.

Also, even if some event listener returns false (meaning it could handle the event), the rest of event listeners will still be called, which seems fair. (This guarantee will prevent third-party library developers from racing for first place as there is no priority in voting).

I know it's a matter of preference, but personally it makes more sense to me to return true from event listener if it successfully managed to handle the event (so it doesn't need to be sent to JS) and false otherwise (meaning it couldn't handle the event so it probably needs to be passed to JS). So we would start from result = false, use || instead of && here and don't need ! in Scheduler.cpp.

Also, a comment on the semantics of the return value from event listener would be helpful for the other developers as well.

BTW I'm not sure but it looks like the syntax without ->operator(), i.e. listener(eventTarget, type, priority, payloadFactory) would also work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree on true/false comment, it will be more aligned with platform apis that way
I added the comment for the Event listener internally, but it probably didn't sync to GitHub.

Also about operator(), it is dereferencing shared pointer here, so just calling the function doesn't work, unfortunately
I could deref it into EventListener const & and call it that way, but not sure there is a point in doing so

Copy link
Contributor

Choose a reason for hiding this comment

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

You're right, I forgot that it's a shared pointer. In such case (*listener)(eventTarget, type, priority, payloadFactory) would do, but the original version with ->operator() is certainly better in terms of explicitness and readability.

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D35314058

ShikaSD pushed a commit to ShikaSD/react-native that referenced this pull request Apr 2, 2022
Summary:
Pull Request resolved: facebook#33545

Exposes `UIManager` instance for access from third-party modules.

Changelog: [Changed] Exposes `UIManager` instance for third-party access.

Differential Revision: D35314058

fbshipit-source-id: 90752fb57c662b78d5355b84f35221d7050e810a
@analysis-bot
Copy link

analysis-bot commented Apr 2, 2022

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 7,775,951 +3,036
android hermes armeabi-v7a 7,181,695 +2,737
android hermes x86 8,085,263 +3,330
android hermes x86_64 8,065,446 +3,611
android jsc arm64-v8a 9,649,955 +3,046
android jsc armeabi-v7a 8,424,085 +2,736
android jsc x86 9,599,458 +3,326
android jsc x86_64 10,197,044 +3,614

Base commit: aeac6ab
Branch: main

@tomekzaw
Copy link
Contributor

tomekzaw commented Apr 5, 2022

@ShikaSD We have just tried out this PR in Fabric version of react-native-reanimated. The good news is that we managed to implement and install a custom event listener on iOS (although we had some difficulties with obtaining a reference to RCTScheduler due to the fact that bridge.surfacePresenter was not initialized at the time we initialize Reanimated, but it looks like enabling requiresMainQueueSetup resolves this issue).

The bad news is that unfortunately I've overlooked the fact that the proposed event listeners are called on the JS thread, after the events are flushed from EventQueue. However, in Reanimated we need to intercept and handle events while still on the UI thread.

Can you please let us know if it would be possible to tweak this PR so we can handle the events still on the UI thread?

Andrei Shikov added 4 commits April 21, 2022 06:28
Summary:
Exposes event listener through iOS scheduler wrapper (`RCTScheduler`) and exposes scheduler itself through `RCTSurfacePresenter`.

Changelog: [Changed] Exposed `RCTScheduler` to allow setting event listeners.

Differential Revision: D35313398

fbshipit-source-id: 67d27969d7a64f021810292f84ddb52484c11b68
Summary:
Minimal set of changes to intercept events in external modules. Current intended use-case is for Reanimated to handle events for the Animated properties.

Changelog: [Added] Add listeners to allow intercepting events in C++ core.

Differential Revision: D35312534

fbshipit-source-id: 17ea760d016e68ee203b0106a113006f39fc159b
Differential Revision: D35313399

fbshipit-source-id: d53d9642ae351360b5825d280f4244ce701eebcd
Summary:
Pull Request resolved: facebook#33545

Exposes `UIManager` instance for access from third-party modules.

Changelog: [Changed] Exposes `UIManager` instance for third-party access.

Reviewed By: javache

Differential Revision: D35314058

fbshipit-source-id: 8640911c24a19c48fe6a4141cfec26c9427fb9c3
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D35314058

ShikaSD pushed a commit to ShikaSD/react-native that referenced this pull request Apr 21, 2022
Summary:
Pull Request resolved: facebook#33545

Exposes `UIManager` instance for access from third-party modules.

Changelog: [Changed] Exposes `UIManager` instance for third-party access.

Differential Revision: D35314058

fbshipit-source-id: b80c5520185f272f66788c3392eccecbb2eb1def
@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @cortinico in 54db5f2.

When will my fix make it into a release? | Upcoming Releases

@react-native-bot react-native-bot added the Merged This PR has been merged. label Apr 26, 2022
christophpurrer pushed a commit to christophpurrer/react-native-macos that referenced this pull request Nov 11, 2022
Summary:
Pull Request resolved: facebook#33545

Exposes `UIManager` instance for access from third-party modules.

Changelog: [Changed] Exposes `UIManager` instance for third-party access.

Reviewed By: javache

Differential Revision: D35314058

fbshipit-source-id: 1922c2afc37b105b153a82f45e5bac9c0b0cdfae
Saadnajmi pushed a commit to microsoft/react-native-macos that referenced this pull request Nov 12, 2022
Summary:
Pull Request resolved: facebook#33545

Exposes `UIManager` instance for access from third-party modules.

Changelog: [Changed] Exposes `UIManager` instance for third-party access.

Reviewed By: javache

Differential Revision: D35314058

fbshipit-source-id: 1922c2afc37b105b153a82f45e5bac9c0b0cdfae

Co-authored-by: Nicola Corti <ncor@fb.com>
shwanton pushed a commit to shwanton/react-native-macos that referenced this pull request Feb 13, 2023
Summary:
Pull Request resolved: facebook#33545

Exposes `UIManager` instance for access from third-party modules.

Changelog: [Changed] Exposes `UIManager` instance for third-party access.

Reviewed By: javache

Differential Revision: D35314058

fbshipit-source-id: 1922c2afc37b105b153a82f45e5bac9c0b0cdfae

Co-authored-by: Nicola Corti <ncor@fb.com>
shwanton pushed a commit to shwanton/react-native-macos that referenced this pull request Mar 10, 2023
Summary:
Pull Request resolved: facebook#33545

Exposes `UIManager` instance for access from third-party modules.

Changelog: [Changed] Exposes `UIManager` instance for third-party access.

Reviewed By: javache

Differential Revision: D35314058

fbshipit-source-id: 1922c2afc37b105b153a82f45e5bac9c0b0cdfae

Co-authored-by: Nicola Corti <ncor@fb.com>
shwanton pushed a commit to shwanton/react-native-macos that referenced this pull request Mar 10, 2023
Summary:
Pull Request resolved: facebook#33545

Exposes `UIManager` instance for access from third-party modules.

Changelog: [Changed] Exposes `UIManager` instance for third-party access.

Reviewed By: javache

Differential Revision: D35314058

fbshipit-source-id: 1922c2afc37b105b153a82f45e5bac9c0b0cdfae

Co-authored-by: Nicola Corti <ncor@fb.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. p: Facebook Partner: Facebook Partner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants