mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
LayoutAnimations: stopSurface
Summary: Implementing stopSurface to stop ongoing animations. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D23382974 fbshipit-source-id: 478e0b1ad443ceeb771b03bd1689ec2bdbe02979
This commit is contained in:
committed by
Facebook GitHub Bot
parent
6a3c866b6a
commit
fe7ff13fcf
@@ -316,6 +316,11 @@ bool LayoutAnimationKeyFrameManager::shouldOverridePullTransaction() const {
|
||||
return shouldAnimateFrame();
|
||||
}
|
||||
|
||||
void LayoutAnimationKeyFrameManager::stopSurface(SurfaceId surfaceId) {
|
||||
std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
|
||||
surfaceIdsToStop_.push_back(surfaceId);
|
||||
}
|
||||
|
||||
bool LayoutAnimationKeyFrameManager::shouldAnimateFrame() const {
|
||||
// There is potentially a race here between getting and setting
|
||||
// `currentMutation_`. We don't want to lock around this because then we're
|
||||
@@ -780,6 +785,35 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
||||
|
||||
bool inflightAnimationsExistInitially = !inflightAnimations_.empty();
|
||||
|
||||
// Execute stopSurface on any ongoing animations
|
||||
if (inflightAnimationsExistInitially) {
|
||||
std::vector<SurfaceId> surfaceIdsToStop{};
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(surfaceIdsToStopMutex_);
|
||||
surfaceIdsToStop = surfaceIdsToStop_;
|
||||
surfaceIdsToStop_ = {};
|
||||
}
|
||||
|
||||
for (auto it = inflightAnimations_.begin();
|
||||
it != inflightAnimations_.end();) {
|
||||
const auto &animation = *it;
|
||||
|
||||
if (std::find(
|
||||
surfaceIdsToStop.begin(),
|
||||
surfaceIdsToStop.end(),
|
||||
animation.surfaceId) != surfaceIdsToStop.end()) {
|
||||
#ifdef LAYOUT_ANIMATION_VERBOSE_LOGGING
|
||||
LOG(ERROR)
|
||||
<< "LayoutAnimations: stopping animation due to stopSurface on "
|
||||
<< surfaceId;
|
||||
#endif
|
||||
it = inflightAnimations_.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mutations.empty()) {
|
||||
#ifdef RN_SHADOW_TREE_INTROSPECTION
|
||||
{
|
||||
|
||||
@@ -184,6 +184,8 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
|
||||
|
||||
bool shouldOverridePullTransaction() const override;
|
||||
|
||||
void stopSurface(SurfaceId surfaceId) override;
|
||||
|
||||
// This is used to "hijack" the diffing process to figure out which mutations
|
||||
// should be animated. The mutations returned by this function will be
|
||||
// executed immediately.
|
||||
@@ -227,6 +229,9 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
|
||||
ShadowViewMutationList &mutations,
|
||||
bool deletesOnly = false) const;
|
||||
|
||||
mutable std::mutex surfaceIdsToStopMutex_;
|
||||
mutable std::vector<SurfaceId> surfaceIdsToStop_{};
|
||||
|
||||
protected:
|
||||
bool mutatedViewIsVirtual(ShadowViewMutation const &mutation) const;
|
||||
|
||||
|
||||
@@ -246,6 +246,9 @@ void Scheduler::renderTemplateToSurface(
|
||||
void Scheduler::stopSurface(SurfaceId surfaceId) const {
|
||||
SystraceSection s("Scheduler::stopSurface");
|
||||
|
||||
// Stop any ongoing animations.
|
||||
uiManager_->stopSurfaceForAnimationDelegate(surfaceId);
|
||||
|
||||
// Note, we have to do in inside `visit` function while the Shadow Tree
|
||||
// is still being registered.
|
||||
uiManager_->getShadowTreeRegistry().visit(
|
||||
|
||||
@@ -336,6 +336,12 @@ void UIManager::setAnimationDelegate(UIManagerAnimationDelegate *delegate) {
|
||||
animationDelegate_ = delegate;
|
||||
}
|
||||
|
||||
void UIManager::stopSurfaceForAnimationDelegate(SurfaceId surfaceId) {
|
||||
if (animationDelegate_ != nullptr) {
|
||||
animationDelegate_->stopSurface(surfaceId);
|
||||
}
|
||||
}
|
||||
|
||||
void UIManager::animationTick() {
|
||||
if (animationDelegate_ != nullptr &&
|
||||
animationDelegate_->shouldAnimateFrame()) {
|
||||
|
||||
@@ -50,6 +50,11 @@ class UIManager final : public ShadowTreeDelegate {
|
||||
*/
|
||||
void setAnimationDelegate(UIManagerAnimationDelegate *delegate);
|
||||
|
||||
/**
|
||||
* Execute stopSurface on any UIMAnagerAnimationDelegate.
|
||||
*/
|
||||
void stopSurfaceForAnimationDelegate(SurfaceId surfaceId);
|
||||
|
||||
void animationTick();
|
||||
|
||||
/*
|
||||
|
||||
@@ -41,6 +41,11 @@ class UIManagerAnimationDelegate {
|
||||
* Only needed on Android to drive animations.
|
||||
*/
|
||||
virtual bool shouldAnimateFrame() const = 0;
|
||||
|
||||
/**
|
||||
* Drop any animations for a given surface.
|
||||
*/
|
||||
virtual void stopSurface(SurfaceId surfaceId) = 0;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
Reference in New Issue
Block a user