Fabric: MountingCoordinator - the new way to ensure ordering of mount transaction

Summary:
TBD.
This thing fixes flickering during appearing of Fabric screens on iOS.

Reviewed By: mdvacca

Differential Revision: D15116079

fbshipit-source-id: 95ed0ba94667cad67fe4317025128d01b34f69c5
This commit is contained in:
Valentin Shergin
2019-05-03 15:05:26 -07:00
committed by Facebook Github Bot
parent 4803cab8c4
commit 0f2a09d1f6
21 changed files with 343 additions and 220 deletions

View File

@@ -11,7 +11,7 @@
#import <React/RCTPrimitives.h>
#import <react/core/ComponentDescriptor.h>
#import <react/core/ReactPrimitives.h>
#import <react/mounting/MountingTransaction.h>
#import <react/mounting/MountingCoordinator.h>
#import <react/mounting/ShadowView.h>
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.

View File

@@ -15,7 +15,6 @@
#import <react/core/LayoutableShadowNode.h>
#import <react/core/RawProps.h>
#import <react/debug/SystraceSection.h>
#import <react/mounting/MountingTransactionSynchronizer.h>
#import "RCTComponentViewProtocol.h"
#import "RCTComponentViewRegistry.h"
@@ -204,9 +203,7 @@ static void RNPerformMountInstructions(ShadowViewMutationList const &mutations,
}
}
@implementation RCTMountingManager {
better::map<SurfaceId, MountingTransactionSynchronizer> 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<MountingTransaction>(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

View File

@@ -12,8 +12,7 @@
#import <react/core/ComponentDescriptor.h>
#import <react/core/LayoutConstraints.h>
#import <react/core/LayoutContext.h>
#import <react/mounting/MountingTransaction.h>
#import <react/mounting/ShadowViewMutation.h>
#import <react/mounting/MountingCoordinator.h>
#import <react/uimanager/ComponentDescriptorFactory.h>
#import <react/utils/ContextContainer.h>
@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -353,12 +353,18 @@ local_ref<JMountItem::javaobject> 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<local_ref<jobject>> queue;
// Upper bound estimation of mount items to be delivered to Java side.

View File

@@ -57,7 +57,7 @@ class Binding : public jni::HybridClass<Binding>, public SchedulerDelegate {
void stopSurface(jint surfaceId);
void schedulerDidFinishTransaction(
MountingTransaction &&mountingTransaction);
MountingCoordinator::Shared const &mountingCoordinator);
void schedulerDidRequestPreliminaryViewAllocation(
const SurfaceId surfaceId,

View File

@@ -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 <glog/logging.h>
#endif
#include <react/mounting/Differentiator.h>
#include <react/mounting/ShadowViewMutation.h>
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<std::mutex> 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<MountingTransaction> MountingCoordinator::pullTransaction()
const {
std::lock_guard<std::mutex> 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

View File

@@ -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 <better/optional.h>
#include <react/mounting/MountingTransaction.h>
#include <react/mounting/ShadowTreeRevision.h>
#ifndef NDEBUG
#define RN_SHADOW_TREE_INTROSPECTION
#endif
#ifdef RN_SHADOW_TREE_INTROSPECTION
#include <react/mounting/stubs.h>
#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<MountingCoordinator const>;
/*
* 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<MountingTransaction> 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<ShadowTreeRevision> lastRevision_{};
mutable MountingTransaction::Number number_{0};
#ifdef RN_SHADOW_TREE_INTROSPECTION
mutable StubViewTree stubViewTree_; // Protected by `mutex_`.
#endif
};
} // namespace react
} // namespace facebook

View File

@@ -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

View File

@@ -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_;
};

View File

@@ -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<MountingTransaction> 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

View File

@@ -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 <better/optional.h>
#include <react/mounting/MountingTransaction.h>
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<MountingTransaction> pull();
private:
MountingTransaction::Revision revision_{0};
std::deque<MountingTransaction> queue_{};
};
} // namespace react
} // namespace facebook

View File

@@ -5,15 +5,13 @@
#include "ShadowTree.h"
#include <glog/logging.h>
#include <react/components/root/RootComponentDescriptor.h>
#include <react/components/view/ViewShadowNode.h>
#include <react/core/LayoutContext.h>
#include <react/core/LayoutPrimitives.h>
#include <react/debug/SystraceSection.h>
#include <react/mounting/Differentiator.h>
#include <react/mounting/MountingTelemetry.h>
#include <react/mounting/ShadowTreeRevision.h>
#include <react/mounting/ShadowViewMutation.h>
#include "ShadowTreeDelegate.h"
@@ -100,9 +98,8 @@ ShadowTree::ShadowTree(
/* .eventEmitter = */ noopEventEmitter,
}));
#ifdef RN_SHADOW_TREE_INTROSPECTION
stubViewTree_ = stubViewTreeFromShadowNode(*rootShadowNode_);
#endif
mountingCoordinator_ = std::make_shared<MountingCoordinator const>(
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;

View File

@@ -5,9 +5,6 @@
#pragma once
#ifndef NDEBUG
#define RN_SHADOW_TREE_INTROSPECTION
#endif
#include <better/mutex.h>
#include <memory>
@@ -17,12 +14,9 @@
#include <react/core/LayoutConstraints.h>
#include <react/core/ReactPrimitives.h>
#include <react/core/ShadowNode.h>
#include <react/mounting/MountingCoordinator.h>
#include <react/mounting/ShadowTreeDelegate.h>
#include <react/mounting/ShadowViewMutation.h>
#ifdef RN_SHADOW_TREE_INTROSPECTION
#include <react/mounting/stubs.h>
#endif
#include <react/mounting/ShadowTreeRevision.h>
namespace facebook {
namespace react {
@@ -83,15 +77,13 @@ class ShadowTree final {
void emitLayoutEvents(
std::vector<LayoutableShadowNode const *> &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

View File

@@ -5,7 +5,7 @@
#pragma once
#include <react/mounting/MountingTransaction.h>
#include <react/mounting/MountingCoordinator.h>
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;
};

View File

@@ -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

View File

@@ -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 <better/optional.h>
#include <react/mounting/MountingTelemetry.h>
#include <react/mounting/MountingTransaction.h>
#include <react/mounting/ShadowViewMutation.h>
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

View File

@@ -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);
}
}

View File

@@ -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_;

View File

@@ -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.