From 9dfb9ae23fb79652d704ba379ebe63052cf36bd1 Mon Sep 17 00:00:00 2001 From: hannomargelo Date: Sat, 30 Aug 2025 18:52:56 +0200 Subject: [PATCH] discord: add more shadow tree tree methods --- .../ReactCommon/SampleTurboModuleSpec.cpp | 2 +- .../react/renderer/mounting/ShadowTree.cpp | 14 ++++++++++++++ .../react/renderer/mounting/ShadowTreeDelegate.h | 5 +++++ .../mounting/tests/StateReconciliationTest.cpp | 3 +++ .../react/renderer/uimanager/UIManager.cpp | 16 ++++++++++++++++ .../react/renderer/uimanager/UIManager.h | 3 +++ .../renderer/uimanager/UIManagerCommitHook.h | 5 +++++ 7 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp index 90e1b2c453af5c..45e75c42546452 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp @@ -359,7 +359,7 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI( std::make_shared>(); eventEmitterMap_["onSubmit"] = std::make_shared>(); - configureEventEmitterCallback(); +// configureEventEmitterCallback(); } std::shared_ptr SampleTurboModuleSpec_ModuleProvider( diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp index e77fe3e906f0af..79032fb9b98138 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp @@ -21,6 +21,16 @@ #include "ShadowTreeDelegate.h" +// Discord - Wrap with ScopeGuard for a function to run on the end of the scope: +#include +struct ScopeGuard { + std::function fn; + ~ScopeGuard() { fn(); } +}; +#define CONCAT_IMPL(x, y) x##y +#define CONCAT(x, y) CONCAT_IMPL(x, y) +#define defer(code) ScopeGuard CONCAT(defer, LINE)([&](){code;}) + namespace facebook::react { using CommitStatus = ShadowTree::CommitStatus; @@ -297,6 +307,7 @@ CommitStatus ShadowTree::tryCommit( *this, oldRootShadowNode, newRootShadowNode, commitOptions); if (!newRootShadowNode) { + delegate_.shadowTreeCommitFinalized(commitOptions); return CommitStatus::Cancelled; } @@ -313,6 +324,7 @@ CommitStatus ShadowTree::tryCommit( { // Updating `currentRevision_` in unique manner if it hasn't changed. std::unique_lock lock(commitMutex_); + defer(delegate_.shadowTreeCommitFinalized(commitOptions)); if (ReactNativeFeatureFlags:: enableGranularShadowTreeStateReconciliation()) { @@ -331,6 +343,8 @@ CommitStatus ShadowTree::tryCommit( auto newRevisionNumber = currentRevision_.number + 1; + delegate_.shadowTreeCommitSucceeded(commitOptions); + { std::scoped_lock dispatchLock(EventEmitter::DispatchMutex()); updateMountedFlag( diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h index 14402722045ec0..ed73511d4a8d6d 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h +++ b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h @@ -38,6 +38,11 @@ class ShadowTreeDelegate { std::shared_ptr mountingCoordinator, bool mountSynchronously) const = 0; + // Called after a commit is known to succeed, however, still under the commit lock + virtual void shadowTreeCommitSucceeded(const ShadowTreeCommitOptions& commitOptions) const = 0; + // Will be called in each case once we are done with the current commit attempt + virtual void shadowTreeCommitFinalized(const ShadowTreeCommitOptions& commitOptions) const = 0; + virtual ~ShadowTreeDelegate() noexcept = default; }; diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp index 5dc71f7bf03370..9046eb162561bf 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp @@ -37,6 +37,9 @@ class DummyShadowTreeDelegate : public ShadowTreeDelegate { void shadowTreeDidFinishTransaction( std::shared_ptr mountingCoordinator, bool mountSynchronously) const override {}; + + void shadowTreeCommitSucceeded(const ShadowTreeCommitOptions& commitOptions) const override {}; + void shadowTreeCommitFinalized(const ShadowTreeCommitOptions& commitOptions) const override {}; }; namespace { diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp index f46da424db4b87..5e5949b149cae9 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp @@ -633,6 +633,22 @@ RootShadowNode::Unshared UIManager::shadowTreeWillCommit( return resultRootShadowNode; } +void UIManager::shadowTreeCommitSucceeded(const ShadowTreeCommitOptions& commitOptions) const { + std::shared_lock lock(commitHookMutex_); + + for (auto* commitHook : commitHooks_) { + commitHook->shadowTreeCommitSucceeded(commitOptions); + } +} + +void UIManager::shadowTreeCommitFinalized(const ShadowTreeCommitOptions& commitOptions) const { + std::shared_lock lock(commitHookMutex_); + + for (auto* commitHook : commitHooks_) { + commitHook->shadowTreeCommitFinalized(commitOptions); + } +} + void UIManager::shadowTreeDidFinishTransaction( std::shared_ptr mountingCoordinator, bool mountSynchronously) const { diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h index d876677c3f1fb5..887a998760e478 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h @@ -130,6 +130,9 @@ class UIManager final : public ShadowTreeDelegate { const RootShadowNode::Unshared& newRootShadowNode, const ShadowTree::CommitOptions& commitOptions) const override; + void shadowTreeCommitSucceeded(const ShadowTreeCommitOptions& commitOptions) const override; + void shadowTreeCommitFinalized(const ShadowTreeCommitOptions& commitOptions) const override; + std::shared_ptr createNode( Tag tag, const std::string& componentName, diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerCommitHook.h b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerCommitHook.h index 2e15c6ca89e595..e01238b853eb70 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerCommitHook.h +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerCommitHook.h @@ -54,6 +54,11 @@ class UIManagerCommitHook { return newRootShadowNode; } + // Discord - Called after a commit is known to succeed, however, still under the commit lock + virtual void shadowTreeCommitSucceeded(const ShadowTreeCommitOptions& commitOptions) = 0; + // Discord - Will be called in each case once we are done with the current commit attempt + virtual void shadowTreeCommitFinalized(const ShadowTreeCommitOptions& commitOptions) = 0; + virtual ~UIManagerCommitHook() noexcept = default; };