You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.9 KiB

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "Timeline.h"
#include <react/renderer/uimanager/UIManager.h>
namespace facebook::react {
Timeline::Timeline(ShadowTree const &shadowTree) : shadowTree_(&shadowTree) {
record(shadowTree.getCurrentRevision().rootShadowNode);
};
#pragma mark - Public
SurfaceId Timeline::getSurfaceId() const noexcept {
return shadowTree_->getSurfaceId();
}
void Timeline::pause() const noexcept {
std::lock_guard<std::recursive_mutex> lock(mutex_);
assert(!paused_ && "");
paused_ = true;
}
void Timeline::resume() const noexcept {
std::lock_guard<std::recursive_mutex> lock(mutex_);
if (!snapshots_.empty()) {
rewind(snapshots_.at(snapshots_.size() - 1));
}
assert(paused_ && "");
paused_ = false;
}
bool Timeline::isPaused() const noexcept {
std::lock_guard<std::recursive_mutex> lock(mutex_);
return paused_;
}
TimelineFrame::List Timeline::getFrames() const noexcept {
std::lock_guard<std::recursive_mutex> lock(mutex_);
auto frames = TimelineFrame::List{};
frames.reserve(snapshots_.size());
for (auto const &snapshot : snapshots_) {
frames.push_back(snapshot.getFrame());
}
return frames;
}
TimelineFrame Timeline::getCurrentFrame() const noexcept {
assert(snapshots_.size() > currentSnapshotIndex_);
return snapshots_.at(currentSnapshotIndex_).getFrame();
}
void Timeline::rewind(TimelineFrame const &frame) const noexcept {
std::lock_guard<std::recursive_mutex> lock(mutex_);
rewind(snapshots_.at(frame.getIndex()));
}
RootShadowNode::Unshared Timeline::shadowTreeWillCommit(
ShadowTree const & /*shadowTree*/,
RootShadowNode::Shared const & /*oldRootShadowNode*/,
RootShadowNode::Unshared const &newRootShadowNode) const noexcept {
std::lock_guard<std::recursive_mutex> lock(mutex_);
if (rewinding_) {
return newRootShadowNode;
}
record(newRootShadowNode);
if (paused_) {
return nullptr;
}
return newRootShadowNode;
}
#pragma mark - Private & Internal
void Timeline::record(
RootShadowNode::Shared const &rootShadowNode) const noexcept {
auto index = (int)snapshots_.size();
snapshots_.push_back(TimelineSnapshot{rootShadowNode, index});
if (!paused_) {
currentSnapshotIndex_ = index;
}
}
void Timeline::rewind(TimelineSnapshot const &snapshot) const noexcept {
std::lock_guard<std::recursive_mutex> lock(mutex_);
currentSnapshotIndex_ = snapshot.getFrame().getIndex();
assert(!rewinding_ && "");
rewinding_ = true;
auto rootShadowNode = snapshot.getRootShadowNode();
shadowTree_->commit(
[&](RootShadowNode const & /*oldRootShadowNode*/)
-> RootShadowNode::Unshared {
return std::static_pointer_cast<RootShadowNode>(
rootShadowNode->ShadowNode::clone({}));
});
assert(rewinding_ && "");
rewinding_ = false;
}
} // namespace facebook::react