react-native-reanimated 3.18.0 → 3.18.2
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/Fabric/ReanimatedCommitHook.cpp +14 -2
- package/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.h +6 -1
- package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.cpp +6 -1
- package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.h +6 -1
- package/Common/cpp/reanimated/Fabric/ShadowTreeCloner.cpp +3 -2
- package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.cpp +86 -24
- package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.h +29 -4
- package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.h +4 -5
- package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +45 -15
- package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h +4 -1
- package/Common/cpp/reanimated/Tools/ReanimatedSystraceSection.h +1 -1
- package/README.md +1 -13
- package/RNReanimated.podspec +1 -1
- package/android/src/main/cpp/reanimated/android/NativeProxy.cpp +25 -21
- package/android/src/main/cpp/reanimated/android/NativeProxy.h +5 -3
- package/apple/reanimated/apple/LayoutReanimation/REASharedTransitionManager.m +1 -2
- package/apple/reanimated/apple/LayoutReanimation/REASwizzledUIManager.mm +8 -7
- package/lib/module/PlatformChecker.js +6 -0
- package/lib/module/PlatformChecker.js.map +1 -1
- package/lib/module/animation/util.js +7 -4
- package/lib/module/animation/util.js.map +1 -1
- package/lib/module/component/FlatList.js +9 -3
- package/lib/module/component/FlatList.js.map +1 -1
- package/lib/module/core.js +0 -2
- package/lib/module/core.js.map +1 -1
- package/lib/module/createAnimatedComponent/NativeEventsManager.js +1 -1
- package/lib/module/createAnimatedComponent/NativeEventsManager.js.map +1 -1
- package/lib/module/createAnimatedComponent/createAnimatedComponent.js +24 -37
- package/lib/module/createAnimatedComponent/createAnimatedComponent.js.map +1 -1
- package/lib/module/hook/useAnimatedRef.js +70 -35
- package/lib/module/hook/useAnimatedRef.js.map +1 -1
- package/lib/module/hook/useHandler.js +7 -0
- package/lib/module/hook/useHandler.js.map +1 -1
- package/lib/module/hook/useScrollViewOffset.js +28 -26
- package/lib/module/hook/useScrollViewOffset.js.map +1 -1
- package/lib/module/hook/utils.js +20 -9
- package/lib/module/hook/utils.js.map +1 -1
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/platform-specific/jsVersion.js +1 -1
- package/lib/module/platformFunctions/setNativeProps.js +1 -1
- package/lib/module/platformFunctions/setNativeProps.js.map +1 -1
- package/lib/module/processBoxShadow.js.map +1 -1
- package/lib/typescript/PlatformChecker.d.ts +2 -0
- package/lib/typescript/PlatformChecker.d.ts.map +1 -1
- package/lib/typescript/animation/util.d.ts.map +1 -1
- package/lib/typescript/component/FlatList.d.ts +10 -2
- package/lib/typescript/component/FlatList.d.ts.map +1 -1
- package/lib/typescript/core.d.ts.map +1 -1
- package/lib/typescript/createAnimatedComponent/commonTypes.d.ts +1 -0
- package/lib/typescript/createAnimatedComponent/commonTypes.d.ts.map +1 -1
- package/lib/typescript/createAnimatedComponent/createAnimatedComponent.d.ts.map +1 -1
- package/lib/typescript/helperTypes.d.ts +1 -3
- package/lib/typescript/helperTypes.d.ts.map +1 -1
- package/lib/typescript/hook/commonTypes.d.ts +7 -4
- package/lib/typescript/hook/commonTypes.d.ts.map +1 -1
- package/lib/typescript/hook/useAnimatedRef.d.ts +3 -1
- package/lib/typescript/hook/useAnimatedRef.d.ts.map +1 -1
- package/lib/typescript/hook/useHandler.d.ts.map +1 -1
- package/lib/typescript/hook/useScrollViewOffset.d.ts.map +1 -1
- package/lib/typescript/hook/utils.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/platform-specific/jsVersion.d.ts +1 -1
- package/lib/typescript/processBoxShadow.d.ts +6 -3
- package/lib/typescript/processBoxShadow.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/PlatformChecker.ts +8 -0
- package/src/animation/util.ts +7 -4
- package/src/component/FlatList.tsx +44 -6
- package/src/core.ts +0 -3
- package/src/createAnimatedComponent/NativeEventsManager.ts +1 -1
- package/src/createAnimatedComponent/commonTypes.ts +9 -0
- package/src/createAnimatedComponent/createAnimatedComponent.tsx +61 -73
- package/src/helperTypes.ts +1 -6
- package/src/hook/commonTypes.ts +9 -4
- package/src/hook/useAnimatedRef.ts +107 -48
- package/src/hook/useHandler.ts +10 -0
- package/src/hook/useScrollViewOffset.ts +34 -29
- package/src/hook/utils.ts +34 -9
- package/src/index.ts +4 -1
- package/src/platform-specific/jsVersion.ts +1 -1
- package/src/platformFunctions/setNativeProps.ts +1 -1
- package/src/processBoxShadow.ts +8 -4
|
@@ -52,7 +52,12 @@ void ReanimatedCommitHook::maybeInitializeLayoutAnimations(
|
|
|
52
52
|
RootShadowNode::Unshared ReanimatedCommitHook::shadowTreeWillCommit(
|
|
53
53
|
ShadowTree const &,
|
|
54
54
|
RootShadowNode::Shared const &,
|
|
55
|
-
RootShadowNode::Unshared const &newRootShadowNode
|
|
55
|
+
RootShadowNode::Unshared const &newRootShadowNode
|
|
56
|
+
#if REACT_NATIVE_MINOR_VERSION >= 80
|
|
57
|
+
,
|
|
58
|
+
const ShadowTreeCommitOptions &commitOptions
|
|
59
|
+
#endif
|
|
60
|
+
) noexcept {
|
|
56
61
|
maybeInitializeLayoutAnimations(newRootShadowNode->getSurfaceId());
|
|
57
62
|
|
|
58
63
|
auto reaShadowNode =
|
|
@@ -89,8 +94,15 @@ RootShadowNode::Unshared ReanimatedCommitHook::shadowTreeWillCommit(
|
|
|
89
94
|
// PropsRegistry.
|
|
90
95
|
// This is very important, since if we didn't pause Reanimated commits,
|
|
91
96
|
// it could lead to RN commits being delayed until the animation is finished
|
|
92
|
-
// (very bad).
|
|
97
|
+
// (very bad). We don't pause Reanimated commits for state updates coming
|
|
98
|
+
// from React Native as this would break sticky header animations.
|
|
99
|
+
#if REACT_NATIVE_MINOR_VERSION >= 80
|
|
100
|
+
if (commitOptions.source == ShadowTreeCommitSource::React) {
|
|
101
|
+
propsRegistry_->pauseReanimatedCommits();
|
|
102
|
+
}
|
|
103
|
+
#else
|
|
93
104
|
propsRegistry_->pauseReanimatedCommits();
|
|
105
|
+
#endif
|
|
94
106
|
}
|
|
95
107
|
|
|
96
108
|
return rootNode;
|
|
@@ -32,7 +32,12 @@ class ReanimatedCommitHook
|
|
|
32
32
|
RootShadowNode::Unshared shadowTreeWillCommit(
|
|
33
33
|
ShadowTree const &shadowTree,
|
|
34
34
|
RootShadowNode::Shared const &oldRootShadowNode,
|
|
35
|
-
RootShadowNode::Unshared const &newRootShadowNode
|
|
35
|
+
RootShadowNode::Unshared const &newRootShadowNode
|
|
36
|
+
#if REACT_NATIVE_MINOR_VERSION >= 80
|
|
37
|
+
,
|
|
38
|
+
const ShadowTreeCommitOptions &commitOptions
|
|
39
|
+
#endif
|
|
40
|
+
) noexcept override;
|
|
36
41
|
|
|
37
42
|
private:
|
|
38
43
|
std::shared_ptr<PropsRegistry> propsRegistry_;
|
|
@@ -18,7 +18,12 @@ ReanimatedMountHook::~ReanimatedMountHook() noexcept {
|
|
|
18
18
|
|
|
19
19
|
void ReanimatedMountHook::shadowTreeDidMount(
|
|
20
20
|
const RootShadowNode::Shared &rootShadowNode,
|
|
21
|
-
|
|
21
|
+
#if REACT_NATIVE_MINOR_VERSION >= 81
|
|
22
|
+
HighResTimeStamp
|
|
23
|
+
#else
|
|
24
|
+
double
|
|
25
|
+
#endif // REACT_NATIVE_MINOR_VERSION >= 81
|
|
26
|
+
) noexcept {
|
|
22
27
|
auto reaShadowNode =
|
|
23
28
|
std::reinterpret_pointer_cast<ReanimatedCommitShadowNode>(
|
|
24
29
|
std::const_pointer_cast<RootShadowNode>(rootShadowNode));
|
|
@@ -21,7 +21,12 @@ class ReanimatedMountHook : public UIManagerMountHook {
|
|
|
21
21
|
|
|
22
22
|
void shadowTreeDidMount(
|
|
23
23
|
RootShadowNode::Shared const &rootShadowNode,
|
|
24
|
-
|
|
24
|
+
#if REACT_NATIVE_MINOR_VERSION >= 81
|
|
25
|
+
HighResTimeStamp /*unmountTime*/
|
|
26
|
+
#else
|
|
27
|
+
double /*unmountTime*/
|
|
28
|
+
#endif // REACT_NATIVE_MINOR_VERSION >= 81
|
|
29
|
+
) noexcept override;
|
|
25
30
|
|
|
26
31
|
private:
|
|
27
32
|
const std::shared_ptr<PropsRegistry> propsRegistry_;
|
|
@@ -42,7 +42,7 @@ Props::Shared mergeProps(
|
|
|
42
42
|
return newProps;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
ShadowNode
|
|
45
|
+
std::shared_ptr<ShadowNode> cloneShadowTreeWithNewPropsRecursive(
|
|
46
46
|
const ShadowNode &shadowNode,
|
|
47
47
|
const ChildrenMap &childrenMap,
|
|
48
48
|
const PropsMap &propsMap) {
|
|
@@ -59,7 +59,8 @@ ShadowNode::Unshared cloneShadowTreeWithNewPropsRecursive(
|
|
|
59
59
|
|
|
60
60
|
return shadowNode.clone(
|
|
61
61
|
{mergeProps(shadowNode, propsMap, *family),
|
|
62
|
-
std::make_shared<ShadowNode
|
|
62
|
+
std::make_shared<std::vector<std::shared_ptr<const ShadowNode>>>(
|
|
63
|
+
children),
|
|
63
64
|
shadowNode.getState()});
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -31,13 +31,25 @@ std::optional<MountingTransaction> LayoutAnimationsProxy::pullTransaction(
|
|
|
31
31
|
auto lock = std::unique_lock<std::recursive_mutex>(mutex);
|
|
32
32
|
PropsParserContext propsParserContext{surfaceId, *contextContainer_};
|
|
33
33
|
ShadowViewMutationList filteredMutations;
|
|
34
|
+
auto &[deadNodes] = surfaceContext_[surfaceId];
|
|
34
35
|
|
|
35
36
|
std::vector<std::shared_ptr<MutationNode>> roots;
|
|
36
|
-
std::unordered_map<Tag,
|
|
37
|
+
std::unordered_map<Tag, Tag> movedViews;
|
|
38
|
+
|
|
39
|
+
addOngoingAnimations(surfaceId, filteredMutations);
|
|
40
|
+
|
|
41
|
+
for (const auto tag : finishedAnimationTags_) {
|
|
42
|
+
auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
|
|
43
|
+
layoutAnimations_.erase(tag);
|
|
44
|
+
updateMap.erase(tag);
|
|
45
|
+
}
|
|
46
|
+
finishedAnimationTags_.clear();
|
|
37
47
|
|
|
38
48
|
parseRemoveMutations(movedViews, mutations, roots);
|
|
39
49
|
|
|
40
|
-
|
|
50
|
+
auto shouldAnimate = !surfacesToRemove_.contains(surfaceId);
|
|
51
|
+
surfacesToRemove_.erase(surfaceId);
|
|
52
|
+
handleRemovals(filteredMutations, roots, deadNodes, shouldAnimate);
|
|
41
53
|
|
|
42
54
|
handleUpdatesAndEnterings(
|
|
43
55
|
filteredMutations, movedViews, mutations, propsParserContext, surfaceId);
|
|
@@ -70,7 +82,7 @@ std::optional<SurfaceId> LayoutAnimationsProxy::progressLayoutAnimation(
|
|
|
70
82
|
|
|
71
83
|
PropsParserContext propsParserContext{
|
|
72
84
|
layoutAnimation.finalView->surfaceId, *contextContainer_};
|
|
73
|
-
#ifdef
|
|
85
|
+
#ifdef RN_SERIALIZABLE_STATE
|
|
74
86
|
rawProps = std::make_shared<RawProps>(folly::dynamic::merge(
|
|
75
87
|
layoutAnimation.finalView->props->rawProps, (folly::dynamic)*rawProps));
|
|
76
88
|
#endif
|
|
@@ -112,11 +124,8 @@ std::optional<SurfaceId> LayoutAnimationsProxy::endLayoutAnimation(
|
|
|
112
124
|
layoutAnimation.count--;
|
|
113
125
|
return {};
|
|
114
126
|
}
|
|
115
|
-
|
|
127
|
+
finishedAnimationTags_.push_back(tag);
|
|
116
128
|
auto surfaceId = layoutAnimation.finalView->surfaceId;
|
|
117
|
-
auto &updateMap = surfaceManager.getUpdateMap(surfaceId);
|
|
118
|
-
layoutAnimations_.erase(tag);
|
|
119
|
-
updateMap.erase(tag);
|
|
120
129
|
|
|
121
130
|
if (!shouldRemove || !nodeForTag_.contains(tag)) {
|
|
122
131
|
return {};
|
|
@@ -125,6 +134,7 @@ std::optional<SurfaceId> LayoutAnimationsProxy::endLayoutAnimation(
|
|
|
125
134
|
auto node = nodeForTag_[tag];
|
|
126
135
|
auto mutationNode = std::static_pointer_cast<MutationNode>(node);
|
|
127
136
|
mutationNode->state = DEAD;
|
|
137
|
+
auto &[deadNodes] = surfaceContext_[surfaceId];
|
|
128
138
|
deadNodes.insert(mutationNode);
|
|
129
139
|
|
|
130
140
|
return surfaceId;
|
|
@@ -135,7 +145,7 @@ std::optional<SurfaceId> LayoutAnimationsProxy::endLayoutAnimation(
|
|
|
135
145
|
traversals and index maintenance
|
|
136
146
|
*/
|
|
137
147
|
void LayoutAnimationsProxy::parseRemoveMutations(
|
|
138
|
-
std::unordered_map<Tag,
|
|
148
|
+
std::unordered_map<Tag, Tag> &movedViews,
|
|
139
149
|
ShadowViewMutationList &mutations,
|
|
140
150
|
std::vector<std::shared_ptr<MutationNode>> &roots) const {
|
|
141
151
|
std::set<Tag> deletedViews;
|
|
@@ -180,8 +190,7 @@ void LayoutAnimationsProxy::parseRemoveMutations(
|
|
|
180
190
|
}
|
|
181
191
|
if (!deletedViews.contains(mutation.oldChildShadowView.tag)) {
|
|
182
192
|
mutationNode->state = MOVED;
|
|
183
|
-
movedViews.insert_or_assign(
|
|
184
|
-
mutation.oldChildShadowView.tag, mutation.oldChildShadowView);
|
|
193
|
+
movedViews.insert_or_assign(mutation.oldChildShadowView.tag, -1);
|
|
185
194
|
}
|
|
186
195
|
nodeForTag_[tag] = mutationNode;
|
|
187
196
|
|
|
@@ -211,7 +220,18 @@ void LayoutAnimationsProxy::parseRemoveMutations(
|
|
|
211
220
|
auto node = nodeForTag_[mutation.newChildShadowView.tag];
|
|
212
221
|
auto mutationNode = std::static_pointer_cast<MutationNode>(node);
|
|
213
222
|
mutationNode->mutation.oldChildShadowView = mutation.oldChildShadowView;
|
|
214
|
-
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
for (const auto &mutation : mutations) {
|
|
227
|
+
if (mutation.type == ShadowViewMutation::Insert &&
|
|
228
|
+
movedViews.contains(mutation.newChildShadowView.tag)) {
|
|
229
|
+
#if REACT_NATIVE_MINOR_VERSION >= 78
|
|
230
|
+
movedViews[mutation.newChildShadowView.tag] = mutation.parentTag;
|
|
231
|
+
#else
|
|
232
|
+
movedViews[mutation.newChildShadowView.tag] =
|
|
233
|
+
mutation.parentShadowView.tag;
|
|
234
|
+
#endif // REACT_NATIVE_MINOR_VERSION >= 78
|
|
215
235
|
}
|
|
216
236
|
}
|
|
217
237
|
|
|
@@ -239,13 +259,15 @@ void LayoutAnimationsProxy::parseRemoveMutations(
|
|
|
239
259
|
|
|
240
260
|
void LayoutAnimationsProxy::handleRemovals(
|
|
241
261
|
ShadowViewMutationList &filteredMutations,
|
|
242
|
-
std::vector<std::shared_ptr<MutationNode>> &roots
|
|
262
|
+
std::vector<std::shared_ptr<MutationNode>> &roots,
|
|
263
|
+
std::unordered_set<std::shared_ptr<MutationNode>> &deadNodes,
|
|
264
|
+
bool shouldAnimate) const {
|
|
243
265
|
// iterate from the end, so that children
|
|
244
266
|
// with higher indices appear first in the mutations list
|
|
245
267
|
for (auto it = roots.rbegin(); it != roots.rend(); it++) {
|
|
246
268
|
auto &node = *it;
|
|
247
269
|
if (!startAnimationsRecursively(
|
|
248
|
-
node, true,
|
|
270
|
+
node, true, shouldAnimate, false, filteredMutations)) {
|
|
249
271
|
filteredMutations.push_back(node->mutation);
|
|
250
272
|
node->unflattenedParent->removeChildFromUnflattenedTree(node); //???
|
|
251
273
|
if (node->state != MOVED) {
|
|
@@ -253,6 +275,7 @@ void LayoutAnimationsProxy::handleRemovals(
|
|
|
253
275
|
filteredMutations.push_back(ShadowViewMutation::DeleteMutation(
|
|
254
276
|
node->mutation.oldChildShadowView));
|
|
255
277
|
nodeForTag_.erase(node->tag);
|
|
278
|
+
node->state = DELETED;
|
|
256
279
|
#ifdef LAYOUT_ANIMATIONS_LOGS
|
|
257
280
|
LOG(INFO) << "delete " << node->tag << std::endl;
|
|
258
281
|
#endif
|
|
@@ -271,7 +294,7 @@ void LayoutAnimationsProxy::handleRemovals(
|
|
|
271
294
|
|
|
272
295
|
void LayoutAnimationsProxy::handleUpdatesAndEnterings(
|
|
273
296
|
ShadowViewMutationList &filteredMutations,
|
|
274
|
-
const std::unordered_map<Tag,
|
|
297
|
+
const std::unordered_map<Tag, Tag> &movedViews,
|
|
275
298
|
ShadowViewMutationList &mutations,
|
|
276
299
|
const PropsParserContext &propsParserContext,
|
|
277
300
|
SurfaceId surfaceId) const {
|
|
@@ -320,6 +343,11 @@ void LayoutAnimationsProxy::handleUpdatesAndEnterings(
|
|
|
320
343
|
auto oldView = *layoutAnimationIt->second.currentView;
|
|
321
344
|
filteredMutations.push_back(ShadowViewMutation::InsertMutation(
|
|
322
345
|
mutationParent, oldView, mutation.index));
|
|
346
|
+
if (movedViews.contains(tag)) {
|
|
347
|
+
#if REACT_NATIVE_MINOR_VERSION >= 78
|
|
348
|
+
layoutAnimationIt->second.parentTag = movedViews.at(tag);
|
|
349
|
+
#endif // REACT_NATIVE_MINOR_VERSION >= 78
|
|
350
|
+
}
|
|
323
351
|
continue;
|
|
324
352
|
}
|
|
325
353
|
|
|
@@ -364,8 +392,23 @@ void LayoutAnimationsProxy::handleUpdatesAndEnterings(
|
|
|
364
392
|
// store the oldChildShadowView, so that we can use this ShadowView when
|
|
365
393
|
// the view is inserted
|
|
366
394
|
oldShadowViewsForReparentings[tag] = mutation.oldChildShadowView;
|
|
367
|
-
|
|
395
|
+
#if REACT_NATIVE_MINOR_VERSION >= 78
|
|
396
|
+
if (movedViews.contains(tag)) {
|
|
397
|
+
mutation.parentTag = movedViews.at(tag);
|
|
398
|
+
}
|
|
399
|
+
if (mutation.parentTag != -1) {
|
|
400
|
+
startLayoutAnimation(tag, mutation);
|
|
401
|
+
}
|
|
402
|
+
break;
|
|
403
|
+
#else
|
|
404
|
+
if (movedViews.contains(tag)) {
|
|
405
|
+
mutation.parentShadowView.tag = movedViews.at(tag);
|
|
406
|
+
}
|
|
407
|
+
if (mutation.parentShadowView.tag != -1) {
|
|
408
|
+
startLayoutAnimation(tag, mutation);
|
|
409
|
+
}
|
|
368
410
|
break;
|
|
411
|
+
#endif // REACT_NATIVE_MINOR_VERSION >= 78
|
|
369
412
|
}
|
|
370
413
|
|
|
371
414
|
case ShadowViewMutation::Type::Remove:
|
|
@@ -449,6 +492,7 @@ void LayoutAnimationsProxy::maybeDropAncestors(
|
|
|
449
492
|
nodeForTag_.erase(node->tag);
|
|
450
493
|
cleanupMutations.push_back(node->mutation);
|
|
451
494
|
maybeCancelAnimation(node->tag);
|
|
495
|
+
node->state = DELETED;
|
|
452
496
|
#ifdef LAYOUT_ANIMATIONS_LOGS
|
|
453
497
|
LOG(INFO) << "delete " << node->tag << std::endl;
|
|
454
498
|
#endif
|
|
@@ -483,7 +527,8 @@ bool LayoutAnimationsProxy::startAnimationsRecursively(
|
|
|
483
527
|
bool hasAnimatedChildren = false;
|
|
484
528
|
|
|
485
529
|
shouldRemoveSubviewsWithoutAnimations =
|
|
486
|
-
shouldRemoveSubviewsWithoutAnimations &&
|
|
530
|
+
shouldRemoveSubviewsWithoutAnimations &&
|
|
531
|
+
(!hasExitAnimation || node->state == MOVED);
|
|
487
532
|
std::vector<std::shared_ptr<MutationNode>> toBeRemoved;
|
|
488
533
|
|
|
489
534
|
// iterate from the end, so that children
|
|
@@ -655,7 +700,7 @@ void LayoutAnimationsProxy::startEnteringAnimation(
|
|
|
655
700
|
current,
|
|
656
701
|
#if REACT_NATIVE_MINOR_VERSION < 78
|
|
657
702
|
parent,
|
|
658
|
-
#endif //
|
|
703
|
+
#endif // REACT_NATIVE_MINOR_VERSION < 78
|
|
659
704
|
mutation,
|
|
660
705
|
opacity,
|
|
661
706
|
tag]() {
|
|
@@ -668,16 +713,14 @@ void LayoutAnimationsProxy::startEnteringAnimation(
|
|
|
668
713
|
{
|
|
669
714
|
auto &mutex = strongThis->mutex;
|
|
670
715
|
auto lock = std::unique_lock<std::recursive_mutex>(mutex);
|
|
671
|
-
strongThis->layoutAnimations_.insert_or_assign(
|
|
672
|
-
tag, LayoutAnimation {
|
|
673
|
-
finalView, current,
|
|
674
716
|
#if REACT_NATIVE_MINOR_VERSION >= 78
|
|
675
|
-
|
|
717
|
+
strongThis->layoutAnimations_.insert_or_assign(
|
|
718
|
+
tag,
|
|
719
|
+
LayoutAnimation{finalView, current, mutation.parentTag, opacity});
|
|
676
720
|
#else
|
|
677
|
-
|
|
721
|
+
strongThis->layoutAnimations_.insert_or_assign(
|
|
722
|
+
tag, LayoutAnimation{finalView, current, parent, opacity});
|
|
678
723
|
#endif // REACT_NATIVE_MINOR_VERSION >= 78
|
|
679
|
-
opacity
|
|
680
|
-
});
|
|
681
724
|
window = strongThis->surfaceManager.getWindow(
|
|
682
725
|
mutation.newChildShadowView.surfaceId);
|
|
683
726
|
}
|
|
@@ -865,6 +908,25 @@ void LayoutAnimationsProxy::maybeUpdateWindowDimensions(
|
|
|
865
908
|
}
|
|
866
909
|
}
|
|
867
910
|
|
|
911
|
+
// UIManagerAnimationDelegate
|
|
912
|
+
|
|
913
|
+
void LayoutAnimationsProxy::uiManagerDidConfigureNextLayoutAnimation(
|
|
914
|
+
jsi::Runtime &runtime,
|
|
915
|
+
const RawValue &config,
|
|
916
|
+
const jsi::Value &successCallbackValue,
|
|
917
|
+
const jsi::Value &failureCallbackValue) const {}
|
|
918
|
+
|
|
919
|
+
void LayoutAnimationsProxy::setComponentDescriptorRegistry(
|
|
920
|
+
const SharedComponentDescriptorRegistry &componentDescriptorRegistry) {}
|
|
921
|
+
|
|
922
|
+
bool LayoutAnimationsProxy::shouldAnimateFrame() const {
|
|
923
|
+
return false;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
void LayoutAnimationsProxy::stopSurface(SurfaceId surfaceId) {
|
|
927
|
+
surfacesToRemove_.insert(surfaceId);
|
|
928
|
+
}
|
|
929
|
+
|
|
868
930
|
} // namespace reanimated
|
|
869
931
|
|
|
870
932
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#include <react/renderer/componentregistry/ComponentDescriptorFactory.h>
|
|
11
11
|
#include <react/renderer/mounting/MountingOverrideDelegate.h>
|
|
12
12
|
#include <react/renderer/mounting/ShadowView.h>
|
|
13
|
+
#include <react/renderer/uimanager/UIManagerAnimationDelegate.h>
|
|
13
14
|
|
|
14
15
|
#include <memory>
|
|
15
16
|
#include <string>
|
|
@@ -35,15 +36,22 @@ struct LayoutAnimation {
|
|
|
35
36
|
LayoutAnimation &operator=(const LayoutAnimation &other) = default;
|
|
36
37
|
};
|
|
37
38
|
|
|
39
|
+
struct SurfaceContext {
|
|
40
|
+
mutable std::unordered_set<std::shared_ptr<MutationNode>> deadNodes;
|
|
41
|
+
};
|
|
42
|
+
|
|
38
43
|
struct LayoutAnimationsProxy
|
|
39
44
|
: public MountingOverrideDelegate,
|
|
45
|
+
public UIManagerAnimationDelegate,
|
|
40
46
|
public std::enable_shared_from_this<LayoutAnimationsProxy> {
|
|
41
47
|
mutable std::unordered_map<Tag, std::shared_ptr<Node>> nodeForTag_;
|
|
42
48
|
mutable std::unordered_map<Tag, LayoutAnimation> layoutAnimations_;
|
|
43
49
|
mutable std::recursive_mutex mutex;
|
|
44
50
|
mutable SurfaceManager surfaceManager;
|
|
45
|
-
mutable std::
|
|
51
|
+
mutable std::unordered_map<SurfaceId, SurfaceContext> surfaceContext_;
|
|
46
52
|
mutable std::unordered_map<Tag, int> leastRemoved;
|
|
53
|
+
mutable std::unordered_set<SurfaceId> surfacesToRemove_;
|
|
54
|
+
mutable std::vector<Tag> finishedAnimationTags_;
|
|
47
55
|
std::shared_ptr<LayoutAnimationsManager> layoutAnimationsManager_;
|
|
48
56
|
ContextContainer::Shared contextContainer_;
|
|
49
57
|
SharedComponentDescriptorRegistry componentDescriptorRegistry_;
|
|
@@ -76,16 +84,18 @@ struct LayoutAnimationsProxy
|
|
|
76
84
|
void maybeCancelAnimation(const int tag) const;
|
|
77
85
|
|
|
78
86
|
void parseRemoveMutations(
|
|
79
|
-
std::unordered_map<Tag,
|
|
87
|
+
std::unordered_map<Tag, Tag> &movedViews,
|
|
80
88
|
ShadowViewMutationList &mutations,
|
|
81
89
|
std::vector<std::shared_ptr<MutationNode>> &roots) const;
|
|
82
90
|
void handleRemovals(
|
|
83
91
|
ShadowViewMutationList &filteredMutations,
|
|
84
|
-
std::vector<std::shared_ptr<MutationNode>> &roots
|
|
92
|
+
std::vector<std::shared_ptr<MutationNode>> &roots,
|
|
93
|
+
std::unordered_set<std::shared_ptr<MutationNode>> &deadNodes,
|
|
94
|
+
bool shouldAnimate) const;
|
|
85
95
|
|
|
86
96
|
void handleUpdatesAndEnterings(
|
|
87
97
|
ShadowViewMutationList &filteredMutations,
|
|
88
|
-
const std::unordered_map<Tag,
|
|
98
|
+
const std::unordered_map<Tag, Tag> &movedViews,
|
|
89
99
|
ShadowViewMutationList &mutations,
|
|
90
100
|
const PropsParserContext &propsParserContext,
|
|
91
101
|
SurfaceId surfaceId) const;
|
|
@@ -140,6 +150,21 @@ struct LayoutAnimationsProxy
|
|
|
140
150
|
MountingTransaction::Number number,
|
|
141
151
|
const TransactionTelemetry &telemetry,
|
|
142
152
|
ShadowViewMutationList mutations) const override;
|
|
153
|
+
|
|
154
|
+
// UIManagerAnimationDelegate
|
|
155
|
+
|
|
156
|
+
void uiManagerDidConfigureNextLayoutAnimation(
|
|
157
|
+
jsi::Runtime &runtime,
|
|
158
|
+
const RawValue &config,
|
|
159
|
+
const jsi::Value &successCallbackValue,
|
|
160
|
+
const jsi::Value &failureCallbackValue) const override;
|
|
161
|
+
|
|
162
|
+
void setComponentDescriptorRegistry(const SharedComponentDescriptorRegistry &
|
|
163
|
+
componentDescriptorRegistry) override;
|
|
164
|
+
|
|
165
|
+
bool shouldAnimateFrame() const override;
|
|
166
|
+
|
|
167
|
+
void stopSurface(SurfaceId surfaceId) override;
|
|
143
168
|
};
|
|
144
169
|
|
|
145
170
|
} // namespace reanimated
|
|
@@ -136,11 +136,10 @@ static inline void updateLayoutMetrics(
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
static inline bool isRNSScreen(std::shared_ptr<MutationNode> node) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
!std::strcmp(
|
|
143
|
-
node->mutation.oldChildShadowView.componentName, "RNSScreen");
|
|
139
|
+
const auto &componentName = node->mutation.oldChildShadowView.componentName;
|
|
140
|
+
return !std::strcmp(componentName, "RNSScreenStack") ||
|
|
141
|
+
!std::strcmp(componentName, "RNSScreen") ||
|
|
142
|
+
!std::strcmp(componentName, "RNSModalScreen");
|
|
144
143
|
}
|
|
145
144
|
|
|
146
145
|
static inline bool hasLayoutChanged(const ShadowViewMutation &mutation) {
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
24
24
|
#include <react/renderer/scheduler/Scheduler.h>
|
|
25
25
|
#include <react/renderer/uimanager/UIManagerBinding.h>
|
|
26
|
-
#include <react/renderer/uimanager/primitives.h>
|
|
27
26
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
28
27
|
|
|
29
28
|
#include <functional>
|
|
@@ -37,6 +36,15 @@
|
|
|
37
36
|
|
|
38
37
|
namespace reanimated {
|
|
39
38
|
|
|
39
|
+
#if REACT_NATIVE_MINOR_VERSION >= 81
|
|
40
|
+
static inline std::shared_ptr<const ShadowNode> shadowNodeFromValue(
|
|
41
|
+
jsi::Runtime &rt,
|
|
42
|
+
const jsi::Value &shadowNodeWrapper) {
|
|
43
|
+
return Bridging<std::shared_ptr<const ShadowNode>>::fromJs(
|
|
44
|
+
rt, shadowNodeWrapper);
|
|
45
|
+
}
|
|
46
|
+
#endif
|
|
47
|
+
|
|
40
48
|
ReanimatedModuleProxy::ReanimatedModuleProxy(
|
|
41
49
|
const std::shared_ptr<WorkletsModuleProxy> &workletsModuleProxy,
|
|
42
50
|
jsi::Runtime &rnRuntime,
|
|
@@ -161,14 +169,20 @@ void ReanimatedModuleProxy::init(
|
|
|
161
169
|
if (!surfaceId) {
|
|
162
170
|
return;
|
|
163
171
|
}
|
|
164
|
-
strongThis->
|
|
165
|
-
*surfaceId, [](const ShadowTree &shadowTree) {
|
|
166
|
-
shadowTree.notifyDelegatesOfUpdates();
|
|
167
|
-
});
|
|
172
|
+
strongThis->layoutAnimationFlushRequests_.insert(*surfaceId);
|
|
168
173
|
};
|
|
169
174
|
|
|
175
|
+
auto requestLayoutAnimationRender = [weakThis = weak_from_this()](double) {
|
|
176
|
+
auto strongThis = weakThis.lock();
|
|
177
|
+
if (!strongThis) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
strongThis->layoutAnimationRenderRequested_ = false;
|
|
181
|
+
};
|
|
182
|
+
|
|
170
183
|
EndLayoutAnimationFunction endLayoutAnimation =
|
|
171
|
-
[weakThis = weak_from_this()](
|
|
184
|
+
[weakThis = weak_from_this(), requestLayoutAnimationRender](
|
|
185
|
+
int tag, bool shouldRemove) {
|
|
172
186
|
auto strongThis = weakThis.lock();
|
|
173
187
|
if (!strongThis) {
|
|
174
188
|
return;
|
|
@@ -176,14 +190,19 @@ void ReanimatedModuleProxy::init(
|
|
|
176
190
|
|
|
177
191
|
auto surfaceId = strongThis->layoutAnimationsProxy_->endLayoutAnimation(
|
|
178
192
|
tag, shouldRemove);
|
|
193
|
+
|
|
194
|
+
if (!strongThis->layoutAnimationRenderRequested_) {
|
|
195
|
+
strongThis->layoutAnimationRenderRequested_ = true;
|
|
196
|
+
// if an animation has duration 0, performOperations would not get
|
|
197
|
+
// called for it so we call requestRender to have it called in the
|
|
198
|
+
// next frame
|
|
199
|
+
strongThis->requestRender_(requestLayoutAnimationRender);
|
|
200
|
+
}
|
|
201
|
+
|
|
179
202
|
if (!surfaceId) {
|
|
180
203
|
return;
|
|
181
204
|
}
|
|
182
|
-
|
|
183
|
-
strongThis->uiManager_->getShadowTreeRegistry().visit(
|
|
184
|
-
*surfaceId, [](const ShadowTree &shadowTree) {
|
|
185
|
-
shadowTree.notifyDelegatesOfUpdates();
|
|
186
|
-
});
|
|
205
|
+
strongThis->layoutAnimationFlushRequests_.insert(*surfaceId);
|
|
187
206
|
};
|
|
188
207
|
|
|
189
208
|
auto obtainProp = [weakThis = weak_from_this()](
|
|
@@ -355,7 +374,7 @@ static inline std::string intColorToHex(const int val) {
|
|
|
355
374
|
std::string ReanimatedModuleProxy::obtainPropFromShadowNode(
|
|
356
375
|
jsi::Runtime &rt,
|
|
357
376
|
const std::string &propName,
|
|
358
|
-
const
|
|
377
|
+
const std::shared_ptr<const ShadowNode> &shadowNode) {
|
|
359
378
|
auto newestCloneOfShadowNode =
|
|
360
379
|
uiManager_->getNewestCloneOfShadowNode(*shadowNode);
|
|
361
380
|
|
|
@@ -700,13 +719,23 @@ void ReanimatedModuleProxy::updateProps(
|
|
|
700
719
|
}
|
|
701
720
|
|
|
702
721
|
void ReanimatedModuleProxy::performOperations() {
|
|
722
|
+
ReanimatedSystraceSection s("performOperations");
|
|
723
|
+
|
|
724
|
+
if (!layoutAnimationFlushRequests_.empty()) {
|
|
725
|
+
auto flushRequestsCopy = std::move(layoutAnimationFlushRequests_);
|
|
726
|
+
for (const auto surfaceId : flushRequestsCopy) {
|
|
727
|
+
uiManager_->getShadowTreeRegistry().visit(
|
|
728
|
+
surfaceId, [](const ShadowTree &shadowTree) {
|
|
729
|
+
shadowTree.notifyDelegatesOfUpdates();
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
703
734
|
if (operationsInBatch_.empty() && tagsToRemove_.empty()) {
|
|
704
735
|
// nothing to do
|
|
705
736
|
return;
|
|
706
737
|
}
|
|
707
738
|
|
|
708
|
-
ReanimatedSystraceSection s("performOperations");
|
|
709
|
-
|
|
710
739
|
auto copiedOperationsQueue = std::move(operationsInBatch_);
|
|
711
740
|
operationsInBatch_.clear();
|
|
712
741
|
|
|
@@ -809,7 +838,7 @@ void ReanimatedModuleProxy::dispatchCommand(
|
|
|
809
838
|
const jsi::Value &shadowNodeValue,
|
|
810
839
|
const jsi::Value &commandNameValue,
|
|
811
840
|
const jsi::Value &argsValue) {
|
|
812
|
-
|
|
841
|
+
const auto shadowNode = shadowNodeFromValue(rt, shadowNodeValue);
|
|
813
842
|
std::string commandName = stringFromValue(rt, commandNameValue);
|
|
814
843
|
folly::dynamic args = commandArgsFromValue(rt, argsValue);
|
|
815
844
|
const auto &scheduler = static_cast<Scheduler *>(uiManager_->getDelegate());
|
|
@@ -911,6 +940,7 @@ void ReanimatedModuleProxy::initializeLayoutAnimationsProxy() {
|
|
|
911
940
|
scheduler->getContextContainer(),
|
|
912
941
|
uiWorkletRuntime_->getJSIRuntime(),
|
|
913
942
|
workletsModuleProxy_->getUIScheduler());
|
|
943
|
+
uiManager_->setAnimationDelegate(layoutAnimationsProxy_.get());
|
|
914
944
|
}
|
|
915
945
|
}
|
|
916
946
|
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
24
24
|
|
|
25
25
|
#include <memory>
|
|
26
|
+
#include <set>
|
|
26
27
|
#include <string>
|
|
27
28
|
#include <unordered_set>
|
|
28
29
|
#include <utility>
|
|
@@ -150,7 +151,7 @@ class ReanimatedModuleProxy
|
|
|
150
151
|
std::string obtainPropFromShadowNode(
|
|
151
152
|
jsi::Runtime &rt,
|
|
152
153
|
const std::string &propName,
|
|
153
|
-
const
|
|
154
|
+
const std::shared_ptr<const ShadowNode> &shadowNode);
|
|
154
155
|
|
|
155
156
|
#ifdef IS_REANIMATED_EXAMPLE_APP
|
|
156
157
|
std::function<std::string()> createRegistriesLeakCheck();
|
|
@@ -233,6 +234,8 @@ class ReanimatedModuleProxy
|
|
|
233
234
|
std::shared_ptr<PropsRegistry> propsRegistry_;
|
|
234
235
|
std::shared_ptr<ReanimatedCommitHook> commitHook_;
|
|
235
236
|
std::shared_ptr<ReanimatedMountHook> mountHook_;
|
|
237
|
+
std::set<SurfaceId> layoutAnimationFlushRequests_;
|
|
238
|
+
bool layoutAnimationRenderRequested_;
|
|
236
239
|
|
|
237
240
|
std::vector<Tag> tagsToRemove_; // from `propsRegistry_`
|
|
238
241
|
#else
|
package/README.md
CHANGED
|
@@ -6,21 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
React Native Reanimated provides a more comprehensive,
|
|
8
8
|
low-level abstraction for the Animated library API on which to build,
|
|
9
|
-
allowing for much greater flexibility, especially when it comes to
|
|
9
|
+
allowing for much greater flexibility, especially when it comes to
|
|
10
10
|
gesture-based interactions.
|
|
11
11
|
|
|
12
|
-
### Nightly CI state
|
|
13
|
-
|
|
14
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/npm-reanimated-publish-nightly.yml)
|
|
15
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/reanimated-compatibility-check-nightly.yml)
|
|
16
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/static-framework-reanimated-build-check-nightly.yml)
|
|
17
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/react-native-nightly-reanimated-build-check-nightly.yml)
|
|
18
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/expo-devclient-build-check-nightly.yml)
|
|
19
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/reanimated-typescript-compatibility-test-nightly.yml)
|
|
20
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/V8-reanimated-build-check-nightly.yml)
|
|
21
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/windows-hosted-app-reanimated-build-check-nightly.yml)
|
|
22
|
-
[](https://github.com/software-mansion/react-native-reanimated/actions/workflows/url-validation-nightly.yml)
|
|
23
|
-
|
|
24
12
|
## Installation
|
|
25
13
|
|
|
26
14
|
Check out the [installation](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/#installation) section of our docs for the detailed installation instructions.
|
package/RNReanimated.podspec
CHANGED
|
@@ -81,7 +81,7 @@ Pod::Spec.new do |s|
|
|
|
81
81
|
'"$(PODS_ROOT)/Headers/Private/Yoga"',
|
|
82
82
|
].join(' '),
|
|
83
83
|
"FRAMEWORK_SEARCH_PATHS" => '"${PODS_CONFIGURATION_BUILD_DIR}/React-hermes"',
|
|
84
|
-
"CLANG_CXX_LANGUAGE_STANDARD" => "c++
|
|
84
|
+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
|
|
85
85
|
"GCC_PREPROCESSOR_DEFINITIONS[config=*Debug*]" => hermes_debug_hidden_flags,
|
|
86
86
|
"GCC_PREPROCESSOR_DEFINITIONS[config=*Release*]" => '$(inherited)',
|
|
87
87
|
}
|