react-native-reanimated 4.3.1 → 4.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Common/cpp/reanimated/CSS/interpolation/transforms/TransformOperationInterpolator.cpp +12 -5
- package/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.cpp +59 -37
- package/Common/cpp/reanimated/CSS/misc/ViewStylesRepository.h +11 -8
- package/Common/cpp/reanimated/CSS/registries/CSSAnimationsRegistry.cpp +4 -0
- package/Common/cpp/reanimated/CSS/registries/StaticPropsRegistry.cpp +17 -4
- package/Common/cpp/reanimated/CSS/registries/StaticPropsRegistry.h +5 -0
- package/Common/cpp/reanimated/CSS/svg/values/SVGStrokeDashArray.cpp +5 -0
- package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.cpp +25 -12
- package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.h +3 -0
- package/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp +48 -23
- package/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h +13 -6
- package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h +38 -0
- package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.cpp +106 -33
- package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp +205 -92
- package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h +4 -0
- package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +5 -11
- package/android/CMakeLists.txt +4 -1
- package/android/build.gradle +2 -0
- package/android/generate-stub-pch.gradle.kts +84 -0
- package/android/src/main/cpp/ReanimatedPCH.h +46 -0
- package/android/src/main/java/com/swmansion/reanimated/NativeProxy.java +14 -1
- package/android/src/main/java/com/swmansion/reanimated/keyboard/KeyboardAnimationCallback.java +9 -1
- package/apple/reanimated/apple/ReanimatedModule.mm +12 -1
- package/lib/module/PropsRegistryGarbageCollector.js +3 -6
- package/lib/module/PropsRegistryGarbageCollector.js.map +1 -1
- package/lib/module/animation/styleAnimation.js +4 -3
- package/lib/module/animation/styleAnimation.js.map +1 -1
- package/lib/module/common/constants/platform.js +5 -5
- package/lib/module/common/constants/platform.js.map +1 -1
- package/lib/module/createAnimatedComponent/getViewInfo.js +3 -1
- package/lib/module/createAnimatedComponent/getViewInfo.js.map +1 -1
- package/lib/module/css/component/AnimatedComponent.js +0 -2
- package/lib/module/css/component/AnimatedComponent.js.map +1 -1
- package/lib/module/css/native/managers/CSSManager.js +5 -5
- package/lib/module/css/native/managers/CSSManager.js.map +1 -1
- package/lib/module/css/native/managers/CSSTransitionsManager.js +8 -1
- package/lib/module/css/native/managers/CSSTransitionsManager.js.map +1 -1
- package/lib/module/css/svg/native/processors/stroke.js +9 -5
- package/lib/module/css/svg/native/processors/stroke.js.map +1 -1
- package/lib/module/layoutReanimation/animationsManager.js +9 -6
- package/lib/module/layoutReanimation/animationsManager.js.map +1 -1
- package/lib/module/platform-specific/findHostInstance.js +8 -5
- package/lib/module/platform-specific/findHostInstance.js.map +1 -1
- package/lib/module/platform-specific/jsVersion.js +1 -1
- package/lib/module/updateProps/updateProps.js +3 -2
- package/lib/module/updateProps/updateProps.js.map +1 -1
- package/lib/module/valueSetter.js +1 -1
- package/lib/module/valueSetter.js.map +1 -1
- package/lib/typescript/PropsRegistryGarbageCollector.d.ts +0 -1
- package/lib/typescript/PropsRegistryGarbageCollector.d.ts.map +1 -1
- package/lib/typescript/animation/styleAnimation.d.ts +1 -1
- package/lib/typescript/animation/styleAnimation.d.ts.map +1 -1
- package/lib/typescript/common/constants/platform.d.ts.map +1 -1
- package/lib/typescript/createAnimatedComponent/commonTypes.d.ts +0 -1
- package/lib/typescript/createAnimatedComponent/commonTypes.d.ts.map +1 -1
- package/lib/typescript/createAnimatedComponent/getViewInfo.d.ts.map +1 -1
- package/lib/typescript/css/component/AnimatedComponent.d.ts +0 -1
- package/lib/typescript/css/component/AnimatedComponent.d.ts.map +1 -1
- package/lib/typescript/css/native/managers/CSSTransitionsManager.d.ts +5 -1
- package/lib/typescript/css/native/managers/CSSTransitionsManager.d.ts.map +1 -1
- package/lib/typescript/css/svg/native/processors/stroke.d.ts.map +1 -1
- package/lib/typescript/layoutReanimation/animationsManager.d.ts.map +1 -1
- package/lib/typescript/platform-specific/findHostInstance.d.ts.map +1 -1
- package/lib/typescript/platform-specific/jsVersion.d.ts +1 -1
- package/lib/typescript/platform-specific/types.d.ts +1 -0
- package/lib/typescript/platform-specific/types.d.ts.map +1 -1
- package/lib/typescript/updateProps/updateProps.d.ts.map +1 -1
- package/lib/typescript/valueSetter.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/PropsRegistryGarbageCollector.ts +3 -6
- package/src/animation/styleAnimation.ts +5 -3
- package/src/common/constants/platform.ts +6 -5
- package/src/createAnimatedComponent/commonTypes.ts +0 -1
- package/src/createAnimatedComponent/getViewInfo.ts +3 -1
- package/src/css/component/AnimatedComponent.tsx +0 -2
- package/src/css/native/managers/CSSManager.ts +8 -8
- package/src/css/native/managers/CSSTransitionsManager.ts +9 -2
- package/src/css/svg/native/processors/stroke.ts +9 -6
- package/src/layoutReanimation/animationsManager.ts +9 -7
- package/src/platform-specific/findHostInstance.ts +7 -7
- package/src/platform-specific/jsVersion.ts +1 -1
- package/src/platform-specific/types.ts +2 -0
- package/src/updateProps/updateProps.ts +3 -2
- package/src/valueSetter.ts +2 -1
|
@@ -518,11 +518,10 @@ bool LayoutAnimationsProxy_Experimental::startAnimationsRecursively(
|
|
|
518
518
|
|
|
519
519
|
if (hasExitAnimation) {
|
|
520
520
|
node->state = ANIMATING;
|
|
521
|
-
startExitingAnimation(node);
|
|
522
521
|
lightNodes_[node->current.tag] = node;
|
|
522
|
+
startExitingAnimation(node);
|
|
523
523
|
} else {
|
|
524
|
-
|
|
525
|
-
// layoutAnimationsManager_->clearLayoutAnimationConfig(node->tag);
|
|
524
|
+
layoutAnimationsManager_->clearLayoutAnimationConfig(node->current.tag);
|
|
526
525
|
}
|
|
527
526
|
|
|
528
527
|
return wantAnimateExit;
|
|
@@ -534,6 +533,13 @@ void LayoutAnimationsProxy_Experimental::updateOngoingAnimationTarget(const int
|
|
|
534
533
|
}
|
|
535
534
|
|
|
536
535
|
void LayoutAnimationsProxy_Experimental::maybeCancelAnimation(const int tag) const {
|
|
536
|
+
#ifdef ANDROID
|
|
537
|
+
// also invalidate animation starts that are scheduled but haven't run yet,
|
|
538
|
+
// so they don't re-create the animation after this cancellation
|
|
539
|
+
if (const auto it = pendingStarts_.find(tag); it != pendingStarts_.end()) {
|
|
540
|
+
it->second.handle++;
|
|
541
|
+
}
|
|
542
|
+
#endif
|
|
537
543
|
if (!layoutAnimations_.contains(tag)) {
|
|
538
544
|
return;
|
|
539
545
|
}
|
|
@@ -678,9 +684,24 @@ void LayoutAnimationsProxy_Experimental::startEnteringAnimation(const std::share
|
|
|
678
684
|
const auto &parent = node->parent.lock();
|
|
679
685
|
react_native_assert(parent && "Parent node is nullptr");
|
|
680
686
|
const auto parentTag = parent->current.tag;
|
|
687
|
+
#ifdef ANDROID
|
|
688
|
+
const auto handle = pendingStarts_[newChildShadowView.tag].handle;
|
|
689
|
+
pendingStarts_[newChildShadowView.tag].count++;
|
|
690
|
+
#endif
|
|
681
691
|
|
|
682
692
|
scheduleOnUI(
|
|
683
|
-
uiScheduler_,
|
|
693
|
+
uiScheduler_,
|
|
694
|
+
[weakThis = weak_from_this(),
|
|
695
|
+
finalView,
|
|
696
|
+
currentView,
|
|
697
|
+
newChildShadowView,
|
|
698
|
+
parentTag,
|
|
699
|
+
opacity
|
|
700
|
+
#ifdef ANDROID
|
|
701
|
+
,
|
|
702
|
+
handle
|
|
703
|
+
#endif
|
|
704
|
+
]() {
|
|
684
705
|
auto strongThis = weakThis.lock();
|
|
685
706
|
if (!strongThis) {
|
|
686
707
|
return;
|
|
@@ -690,6 +711,12 @@ void LayoutAnimationsProxy_Experimental::startEnteringAnimation(const std::share
|
|
|
690
711
|
const auto tag = newChildShadowView.tag;
|
|
691
712
|
{
|
|
692
713
|
auto lock = std::unique_lock<std::recursive_mutex>(strongThis->mutex);
|
|
714
|
+
#ifdef ANDROID
|
|
715
|
+
if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
|
|
716
|
+
// the view was removed before this start could run
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
#endif
|
|
693
720
|
strongThis->layoutAnimations_[tag] = {
|
|
694
721
|
.finalView = newChildShadowView,
|
|
695
722
|
.currentView = newChildShadowView,
|
|
@@ -723,38 +750,63 @@ void LayoutAnimationsProxy_Experimental::startExitingAnimation(const std::shared
|
|
|
723
750
|
const auto &parent = node->parent.lock();
|
|
724
751
|
react_native_assert(parent && "Parent node is nullptr");
|
|
725
752
|
const auto parentTag = parent->current.tag;
|
|
753
|
+
#ifdef ANDROID
|
|
754
|
+
const auto handle = pendingStarts_[tag].handle;
|
|
755
|
+
pendingStarts_[tag].count++;
|
|
756
|
+
#endif
|
|
726
757
|
|
|
727
|
-
scheduleOnUI(
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
758
|
+
scheduleOnUI(
|
|
759
|
+
uiScheduler_,
|
|
760
|
+
[weakThis = weak_from_this(),
|
|
761
|
+
tag,
|
|
762
|
+
parentTag,
|
|
763
|
+
oldChildShadowView,
|
|
764
|
+
surfaceId
|
|
765
|
+
#ifdef ANDROID
|
|
766
|
+
,
|
|
767
|
+
handle
|
|
768
|
+
#endif
|
|
769
|
+
]() {
|
|
770
|
+
auto strongThis = weakThis.lock();
|
|
771
|
+
if (!strongThis) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
732
774
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
775
|
+
auto oldView = oldChildShadowView;
|
|
776
|
+
Rect window{};
|
|
777
|
+
{
|
|
778
|
+
auto &mutex = strongThis->mutex;
|
|
779
|
+
auto lock = std::unique_lock<std::recursive_mutex>(mutex);
|
|
780
|
+
#ifdef ANDROID
|
|
781
|
+
if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
|
|
782
|
+
// the view was removed (e.g. its subtree was force-ended by a screen
|
|
783
|
+
// pop) before this start could run — its Remove+Delete are already on
|
|
784
|
+
// their way to the mounting layer, so starting the animation now
|
|
785
|
+
// would emit updates for a view that's about to be deleted
|
|
786
|
+
strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
#endif
|
|
790
|
+
oldView = strongThis->maybeCreateLayoutAnimation(oldView, oldView, parentTag);
|
|
791
|
+
window = strongThis->surfaceManager.getWindow(surfaceId);
|
|
792
|
+
}
|
|
741
793
|
|
|
742
|
-
|
|
794
|
+
const Snapshot values(oldView, window);
|
|
743
795
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
796
|
+
auto &uiRuntime = strongThis->uiRuntime_;
|
|
797
|
+
const jsi::Object yogaValues(uiRuntime);
|
|
798
|
+
yogaValues.setProperty(uiRuntime, "currentOriginX", values.x);
|
|
799
|
+
yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", values.x);
|
|
800
|
+
yogaValues.setProperty(uiRuntime, "currentOriginY", values.y);
|
|
801
|
+
yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", values.y);
|
|
802
|
+
yogaValues.setProperty(uiRuntime, "currentWidth", values.width);
|
|
803
|
+
yogaValues.setProperty(uiRuntime, "currentHeight", values.height);
|
|
804
|
+
yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
|
|
805
|
+
yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
|
|
806
|
+
strongThis->layoutAnimationsManager_->startLayoutAnimation(
|
|
807
|
+
uiRuntime, tag, LayoutAnimationType::EXITING, yogaValues);
|
|
808
|
+
strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
|
|
809
|
+
});
|
|
758
810
|
}
|
|
759
811
|
|
|
760
812
|
void LayoutAnimationsProxy_Experimental::startLayoutAnimation(const std::shared_ptr<LightNode> &node) const {
|
|
@@ -765,9 +817,24 @@ void LayoutAnimationsProxy_Experimental::startLayoutAnimation(const std::shared_
|
|
|
765
817
|
const auto &parent = node->parent.lock();
|
|
766
818
|
react_native_assert(parent && "Parent node is nullptr");
|
|
767
819
|
const auto parentTag = parent->current.tag;
|
|
820
|
+
#ifdef ANDROID
|
|
821
|
+
const auto handle = pendingStarts_[tag].handle;
|
|
822
|
+
pendingStarts_[tag].count++;
|
|
823
|
+
#endif
|
|
768
824
|
|
|
769
825
|
scheduleOnUI(
|
|
770
|
-
uiScheduler_,
|
|
826
|
+
uiScheduler_,
|
|
827
|
+
[weakThis = weak_from_this(),
|
|
828
|
+
surfaceId,
|
|
829
|
+
oldChildShadowView,
|
|
830
|
+
newChildShadowView,
|
|
831
|
+
parentTag,
|
|
832
|
+
tag
|
|
833
|
+
#ifdef ANDROID
|
|
834
|
+
,
|
|
835
|
+
handle
|
|
836
|
+
#endif
|
|
837
|
+
]() {
|
|
771
838
|
auto strongThis = weakThis.lock();
|
|
772
839
|
if (!strongThis) {
|
|
773
840
|
return;
|
|
@@ -778,6 +845,12 @@ void LayoutAnimationsProxy_Experimental::startLayoutAnimation(const std::shared_
|
|
|
778
845
|
{
|
|
779
846
|
auto &mutex = strongThis->mutex;
|
|
780
847
|
auto lock = std::unique_lock<std::recursive_mutex>(mutex);
|
|
848
|
+
#ifdef ANDROID
|
|
849
|
+
if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
|
|
850
|
+
// the view was removed before this start could run
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
#endif
|
|
781
854
|
oldView = strongThis->maybeCreateLayoutAnimation(oldView, newChildShadowView, parentTag);
|
|
782
855
|
window = strongThis->surfaceManager.getWindow(surfaceId);
|
|
783
856
|
}
|
|
@@ -39,6 +39,8 @@ std::optional<MountingTransaction> LayoutAnimationsProxy_Legacy::pullTransaction
|
|
|
39
39
|
std::vector<std::shared_ptr<MutationNode>> roots;
|
|
40
40
|
std::unordered_map<Tag, Tag> movedViews;
|
|
41
41
|
|
|
42
|
+
reconcileContradictedRemovals(mutations, filteredMutations, surfaceId);
|
|
43
|
+
|
|
42
44
|
addOngoingAnimations(surfaceId, filteredMutations);
|
|
43
45
|
|
|
44
46
|
#ifdef ANDROID
|
|
@@ -64,6 +66,40 @@ std::optional<MountingTransaction> LayoutAnimationsProxy_Legacy::pullTransaction
|
|
|
64
66
|
return MountingTransaction{surfaceId, transactionNumber, std::move(filteredMutations), telemetry};
|
|
65
67
|
}
|
|
66
68
|
|
|
69
|
+
// If React re-creates or re-inserts a tag whose exiting removal we are still
|
|
70
|
+
// withholding, it has contradicted that withheld Remove/Delete. Flush it now
|
|
71
|
+
// instead of letting it fire later against a stale hierarchy (which would
|
|
72
|
+
// unmount the wrong, still-live view and crash the mounting layer).
|
|
73
|
+
//
|
|
74
|
+
// This must run before addOngoingAnimations (which would otherwise emit an
|
|
75
|
+
// Update for a tag we are about to Delete this frame) and before
|
|
76
|
+
// parseRemoveMutations, so the rest of the pipeline sees clean bookkeeping.
|
|
77
|
+
void LayoutAnimationsProxy_Legacy::reconcileContradictedRemovals(
|
|
78
|
+
ShadowViewMutationList &mutations,
|
|
79
|
+
ShadowViewMutationList &filteredMutations,
|
|
80
|
+
SurfaceId surfaceId) const {
|
|
81
|
+
auto &[deadNodes] = surfaceContext_[surfaceId];
|
|
82
|
+
for (auto &mutation : mutations) {
|
|
83
|
+
if (mutation.type != ShadowViewMutation::Type::Create && mutation.type != ShadowViewMutation::Type::Insert) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
auto tag = mutation.newChildShadowView.tag;
|
|
87
|
+
auto it = nodeForTag_.find(tag);
|
|
88
|
+
// Only a MutationNode represents a withheld removal; a plain Node is just a
|
|
89
|
+
// live parent of some removed child and must be left untouched.
|
|
90
|
+
if (it == nodeForTag_.end() || !it->second->isMutationNode()) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
auto node = std::static_pointer_cast<MutationNode>(it->second);
|
|
94
|
+
// Flush the withheld Remove/Delete for this tag (and its withheld subtree)
|
|
95
|
+
// right now, mirroring the deadNodes cleanup in handleRemovals. This removes
|
|
96
|
+
// the stale view before React's Create/Insert re-registers the same tag.
|
|
97
|
+
endAnimationsRecursively(node, filteredMutations);
|
|
98
|
+
maybeDropAncestors(node->unflattenedParent, node, filteredMutations);
|
|
99
|
+
deadNodes.erase(node);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
67
103
|
std::optional<SurfaceId> LayoutAnimationsProxy_Legacy::progressLayoutAnimation(int tag, const jsi::Object &newStyle) {
|
|
68
104
|
#ifdef LAYOUT_ANIMATIONS_LOGS
|
|
69
105
|
LOG(INFO) << "progress layout animation for tag " << tag << std::endl;
|
|
@@ -123,6 +159,10 @@ std::optional<SurfaceId> LayoutAnimationsProxy_Legacy::endLayoutAnimation(int ta
|
|
|
123
159
|
}
|
|
124
160
|
|
|
125
161
|
auto node = nodeForTag_[tag];
|
|
162
|
+
if (!node->isMutationNode()) {
|
|
163
|
+
react_native_assert(false && "exiting tag must map to a MutationNode");
|
|
164
|
+
return {};
|
|
165
|
+
}
|
|
126
166
|
auto mutationNode = std::static_pointer_cast<MutationNode>(node);
|
|
127
167
|
mutationNode->state = ExitingState_Legacy::DEAD;
|
|
128
168
|
auto &[deadNodes] = surfaceContext_[surfaceId];
|
|
@@ -635,38 +675,60 @@ void LayoutAnimationsProxy_Legacy::startEnteringAnimation(const int tag, ShadowV
|
|
|
635
675
|
|
|
636
676
|
auto &viewProps = static_cast<const ViewProps &>(*mutation.newChildShadowView.props);
|
|
637
677
|
auto opacity = viewProps.opacity;
|
|
678
|
+
#ifdef ANDROID
|
|
679
|
+
const auto handle = pendingStarts_[tag].handle;
|
|
680
|
+
pendingStarts_[tag].count++;
|
|
681
|
+
#endif
|
|
638
682
|
|
|
639
|
-
scheduleOnUI(
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
683
|
+
scheduleOnUI(
|
|
684
|
+
uiScheduler_,
|
|
685
|
+
[weakThis = weak_from_this(),
|
|
686
|
+
finalView,
|
|
687
|
+
current,
|
|
688
|
+
mutation,
|
|
689
|
+
opacity,
|
|
690
|
+
tag
|
|
691
|
+
#ifdef ANDROID
|
|
692
|
+
,
|
|
693
|
+
handle
|
|
694
|
+
#endif
|
|
695
|
+
]() {
|
|
696
|
+
auto strongThis = weakThis.lock();
|
|
697
|
+
if (!strongThis) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
644
700
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
tag,
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
701
|
+
Rect window{};
|
|
702
|
+
{
|
|
703
|
+
auto &mutex = strongThis->mutex;
|
|
704
|
+
auto lock = std::unique_lock<std::recursive_mutex>(mutex);
|
|
705
|
+
#ifdef ANDROID
|
|
706
|
+
if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
|
|
707
|
+
// the view was removed before this start could run
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
#endif
|
|
711
|
+
strongThis->layoutAnimations_.insert_or_assign(
|
|
712
|
+
tag,
|
|
713
|
+
LayoutAnimation{
|
|
714
|
+
.finalView = finalView, .currentView = current, .parentTag = mutation.parentTag, .opacity = opacity});
|
|
715
|
+
window = strongThis->surfaceManager.getWindow(mutation.newChildShadowView.surfaceId);
|
|
716
|
+
}
|
|
655
717
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
718
|
+
Snapshot values(mutation.newChildShadowView, window);
|
|
719
|
+
auto &uiRuntime = strongThis->uiRuntime_;
|
|
720
|
+
jsi::Object yogaValues(uiRuntime);
|
|
721
|
+
yogaValues.setProperty(uiRuntime, "targetOriginX", values.x);
|
|
722
|
+
yogaValues.setProperty(uiRuntime, "targetGlobalOriginX", values.x);
|
|
723
|
+
yogaValues.setProperty(uiRuntime, "targetOriginY", values.y);
|
|
724
|
+
yogaValues.setProperty(uiRuntime, "targetGlobalOriginY", values.y);
|
|
725
|
+
yogaValues.setProperty(uiRuntime, "targetWidth", values.width);
|
|
726
|
+
yogaValues.setProperty(uiRuntime, "targetHeight", values.height);
|
|
727
|
+
yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
|
|
728
|
+
yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
|
|
729
|
+
strongThis->layoutAnimationsManager_->startLayoutAnimation(
|
|
730
|
+
uiRuntime, tag, LayoutAnimationType::ENTERING, yogaValues);
|
|
731
|
+
});
|
|
670
732
|
}
|
|
671
733
|
|
|
672
734
|
void LayoutAnimationsProxy_Legacy::startExitingAnimation(const int tag, ShadowViewMutation &mutation) const {
|
|
@@ -674,38 +736,62 @@ void LayoutAnimationsProxy_Legacy::startExitingAnimation(const int tag, ShadowVi
|
|
|
674
736
|
LOG(INFO) << "start exiting animation for tag " << tag << std::endl;
|
|
675
737
|
#endif
|
|
676
738
|
auto surfaceId = mutation.oldChildShadowView.surfaceId;
|
|
739
|
+
#ifdef ANDROID
|
|
740
|
+
const auto handle = pendingStarts_[tag].handle;
|
|
741
|
+
pendingStarts_[tag].count++;
|
|
742
|
+
#endif
|
|
677
743
|
|
|
678
|
-
scheduleOnUI(
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
744
|
+
scheduleOnUI(
|
|
745
|
+
uiScheduler_,
|
|
746
|
+
[weakThis = weak_from_this(),
|
|
747
|
+
tag,
|
|
748
|
+
mutation,
|
|
749
|
+
surfaceId
|
|
750
|
+
#ifdef ANDROID
|
|
751
|
+
,
|
|
752
|
+
handle
|
|
753
|
+
#endif
|
|
754
|
+
]() {
|
|
755
|
+
auto strongThis = weakThis.lock();
|
|
756
|
+
if (!strongThis) {
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
692
759
|
|
|
693
|
-
|
|
760
|
+
auto oldView = mutation.oldChildShadowView;
|
|
761
|
+
Rect window{};
|
|
762
|
+
{
|
|
763
|
+
auto &mutex = strongThis->mutex;
|
|
764
|
+
auto lock = std::unique_lock<std::recursive_mutex>(mutex);
|
|
765
|
+
#ifdef ANDROID
|
|
766
|
+
if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
|
|
767
|
+
// the view was removed (e.g. its subtree was force-ended by a screen
|
|
768
|
+
// pop) before this start could run — its Remove+Delete are already on
|
|
769
|
+
// their way to the mounting layer, so starting the animation now
|
|
770
|
+
// would emit updates for a view that's about to be deleted
|
|
771
|
+
strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
#endif
|
|
775
|
+
strongThis->createLayoutAnimation(mutation, oldView, surfaceId, tag);
|
|
776
|
+
window = strongThis->surfaceManager.getWindow(surfaceId);
|
|
777
|
+
}
|
|
694
778
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
uiRuntime,
|
|
707
|
-
|
|
708
|
-
|
|
779
|
+
Snapshot values(oldView, window);
|
|
780
|
+
|
|
781
|
+
auto &uiRuntime = strongThis->uiRuntime_;
|
|
782
|
+
jsi::Object yogaValues(uiRuntime);
|
|
783
|
+
yogaValues.setProperty(uiRuntime, "currentOriginX", values.x);
|
|
784
|
+
yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", values.x);
|
|
785
|
+
yogaValues.setProperty(uiRuntime, "currentOriginY", values.y);
|
|
786
|
+
yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", values.y);
|
|
787
|
+
yogaValues.setProperty(uiRuntime, "currentWidth", values.width);
|
|
788
|
+
yogaValues.setProperty(uiRuntime, "currentHeight", values.height);
|
|
789
|
+
yogaValues.setProperty(uiRuntime, "windowWidth", values.windowWidth);
|
|
790
|
+
yogaValues.setProperty(uiRuntime, "windowHeight", values.windowHeight);
|
|
791
|
+
strongThis->layoutAnimationsManager_->startLayoutAnimation(
|
|
792
|
+
uiRuntime, tag, LayoutAnimationType::EXITING, yogaValues);
|
|
793
|
+
strongThis->layoutAnimationsManager_->clearLayoutAnimationConfig(tag);
|
|
794
|
+
});
|
|
709
795
|
}
|
|
710
796
|
|
|
711
797
|
void LayoutAnimationsProxy_Legacy::startLayoutAnimation(const int tag, const ShadowViewMutation &mutation) const {
|
|
@@ -713,43 +799,64 @@ void LayoutAnimationsProxy_Legacy::startLayoutAnimation(const int tag, const Sha
|
|
|
713
799
|
LOG(INFO) << "start layout animation for tag " << tag << std::endl;
|
|
714
800
|
#endif
|
|
715
801
|
auto surfaceId = mutation.oldChildShadowView.surfaceId;
|
|
802
|
+
#ifdef ANDROID
|
|
803
|
+
const auto handle = pendingStarts_[tag].handle;
|
|
804
|
+
pendingStarts_[tag].count++;
|
|
805
|
+
#endif
|
|
716
806
|
|
|
717
|
-
scheduleOnUI(
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
807
|
+
scheduleOnUI(
|
|
808
|
+
uiScheduler_,
|
|
809
|
+
[weakThis = weak_from_this(),
|
|
810
|
+
mutation,
|
|
811
|
+
surfaceId,
|
|
812
|
+
tag
|
|
813
|
+
#ifdef ANDROID
|
|
814
|
+
,
|
|
815
|
+
handle
|
|
816
|
+
#endif
|
|
817
|
+
]() {
|
|
818
|
+
auto strongThis = weakThis.lock();
|
|
819
|
+
if (!strongThis) {
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
731
822
|
|
|
732
|
-
|
|
733
|
-
|
|
823
|
+
auto oldView = mutation.oldChildShadowView;
|
|
824
|
+
Rect window{};
|
|
825
|
+
{
|
|
826
|
+
auto &mutex = strongThis->mutex;
|
|
827
|
+
auto lock = std::unique_lock<std::recursive_mutex>(mutex);
|
|
828
|
+
#ifdef ANDROID
|
|
829
|
+
if (consumeIsCancelled(strongThis->pendingStarts_, tag, handle)) {
|
|
830
|
+
// the view was removed before this start could run
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
#endif
|
|
834
|
+
strongThis->createLayoutAnimation(mutation, oldView, surfaceId, tag);
|
|
835
|
+
window = strongThis->surfaceManager.getWindow(surfaceId);
|
|
836
|
+
}
|
|
734
837
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
838
|
+
Snapshot currentValues(oldView, window);
|
|
839
|
+
Snapshot targetValues(mutation.newChildShadowView, window);
|
|
840
|
+
|
|
841
|
+
auto &uiRuntime = strongThis->uiRuntime_;
|
|
842
|
+
jsi::Object yogaValues(uiRuntime);
|
|
843
|
+
yogaValues.setProperty(uiRuntime, "currentOriginX", currentValues.x);
|
|
844
|
+
yogaValues.setProperty(uiRuntime, "currentGlobalOriginX", currentValues.x);
|
|
845
|
+
yogaValues.setProperty(uiRuntime, "currentOriginY", currentValues.y);
|
|
846
|
+
yogaValues.setProperty(uiRuntime, "currentGlobalOriginY", currentValues.y);
|
|
847
|
+
yogaValues.setProperty(uiRuntime, "currentWidth", currentValues.width);
|
|
848
|
+
yogaValues.setProperty(uiRuntime, "currentHeight", currentValues.height);
|
|
849
|
+
yogaValues.setProperty(uiRuntime, "targetOriginX", targetValues.x);
|
|
850
|
+
yogaValues.setProperty(uiRuntime, "targetGlobalOriginX", targetValues.x);
|
|
851
|
+
yogaValues.setProperty(uiRuntime, "targetOriginY", targetValues.y);
|
|
852
|
+
yogaValues.setProperty(uiRuntime, "targetGlobalOriginY", targetValues.y);
|
|
853
|
+
yogaValues.setProperty(uiRuntime, "targetWidth", targetValues.width);
|
|
854
|
+
yogaValues.setProperty(uiRuntime, "targetHeight", targetValues.height);
|
|
855
|
+
yogaValues.setProperty(uiRuntime, "windowWidth", targetValues.windowWidth);
|
|
856
|
+
yogaValues.setProperty(uiRuntime, "windowHeight", targetValues.windowHeight);
|
|
857
|
+
strongThis->layoutAnimationsManager_->startLayoutAnimation(
|
|
858
|
+
uiRuntime, tag, LayoutAnimationType::LAYOUT, yogaValues);
|
|
859
|
+
});
|
|
753
860
|
}
|
|
754
861
|
|
|
755
862
|
void LayoutAnimationsProxy_Legacy::updateOngoingAnimationTarget(const int tag, const ShadowViewMutation &mutation)
|
|
@@ -759,6 +866,12 @@ void LayoutAnimationsProxy_Legacy::updateOngoingAnimationTarget(const int tag, c
|
|
|
759
866
|
}
|
|
760
867
|
|
|
761
868
|
void LayoutAnimationsProxy_Legacy::maybeCancelAnimation(const int tag) const {
|
|
869
|
+
#ifdef ANDROID
|
|
870
|
+
// invalidate animation starts that are scheduled but haven't run yet
|
|
871
|
+
if (const auto it = pendingStarts_.find(tag); it != pendingStarts_.end()) {
|
|
872
|
+
it->second.handle++;
|
|
873
|
+
}
|
|
874
|
+
#endif
|
|
762
875
|
if (!layoutAnimations_.contains(tag)) {
|
|
763
876
|
return;
|
|
764
877
|
}
|
|
@@ -148,6 +148,10 @@ struct LayoutAnimationsProxy_Legacy : public LayoutAnimationsProxyCommon,
|
|
|
148
148
|
std::optional<SurfaceId> endLayoutAnimation(int tag, bool shouldRemove) override;
|
|
149
149
|
void maybeCancelAnimation(const int tag) const;
|
|
150
150
|
|
|
151
|
+
void reconcileContradictedRemovals(
|
|
152
|
+
ShadowViewMutationList &mutations,
|
|
153
|
+
ShadowViewMutationList &filteredMutations,
|
|
154
|
+
SurfaceId surfaceId) const;
|
|
151
155
|
void parseRemoveMutations(
|
|
152
156
|
std::unordered_map<Tag, Tag> &movedViews,
|
|
153
157
|
ShadowViewMutationList &mutations,
|
|
@@ -524,15 +524,13 @@ jsi::Value ReanimatedModuleProxy::getSettledUpdates(jsi::Runtime &rt) {
|
|
|
524
524
|
StaticFeatureFlags::getFlag("FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS") &&
|
|
525
525
|
"getSettledUpdates requires FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS static feature flag to be enabled");
|
|
526
526
|
|
|
527
|
+
constexpr double SETTLED_ANIMATION_THRESHOLD_MS = 1000;
|
|
528
|
+
|
|
527
529
|
// TODO(future): use unified timestamp
|
|
528
530
|
const auto currentTimestamp = getAnimationTimestamp_();
|
|
529
531
|
|
|
530
|
-
// TODO: fix bug when threshold difference is smaller than 1 second
|
|
531
532
|
// TODO(future): flush updates from CSS animations and CSS transitions registries
|
|
532
|
-
|
|
533
|
-
// TODO(future): move removing old updates to separate method
|
|
534
|
-
return animatedPropsRegistry_->getUpdatesOlderThanTimestamp(
|
|
535
|
-
rt, currentTimestamp - 1000 /* 1 second */, currentTimestamp - 2000 /* 2 seconds */);
|
|
533
|
+
return animatedPropsRegistry_->collectSettledUpdates(rt, currentTimestamp - SETTLED_ANIMATION_THRESHOLD_MS);
|
|
536
534
|
}
|
|
537
535
|
|
|
538
536
|
bool ReanimatedModuleProxy::handleEvent(
|
|
@@ -717,11 +715,6 @@ void ReanimatedModuleProxy::performOperations() {
|
|
|
717
715
|
}
|
|
718
716
|
|
|
719
717
|
commitUpdates(uiRuntime, updatesBatch);
|
|
720
|
-
|
|
721
|
-
// Clear the entire cache after the commit
|
|
722
|
-
// (we don't know if the view is updated from outside of Reanimated
|
|
723
|
-
// so we have to clear the entire cache)
|
|
724
|
-
viewStylesRepository_->clearNodesCache();
|
|
725
718
|
}
|
|
726
719
|
|
|
727
720
|
void ReanimatedModuleProxy::performNonLayoutOperations() {
|
|
@@ -1292,7 +1285,8 @@ void ReanimatedModuleProxy::initializeFabric(const std::shared_ptr<UIManager> &u
|
|
|
1292
1285
|
|
|
1293
1286
|
strongThis->requestFlushRegistry();
|
|
1294
1287
|
};
|
|
1295
|
-
mountHook_ =
|
|
1288
|
+
mountHook_ =
|
|
1289
|
+
std::make_shared<ReanimatedMountHook>(uiManager_, updatesRegistryManager_, viewStylesRepository_, request);
|
|
1296
1290
|
commitHook_ = std::make_shared<ReanimatedCommitHook>(uiManager_, updatesRegistryManager_, layoutAnimationsProxy_);
|
|
1297
1291
|
}
|
|
1298
1292
|
|
package/android/CMakeLists.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
project(Reanimated)
|
|
2
|
-
cmake_minimum_required(VERSION 3.
|
|
2
|
+
cmake_minimum_required(VERSION 3.16)
|
|
3
3
|
|
|
4
4
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
5
5
|
|
|
@@ -50,6 +50,9 @@ find_package(react-native-worklets REQUIRED CONFIG)
|
|
|
50
50
|
add_library(reanimated SHARED ${REANIMATED_COMMON_CPP_SOURCES}
|
|
51
51
|
${REANIMATED_ANDROID_CPP_SOURCES})
|
|
52
52
|
|
|
53
|
+
target_precompile_headers(reanimated PRIVATE
|
|
54
|
+
"${ANDROID_CPP_DIR}/ReanimatedPCH.h")
|
|
55
|
+
|
|
53
56
|
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 80)
|
|
54
57
|
include(
|
|
55
58
|
"${REACT_NATIVE_DIR}/ReactCommon/cmake-utils/react-native-flags.cmake")
|
package/android/build.gradle
CHANGED