Skip to content

Commit d33f60e

Browse files
committed
feat: implement LayoutEventEmitter for onLayout events
1 parent 5d7f760 commit d33f60e

5 files changed

Lines changed: 76 additions & 24 deletions

File tree

packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <jsinspector-modern/tracing/PerformanceTracerSection.h>
1212
#include <react/debug/react_native_assert.h>
1313
#include <react/renderer/components/root/RootComponentDescriptor.h>
14-
#include <react/renderer/components/view/ViewShadowNode.h>
1514
#include <react/renderer/core/LayoutContext.h>
1615
#include <react/renderer/core/LayoutPrimitives.h>
1716
#include <react/renderer/mounting/ShadowTreeRevision.h>
@@ -463,8 +462,6 @@ CommitStatus ShadowTree::tryCommit(
463462
delegate_.shadowTreeDidCommit(
464463
*this, newRevision.rootShadowNode, affectedLayoutableNodes);
465464

466-
emitLayoutEvents(affectedLayoutableNodes);
467-
468465
if (isReactBranch) {
469466
scheduleReactRevisionPromotion();
470467
} else if (commitMode == CommitMode::Normal) {
@@ -630,25 +627,6 @@ void ShadowTree::commitEmptyTree() const {
630627
{/* default commit options */});
631628
}
632629

633-
void ShadowTree::emitLayoutEvents(
634-
std::vector<const LayoutableShadowNode*>& affectedLayoutableNodes) const {
635-
TraceSection s(
636-
"ShadowTree::emitLayoutEvents",
637-
"affectedLayoutableNodes",
638-
affectedLayoutableNodes.size());
639-
640-
for (const auto* layoutableNode : affectedLayoutableNodes) {
641-
if (auto viewProps =
642-
dynamic_cast<const ViewProps*>(layoutableNode->getProps().get())) {
643-
if (viewProps->onLayout) {
644-
static_cast<const BaseViewEventEmitter&>(
645-
*layoutableNode->getEventEmitter())
646-
.onLayout(layoutableNode->getLayoutMetrics());
647-
}
648-
}
649-
}
650-
}
651-
652630
void ShadowTree::notifyDelegatesOfUpdates() const {
653631
delegate_.shadowTreeDidFinishTransaction(mountingCoordinator_, true);
654632
}

packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,6 @@ class ShadowTree final {
161161

162162
void mount(ShadowTreeRevision revision, bool mountSynchronously) const;
163163

164-
void emitLayoutEvents(std::vector<const LayoutableShadowNode *> &affectedLayoutableNodes) const;
165-
166164
void scheduleReactRevisionPromotion() const;
167165

168166
const SurfaceId surfaceId_;

packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <react/renderer/mounting/MountingOverrideDelegate.h>
2121
#include <react/renderer/mounting/ShadowViewMutation.h>
2222
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
23+
#include <react/renderer/uimanager/LayoutEventEmitter.h>
2324
#include <react/renderer/uimanager/UIManager.h>
2425
#include <react/renderer/uimanager/UIManagerBinding.h>
2526
#include <mutex>
@@ -148,6 +149,11 @@ Scheduler::Scheduler(
148149

149150
delegate_ = delegate;
150151
commitHooks_ = schedulerToolbox.commitHooks;
152+
153+
// Layout events (`onLayout`) are emitted as a standalone consumer of the
154+
// `shadowTreeDidCommit` commit hook.
155+
commitHooks_.push_back(std::make_shared<LayoutEventEmitter>());
156+
151157
uiManager_ = uiManager;
152158

153159
for (auto& commitHook : commitHooks_) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "LayoutEventEmitter.h"
9+
10+
#include <cxxreact/TraceSection.h>
11+
#include <react/renderer/components/view/ViewShadowNode.h>
12+
#include <react/renderer/core/LayoutableShadowNode.h>
13+
14+
namespace facebook::react {
15+
16+
void LayoutEventEmitter::shadowTreeDidCommit(
17+
const ShadowTree& /*shadowTree*/,
18+
const RootShadowNode::Shared& /*rootShadowNode*/,
19+
const std::vector<const LayoutableShadowNode*>&
20+
affectedLayoutableNodes) noexcept {
21+
TraceSection s(
22+
"LayoutEventEmitter::shadowTreeDidCommit",
23+
"affectedLayoutableNodes",
24+
affectedLayoutableNodes.size());
25+
26+
for (const auto* layoutableNode : affectedLayoutableNodes) {
27+
if (auto viewProps =
28+
dynamic_cast<const ViewProps*>(layoutableNode->getProps().get())) {
29+
if (viewProps->onLayout) {
30+
static_cast<const BaseViewEventEmitter&>(
31+
*layoutableNode->getEventEmitter())
32+
.onLayout(layoutableNode->getLayoutMetrics());
33+
}
34+
}
35+
}
36+
}
37+
38+
} // namespace facebook::react
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <react/renderer/uimanager/UIManagerCommitHook.h>
11+
12+
namespace facebook::react {
13+
14+
/*
15+
* Emits layout events (`onLayout`) for the nodes whose layout changed in
16+
* each commit, using the `shadowTreeDidCommit` commit hook as the source of
17+
* layout changes (this logic used to be implemented directly in
18+
* `ShadowTree`).
19+
*/
20+
class LayoutEventEmitter final : public UIManagerCommitHook {
21+
public:
22+
void commitHookWasRegistered(const UIManager& uiManager) noexcept override {}
23+
void commitHookWasUnregistered(const UIManager& uiManager) noexcept override {}
24+
25+
void shadowTreeDidCommit(
26+
const ShadowTree& shadowTree,
27+
const RootShadowNode::Shared& rootShadowNode,
28+
const std::vector<const LayoutableShadowNode*>&
29+
affectedLayoutableNodes) noexcept override;
30+
};
31+
32+
} // namespace facebook::react

0 commit comments

Comments
 (0)