diff --git a/React/Fabric/Mounting/RCTMountingManager.h b/React/Fabric/Mounting/RCTMountingManager.h index 8233bbb7d99..9dc1538c128 100644 --- a/React/Fabric/Mounting/RCTMountingManager.h +++ b/React/Fabric/Mounting/RCTMountingManager.h @@ -11,7 +11,7 @@ #import #import #import -#import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -30,7 +30,7 @@ NS_ASSUME_NONNULL_BEGIN * Schedule a mounting transaction to be performed on the main thread. * Can be called from any thread. */ -- (void)scheduleTransaction:(facebook::react::MountingTransaction &&)mountingTransaction; +- (void)scheduleTransaction:(facebook::react::MountingCoordinator::Shared const &)mountingCoordinator; /** * Suggests preliminary creation of a component view of given type. diff --git a/React/Fabric/Mounting/RCTMountingManager.mm b/React/Fabric/Mounting/RCTMountingManager.mm index b34ba11773d..5b933ae71bf 100644 --- a/React/Fabric/Mounting/RCTMountingManager.mm +++ b/React/Fabric/Mounting/RCTMountingManager.mm @@ -15,7 +15,6 @@ #import #import #import -#import #import "RCTComponentViewProtocol.h" #import "RCTComponentViewRegistry.h" @@ -204,9 +203,7 @@ static void RNPerformMountInstructions(ShadowViewMutationList const &mutations, } } -@implementation RCTMountingManager { - better::map syncronizers_; -} +@implementation RCTMountingManager - (instancetype)init { @@ -217,49 +214,39 @@ static void RNPerformMountInstructions(ShadowViewMutationList const &mutations, return self; } -- (void)scheduleTransaction:(MountingTransaction &&)mountingTransaction; +- (void)scheduleTransaction:(MountingCoordinator::Shared const &)mountingCoordinator { if (RCTIsMainQueue()) { // Already on the proper thread, so: // * No need to do a thread jump; // * No need to do expensive copy of all mutations; // * No need to allocate a block. - [self mountMutations:std::move(mountingTransaction)]; + [self mountMutations:mountingCoordinator]; return; } - // We need a non-reference for `mountingTransaction` to allow copy semantic. - auto sharedMountingTransaction = std::make_shared(std::move(mountingTransaction)); - + auto mountingCoordinatorCopy = mountingCoordinator; RCTExecuteOnMainQueue(^{ RCTAssertMainQueue(); - [self mountMutations:std::move(*sharedMountingTransaction)]; + [self mountMutations:mountingCoordinatorCopy]; }); } -- (void)mountMutations:(MountingTransaction &&)mountingTransaction +- (void)mountMutations:(MountingCoordinator::Shared const &)mountingCoordinator { SystraceSection s("-[RCTMountingManager mountMutations:]"); - RCTAssertMainQueue(); - - auto &syncronizer = syncronizers_[mountingTransaction.getSurfaceId()]; - - syncronizer.push(std::move(mountingTransaction)); - - while (true) { - auto mountingTransactionOptional = syncronizer.pull(); - if (!mountingTransactionOptional.has_value()) { - break; - } - - auto transaction = std::move(*mountingTransactionOptional); - auto surfaceId = transaction.getSurfaceId(); - - [self.delegate mountingManager:self willMountComponentsWithRootTag:surfaceId]; - RNPerformMountInstructions(transaction.getMutations(), self.componentViewRegistry); - [self.delegate mountingManager:self didMountComponentsWithRootTag:surfaceId]; + auto transaction = mountingCoordinator->pullTransaction(); + if (!transaction.has_value()) { + return; } + + auto surfaceId = transaction->getSurfaceId(); + + RCTAssertMainQueue(); + [self.delegate mountingManager:self willMountComponentsWithRootTag:surfaceId]; + RNPerformMountInstructions(transaction->getMutations(), self.componentViewRegistry); + [self.delegate mountingManager:self didMountComponentsWithRootTag:surfaceId]; } - (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag diff --git a/React/Fabric/RCTScheduler.h b/React/Fabric/RCTScheduler.h index 04d412a9c23..b67244fab1b 100644 --- a/React/Fabric/RCTScheduler.h +++ b/React/Fabric/RCTScheduler.h @@ -12,8 +12,7 @@ #import #import #import -#import -#import +#import #import #import @@ -26,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN */ @protocol RCTSchedulerDelegate -- (void)schedulerDidFinishTransaction:(facebook::react::MountingTransaction &&)mountingTransaction; +- (void)schedulerDidFinishTransaction:(facebook::react::MountingCoordinator::Shared const &)mountingCoordinator; - (void)schedulerOptimisticallyCreateComponentViewWithComponentHandle:(facebook::react::ComponentHandle)componentHandle; diff --git a/React/Fabric/RCTScheduler.mm b/React/Fabric/RCTScheduler.mm index 53fd67fc55c..185e012fed6 100644 --- a/React/Fabric/RCTScheduler.mm +++ b/React/Fabric/RCTScheduler.mm @@ -22,10 +22,10 @@ class SchedulerDelegateProxy : public SchedulerDelegate { public: SchedulerDelegateProxy(void *scheduler) : scheduler_(scheduler) {} - void schedulerDidFinishTransaction(MountingTransaction &&mountingTransaction) override + void schedulerDidFinishTransaction(MountingCoordinator::Shared const &mountingCoordinator) override { RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_; - [scheduler.delegate schedulerDidFinishTransaction:std::move(mountingTransaction)]; + [scheduler.delegate schedulerDidFinishTransaction:mountingCoordinator]; } void schedulerDidRequestPreliminaryViewAllocation(SurfaceId surfaceId, const ShadowView &shadowView) override diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index 3bc666b092c..bb2daa8ad6e 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -311,13 +311,13 @@ using namespace facebook::react; #pragma mark - RCTSchedulerDelegate -- (void)schedulerDidFinishTransaction:(facebook::react::MountingTransaction &&)mountingTransaction +- (void)schedulerDidFinishTransaction:(facebook::react::MountingCoordinator::Shared const &)mountingCoordinator { - RCTFabricSurface *surface = [_surfaceRegistry surfaceForRootTag:mountingTransaction.getSurfaceId()]; + RCTFabricSurface *surface = [_surfaceRegistry surfaceForRootTag:mountingCoordinator->getSurfaceId()]; [surface _setStage:RCTSurfaceStagePrepared]; - [_mountingManager scheduleTransaction:std::move(mountingTransaction)]; + [_mountingManager scheduleTransaction:mountingCoordinator]; } - (void)schedulerOptimisticallyCreateComponentViewWithComponentHandle:(ComponentHandle)componentHandle diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp index afdda6806a4..5f761938751 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp @@ -353,12 +353,18 @@ local_ref createCreateMountItem( } void Binding::schedulerDidFinishTransaction( - MountingTransaction &&mountingTransaction) { + MountingCoordinator::Shared const &mountingCoordinator) { SystraceSection s("FabricUIManager::schedulerDidFinishTransaction"); - auto telemetry = mountingTransaction.getTelemetry(); - auto mutations = mountingTransaction.getMutations(); - auto surfaceId = mountingTransaction.getSurfaceId(); + auto mountingTransaction = mountingCoordinator->pullTransaction(); + + if (!mountingTransaction.has_value()) { + return; + } + + auto telemetry = mountingTransaction->getTelemetry(); + auto surfaceId = mountingTransaction->getSurfaceId(); + auto &mutations = mountingTransaction->getMutations(); std::vector> queue; // Upper bound estimation of mount items to be delivered to Java side. diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.h index 535245c1baa..e61b5c1ceba 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.h @@ -57,7 +57,7 @@ class Binding : public jni::HybridClass, public SchedulerDelegate { void stopSurface(jint surfaceId); void schedulerDidFinishTransaction( - MountingTransaction &&mountingTransaction); + MountingCoordinator::Shared const &mountingCoordinator); void schedulerDidRequestPreliminaryViewAllocation( const SurfaceId surfaceId, diff --git a/ReactCommon/fabric/mounting/MountingCoordinator.cpp b/ReactCommon/fabric/mounting/MountingCoordinator.cpp new file mode 100644 index 00000000000..e36eddcbb88 --- /dev/null +++ b/ReactCommon/fabric/mounting/MountingCoordinator.cpp @@ -0,0 +1,88 @@ +/** + * 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. + */ + +#include "MountingCoordinator.h" + +#ifdef RN_SHADOW_TREE_INTROSPECTION +#include +#endif + +#include +#include + +namespace facebook { +namespace react { + +MountingCoordinator::MountingCoordinator(ShadowTreeRevision baseRevision) + : surfaceId_(baseRevision.getRootShadowNode().getSurfaceId()), + baseRevision_(baseRevision) { +#ifdef RN_SHADOW_TREE_INTROSPECTION + stubViewTree_ = stubViewTreeFromShadowNode(baseRevision_.getRootShadowNode()); +#endif +} + +SurfaceId MountingCoordinator::getSurfaceId() const { + return surfaceId_; +} + +void MountingCoordinator::push(ShadowTreeRevision &&revision) const { + std::lock_guard lock(mutex_); + + assert(revision.getNumber() > baseRevision_.getNumber()); + assert( + !lastRevision_.has_value() || + revision.getNumber() != lastRevision_->getNumber()); + + if (!lastRevision_.has_value() || + lastRevision_->getNumber() < revision.getNumber()) { + lastRevision_ = std::move(revision); + } +} + +better::optional MountingCoordinator::pullTransaction() + const { + std::lock_guard lock(mutex_); + + if (!lastRevision_.has_value()) { + return {}; + } + + number_++; + + auto mutations = calculateShadowViewMutations( + baseRevision_.getRootShadowNode(), lastRevision_->getRootShadowNode()); + +#ifdef RN_SHADOW_TREE_INTROSPECTION + stubViewTree_.mutate(mutations); + auto stubViewTree = + stubViewTreeFromShadowNode(lastRevision_->getRootShadowNode()); + if (stubViewTree_ != stubViewTree) { + LOG(ERROR) << "Old tree:" + << "\n" + << baseRevision_.getRootShadowNode().getDebugDescription() + << "\n"; + LOG(ERROR) << "New tree:" + << "\n" + << lastRevision_->getRootShadowNode().getDebugDescription() + << "\n"; + LOG(ERROR) << "Mutations:" + << "\n" + << getDebugDescription(mutations); + assert(false); + } +#endif + + auto telemetry = lastRevision_->getTelemetry(); + baseRevision_ = std::move(*lastRevision_); + lastRevision_.reset(); + + return MountingTransaction{ + surfaceId_, number_, std::move(mutations), telemetry}; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/mounting/MountingCoordinator.h b/ReactCommon/fabric/mounting/MountingCoordinator.h new file mode 100644 index 00000000000..efc446c8310 --- /dev/null +++ b/ReactCommon/fabric/mounting/MountingCoordinator.h @@ -0,0 +1,81 @@ +/** + * 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 + +#include +#include + +#ifndef NDEBUG +#define RN_SHADOW_TREE_INTROSPECTION +#endif + +#ifdef RN_SHADOW_TREE_INTROSPECTION +#include +#endif + +namespace facebook { +namespace react { + +/* + * Stores inside all non-mounted yet revisions of a shadow tree and coordinates + * mounting. The object stores the most recent mounted revision and the most + * recent committed one. Then when a new mounting transaction is requested the + * object generates mutation instructions and returns it as a + * `MountingTransaction`. + */ +class MountingCoordinator final { + public: + using Shared = std::shared_ptr; + + /* + * The constructor is ment to be used only inside `ShadowTree`, and it's + * `public` only to enable using with `std::make_shared<>`. + */ + MountingCoordinator(ShadowTreeRevision baseRevision); + + /* + * Returns the id of the surface that the coordinator belongs to. + */ + SurfaceId getSurfaceId() const; + + /* + * Computes a consequent mounting transaction and returns it. + * The returning transaction can accumulate multiple recent revisions of a + * shadow tree. Returns empty optional if there no new shadow tree revision to + * mount. + * The method is thread-safe and can be called from any thread. + * However, a consumer should always call it on the same thread (e.g. on the + * main thread) or ensure sequentiality of mount transaction separately. + */ + better::optional pullTransaction() const; + + private: + friend class ShadowTree; + + /* + * Methods from this section are meant to be used by `ShadowTree` only. + */ + void push(ShadowTreeRevision &&revision) const; + + private: + SurfaceId const surfaceId_; + + mutable std::mutex mutex_; + mutable ShadowTreeRevision baseRevision_; + mutable better::optional lastRevision_{}; + mutable MountingTransaction::Number number_{0}; + +#ifdef RN_SHADOW_TREE_INTROSPECTION + mutable StubViewTree stubViewTree_; // Protected by `mutex_`. +#endif +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/mounting/MountingTransaction.cpp b/ReactCommon/fabric/mounting/MountingTransaction.cpp index 09992b9f893..846ea39f067 100644 --- a/ReactCommon/fabric/mounting/MountingTransaction.cpp +++ b/ReactCommon/fabric/mounting/MountingTransaction.cpp @@ -10,15 +10,15 @@ namespace facebook { namespace react { -using Revision = MountingTransaction::Revision; +using Number = MountingTransaction::Number; MountingTransaction::MountingTransaction( SurfaceId surfaceId, - Revision revision, + Number number, ShadowViewMutationList &&mutations, MountingTelemetry telemetry) : surfaceId_(surfaceId), - revision_(revision), + number_(number), mutations_(std::move(mutations)), telemetry_(std::move(telemetry)) {} @@ -38,8 +38,8 @@ SurfaceId MountingTransaction::getSurfaceId() const { return surfaceId_; } -Revision MountingTransaction::getRevision() const { - return revision_; +Number MountingTransaction::getNumber() const { + return number_; } } // namespace react diff --git a/ReactCommon/fabric/mounting/MountingTransaction.h b/ReactCommon/fabric/mounting/MountingTransaction.h index 759b1cf75ce..2e146841025 100644 --- a/ReactCommon/fabric/mounting/MountingTransaction.h +++ b/ReactCommon/fabric/mounting/MountingTransaction.h @@ -14,19 +14,19 @@ namespace facebook { namespace react { /* - * Encapsulates all artifacts of `ShadowTree` commit, particularly list of - * mutations and meta-data. - * Movable and copyable, but moving is strongly preferred. - * A moved-from object of this type has unspecified value and accessing that is - * UB. + * Encapsulates all artifacts of `ShadowTree` commit (or a series of them), + * particularly list of mutations and meta-data associated with the commit. + * Movable and copyable, but moving is strongly encouraged. + * Beware: A moved-from object of this type has unspecified value and accessing + * that is UB. */ class MountingTransaction final { public: /* - * Revision grows continuously starting from `1`. Value `0` represents the - * state before the very first transaction happens. + * A Number (or revision) grows continuously starting from `1`. Value `0` + * represents the state before the very first transaction happens. */ - using Revision = int64_t; + using Number = int64_t; /* * Copying a list of `ShadowViewMutation` is expensive, so the constructor @@ -34,7 +34,7 @@ class MountingTransaction final { */ MountingTransaction( SurfaceId surfaceId, - Revision revision, + Number number, ShadowViewMutationList &&mutations, MountingTelemetry telemetry); @@ -72,13 +72,13 @@ class MountingTransaction final { SurfaceId getSurfaceId() const; /* - * Returns the revision of the ShadowTree that this transaction represents. + * Returns a sequential number of the particular transaction. */ - Revision getRevision() const; + Number getNumber() const; private: SurfaceId surfaceId_; - Revision revision_; + Number number_; ShadowViewMutationList mutations_; MountingTelemetry telemetry_; }; diff --git a/ReactCommon/fabric/mounting/MountingTransactionSynchronizer.cpp b/ReactCommon/fabric/mounting/MountingTransactionSynchronizer.cpp deleted file mode 100644 index d83a0c13d40..00000000000 --- a/ReactCommon/fabric/mounting/MountingTransactionSynchronizer.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * 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. - */ - -#include "MountingTransactionSynchronizer.h" - -namespace facebook { -namespace react { - -void MountingTransactionSynchronizer::push(MountingTransaction &&transaction) { - assert(transaction.getRevision() >= 1 && "Invalid transaction revision."); - - if (transaction.getRevision() == 1 && revision_ > 0) { - // Special case: - // Seems we have a completely new flow of mutations probably caused by the - // hot-reload process. At this point, there is no way to guarantee anything, - // so let's just start over. - queue_.clear(); - revision_ = 0; - } - - auto it = queue_.begin(); - - while (it != queue_.end()) { - assert( - it->getRevision() != transaction.getRevision() && - "Attempt to re-insert transaction with same revision."); - - if (it->getRevision() > transaction.getRevision()) { - queue_.insert(it, std::move(transaction)); - return; - } - - it++; - } - - queue_.push_back(std::move(transaction)); -} - -better::optional MountingTransactionSynchronizer::pull() { - if (queue_.size() == 0) { - return {}; - } - - if (queue_.front().getRevision() != revision_ + 1) { - return {}; - } - - revision_++; - - auto transaction = std::move(queue_.front()); - queue_.pop_front(); - - return {std::move(transaction)}; -} - -} // namespace react -} // namespace facebook diff --git a/ReactCommon/fabric/mounting/MountingTransactionSynchronizer.h b/ReactCommon/fabric/mounting/MountingTransactionSynchronizer.h deleted file mode 100644 index 5e4989a1ee5..00000000000 --- a/ReactCommon/fabric/mounting/MountingTransactionSynchronizer.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * 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 - -#include - -namespace facebook { -namespace react { - -/* - * ShadowTree commits happen concurrently with limited synchronization that only - * ensures the correctness of the commit from ShadowTree perspective. At the - * same time artifacts of the commit () needs to be delivered (also - * concurrently) to the proper thread and executed in order (not-concurrently). - * To achieve this we need some synchronization mechanism on the receiving - * (mounting) side. This class implements this process. This class is *not* - * thread-safe (and must not be). - */ -class MountingTransactionSynchronizer final { - public: - /* - * Pushes (adds) a new MountingTransaction to the internal queue. - */ - void push(MountingTransaction &&transaction); - - /* - * Pulls (returns and removes) a MountingTransaction from the internal queue - * if it has something ready to be pulled. Return an empty optional otherwise. - */ - better::optional pull(); - - private: - MountingTransaction::Revision revision_{0}; - std::deque queue_{}; -}; - -} // namespace react -} // namespace facebook diff --git a/ReactCommon/fabric/mounting/ShadowTree.cpp b/ReactCommon/fabric/mounting/ShadowTree.cpp index 09ebbacbaff..af08afd792b 100644 --- a/ReactCommon/fabric/mounting/ShadowTree.cpp +++ b/ReactCommon/fabric/mounting/ShadowTree.cpp @@ -5,15 +5,13 @@ #include "ShadowTree.h" -#include - #include #include #include #include #include -#include #include +#include #include #include "ShadowTreeDelegate.h" @@ -100,9 +98,8 @@ ShadowTree::ShadowTree( /* .eventEmitter = */ noopEventEmitter, })); -#ifdef RN_SHADOW_TREE_INTROSPECTION - stubViewTree_ = stubViewTreeFromShadowNode(*rootShadowNode_); -#endif + mountingCoordinator_ = std::make_shared( + ShadowTreeRevision{rootShadowNode_, 0, {}}); } ShadowTree::~ShadowTree() { @@ -171,9 +168,7 @@ bool ShadowTree::tryCommit(ShadowTreeCommitTransaction transaction) const { newRootShadowNode->sealRecursive(); - int revision; - auto mutations = - calculateShadowViewMutations(*oldRootShadowNode, *newRootShadowNode); + auto revisionNumber = ShadowTreeRevision::Number{}; { // Updating `rootShadowNode_` in unique manner if it hasn't changed. @@ -192,34 +187,19 @@ bool ShadowTree::tryCommit(ShadowTreeCommitTransaction transaction) const { oldRootShadowNode->getChildren(), newRootShadowNode->getChildren()); } - revision = revision_; - revision_++; - -#ifdef RN_SHADOW_TREE_INTROSPECTION - stubViewTree_.mutate(mutations); - auto stubViewTree = stubViewTreeFromShadowNode(*rootShadowNode_); - if (stubViewTree_ != stubViewTree) { - LOG(ERROR) << "Old tree:" - << "\n" - << oldRootShadowNode->getDebugDescription() << "\n"; - LOG(ERROR) << "New tree:" - << "\n" - << newRootShadowNode->getDebugDescription() << "\n"; - LOG(ERROR) << "Mutations:" - << "\n" - << getDebugDescription(mutations); - assert(false); - } -#endif + revisionNumber_++; + revisionNumber = revisionNumber_; } emitLayoutEvents(affectedLayoutableNodes); telemetry.didCommit(); + mountingCoordinator_->push( + ShadowTreeRevision{newRootShadowNode, revisionNumber, telemetry}); + if (delegate_) { - delegate_->shadowTreeDidCommit( - *this, {surfaceId_, revision, std::move(mutations), telemetry}); + delegate_->shadowTreeDidCommit(*this, mountingCoordinator_); } return true; diff --git a/ReactCommon/fabric/mounting/ShadowTree.h b/ReactCommon/fabric/mounting/ShadowTree.h index 62e7db03b22..4fedcf7449f 100644 --- a/ReactCommon/fabric/mounting/ShadowTree.h +++ b/ReactCommon/fabric/mounting/ShadowTree.h @@ -5,9 +5,6 @@ #pragma once -#ifndef NDEBUG -#define RN_SHADOW_TREE_INTROSPECTION -#endif #include #include @@ -17,12 +14,9 @@ #include #include #include +#include #include -#include - -#ifdef RN_SHADOW_TREE_INTROSPECTION -#include -#endif +#include namespace facebook { namespace react { @@ -83,15 +77,13 @@ class ShadowTree final { void emitLayoutEvents( std::vector &affectedLayoutableNodes) const; - const SurfaceId surfaceId_; + SurfaceId const surfaceId_; mutable better::shared_mutex commitMutex_; mutable SharedRootShadowNode rootShadowNode_; // Protected by `commitMutex_`. - mutable int revision_{1}; // Protected by `commitMutex_`. + mutable ShadowTreeRevision::Number revisionNumber_{ + 0}; // Protected by `commitMutex_`. ShadowTreeDelegate const *delegate_; - -#ifdef RN_SHADOW_TREE_INTROSPECTION - mutable StubViewTree stubViewTree_; // Protected by `commitMutex_`. -#endif + MountingCoordinator::Shared mountingCoordinator_; }; } // namespace react diff --git a/ReactCommon/fabric/mounting/ShadowTreeDelegate.h b/ReactCommon/fabric/mounting/ShadowTreeDelegate.h index 0e17cd23491..cda72e2f1ee 100644 --- a/ReactCommon/fabric/mounting/ShadowTreeDelegate.h +++ b/ReactCommon/fabric/mounting/ShadowTreeDelegate.h @@ -5,7 +5,7 @@ #pragma once -#include +#include namespace facebook { namespace react { @@ -21,8 +21,8 @@ class ShadowTreeDelegate { * Called right after Shadow Tree commit a new state of the the tree. */ virtual void shadowTreeDidCommit( - const ShadowTree &shadowTree, - MountingTransaction &&transaction) const = 0; + ShadowTree const &shadowTree, + MountingCoordinator::Shared const &mountingCoordinator) const = 0; virtual ~ShadowTreeDelegate() noexcept = default; }; diff --git a/ReactCommon/fabric/mounting/ShadowTreeRevision.cpp b/ReactCommon/fabric/mounting/ShadowTreeRevision.cpp new file mode 100644 index 00000000000..2f5730ce6bf --- /dev/null +++ b/ReactCommon/fabric/mounting/ShadowTreeRevision.cpp @@ -0,0 +1,34 @@ +/** + * 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. + */ + +#include "ShadowTreeRevision.h" + +namespace facebook { +namespace react { + +using Number = ShadowTreeRevision::Number; + +ShadowTreeRevision::ShadowTreeRevision( + ShadowNode::Shared const &rootShadowNode, + Number number, + MountingTelemetry telemetry) + : rootShadowNode_(rootShadowNode), number_(number), telemetry_(telemetry) {} + +MountingTelemetry const &ShadowTreeRevision::getTelemetry() const { + return telemetry_; +} + +ShadowNode const &ShadowTreeRevision::getRootShadowNode() { + return *rootShadowNode_; +} + +Number ShadowTreeRevision::getNumber() const { + return number_; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/mounting/ShadowTreeRevision.h b/ReactCommon/fabric/mounting/ShadowTreeRevision.h new file mode 100644 index 00000000000..71ed0395b9e --- /dev/null +++ b/ReactCommon/fabric/mounting/ShadowTreeRevision.h @@ -0,0 +1,62 @@ +/** + * 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 + +#include +#include +#include + +namespace facebook { +namespace react { + +/* + * Represent a particular committed state of a shadow tree. The object contains + * a pointer to a root shadow node, a sequential number of commit and telemetry. + */ +class ShadowTreeRevision final { + public: + /* + * Sequential number of the commit that created this revision of a shadow + * tree. + */ + using Number = int64_t; + + /* + * Creates the object with given root shadow node, revision number and + * telemetry. + */ + ShadowTreeRevision( + ShadowNode::Shared const &rootShadowNode, + Number number, + MountingTelemetry telemetry); + + /* + * Returns telemetry associated with this revision. + */ + MountingTelemetry const &getTelemetry() const; + + private: + friend class MountingCoordinator; + + /* + * Methods from this section are meant to be used by `MountingCoordinator` + * only. + */ + ShadowNode const &getRootShadowNode(); + Number getNumber() const; + + private: + ShadowNode::Shared rootShadowNode_; + Number number_; + MountingTelemetry telemetry_; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index 665ece3c751..c4637c1a3d5 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -228,12 +228,12 @@ SchedulerDelegate *Scheduler::getDelegate() const { #pragma mark - ShadowTreeDelegate void Scheduler::shadowTreeDidCommit( - const ShadowTree &shadowTree, - MountingTransaction &&transaction) const { + ShadowTree const &shadowTree, + MountingCoordinator::Shared const &mountingCoordinator) const { SystraceSection s("Scheduler::shadowTreeDidCommit"); if (delegate_) { - delegate_->schedulerDidFinishTransaction(std::move(transaction)); + delegate_->schedulerDidFinishTransaction(mountingCoordinator); } } diff --git a/ReactCommon/fabric/uimanager/Scheduler.h b/ReactCommon/fabric/uimanager/Scheduler.h index e0cab105a31..ea4469ac3ed 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.h +++ b/ReactCommon/fabric/uimanager/Scheduler.h @@ -91,8 +91,8 @@ class Scheduler final : public UIManagerDelegate, public ShadowTreeDelegate { #pragma mark - ShadowTreeDelegate void shadowTreeDidCommit( - const ShadowTree &shadowTree, - MountingTransaction &&transaction) const override; + ShadowTree const &shadowTree, + MountingCoordinator::Shared const &mountingCoordinator) const override; private: SchedulerDelegate *delegate_; diff --git a/ReactCommon/fabric/uimanager/SchedulerDelegate.h b/ReactCommon/fabric/uimanager/SchedulerDelegate.h index 39996053c58..45212d92dd7 100644 --- a/ReactCommon/fabric/uimanager/SchedulerDelegate.h +++ b/ReactCommon/fabric/uimanager/SchedulerDelegate.h @@ -26,7 +26,7 @@ class SchedulerDelegate { * to construct a new one. */ virtual void schedulerDidFinishTransaction( - MountingTransaction &&mountingTransaction) = 0; + MountingCoordinator::Shared const &mountingCoordinator) = 0; /* * Called right after a new ShadowNode was created.