mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fabric: Introducing UIManagerCommitHook, unified way to alter commits
Summary: The new UIManagerCommitHook can be used to implement commit-atering features without modifying the core. E.g. State Reconciation seems can be implemented as a coomit hook but first we will use it for a new feature called Timeline (see the coming diffs). Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D25221312 fbshipit-source-id: dbe41b475bc8b36e1780d81447ab43b32758bdff
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d2ae775bf7
commit
fb4e06b1a5
@@ -10,6 +10,7 @@
|
||||
#include <react/renderer/core/ShadowNodeFragment.h>
|
||||
#include <react/renderer/debug/SystraceSection.h>
|
||||
#include <react/renderer/graphics/Geometry.h>
|
||||
#include <react/renderer/uimanager/UIManagerCommitHook.h>
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
@@ -330,13 +331,40 @@ ShadowTreeRegistry const &UIManager::getShadowTreeRegistry() const {
|
||||
return shadowTreeRegistry_;
|
||||
}
|
||||
|
||||
void UIManager::registerCommitHook(
|
||||
UIManagerCommitHook const &commitHook) const {
|
||||
std::unique_lock<better::shared_mutex> lock(commitHookMutex_);
|
||||
assert(
|
||||
std::find(commitHooks_.begin(), commitHooks_.end(), &commitHook) ==
|
||||
commitHooks_.end());
|
||||
commitHook.commitHookWasRegistered(*this);
|
||||
commitHooks_.push_back(&commitHook);
|
||||
}
|
||||
|
||||
void UIManager::unregisterCommitHook(
|
||||
UIManagerCommitHook const &commitHook) const {
|
||||
std::unique_lock<better::shared_mutex> lock(commitHookMutex_);
|
||||
auto iterator =
|
||||
std::find(commitHooks_.begin(), commitHooks_.end(), &commitHook);
|
||||
assert(iterator != commitHooks_.end());
|
||||
commitHooks_.erase(iterator);
|
||||
commitHook.commitHookWasUnregistered(*this);
|
||||
}
|
||||
|
||||
#pragma mark - ShadowTreeDelegate
|
||||
|
||||
RootShadowNode::Unshared UIManager::shadowTreeWillCommit(
|
||||
ShadowTree const &shadowTree,
|
||||
RootShadowNode::Shared const &oldRootShadowNode,
|
||||
RootShadowNode::Unshared const &newRootShadowNode) const {
|
||||
std::shared_lock<better::shared_mutex> lock(commitHookMutex_);
|
||||
|
||||
auto resultRootShadowNode = newRootShadowNode;
|
||||
for (auto const *commitHook : commitHooks_) {
|
||||
resultRootShadowNode = commitHook->shadowTreeWillCommit(
|
||||
shadowTree, oldRootShadowNode, resultRootShadowNode);
|
||||
}
|
||||
|
||||
return resultRootShadowNode;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class UIManagerBinding;
|
||||
class UIManagerCommitHook;
|
||||
|
||||
class UIManager final : public ShadowTreeDelegate {
|
||||
public:
|
||||
@@ -67,6 +68,12 @@ class UIManager final : public ShadowTreeDelegate {
|
||||
std::function<void(UIManagerBinding const &uiManagerBinding)> callback)
|
||||
const;
|
||||
|
||||
/*
|
||||
* Registers and unregisters a commit hook.
|
||||
*/
|
||||
void registerCommitHook(UIManagerCommitHook const &commitHook) const;
|
||||
void unregisterCommitHook(UIManagerCommitHook const &commitHook) const;
|
||||
|
||||
#pragma mark - ShadowTreeDelegate
|
||||
|
||||
void shadowTreeDidFinishTransaction(
|
||||
@@ -167,6 +174,9 @@ class UIManager final : public ShadowTreeDelegate {
|
||||
// determine whether a commit should be cancelled. Only to be used
|
||||
// inside UIManagerBinding.
|
||||
std::atomic_uint_fast8_t completeRootEventCounter_{0};
|
||||
|
||||
mutable better::shared_mutex commitHookMutex_;
|
||||
mutable std::vector<UIManagerCommitHook const *> commitHooks_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/renderer/components/root/RootShadowNode.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class ShadowTree;
|
||||
class UIManager;
|
||||
|
||||
/*
|
||||
* Implementing a commit hook allows to observe and alter Shadow Tree commits.
|
||||
*/
|
||||
class UIManagerCommitHook {
|
||||
public:
|
||||
/*
|
||||
* Called right after the commit hook is registered or unregistered.
|
||||
*/
|
||||
virtual void commitHookWasRegistered(UIManager const &uiManager) const
|
||||
noexcept = 0;
|
||||
virtual void commitHookWasUnregistered(UIManager const &uiManager) const
|
||||
noexcept = 0;
|
||||
|
||||
/*
|
||||
* Called right before a `ShadowTree` commits a new tree.
|
||||
* The semantic of the method corresponds to a method of the same name
|
||||
* from `ShadowTreeDelegate`.
|
||||
*/
|
||||
virtual RootShadowNode::Unshared shadowTreeWillCommit(
|
||||
ShadowTree const &shadowTree,
|
||||
RootShadowNode::Shared const &oldRootShadowNode,
|
||||
RootShadowNode::Unshared const &newRootShadowNode) const noexcept = 0;
|
||||
|
||||
virtual ~UIManagerCommitHook() noexcept = default;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
Reference in New Issue
Block a user