Skip to content

Commit 9227dd7

Browse files
Bartlomiej Bloniarzmeta-codesync[bot]
authored andcommitted
Move ShadowNodeFamily to PropsAnimatedNode (#54879)
Summary: Pull Request resolved: #54879 This diff is a part of the process of getting the Animated-itest to work with Animation Backend. During testing I found that sometimes the disconnect method would cleanup `tagToShadowNodeFamily_` when there were more than one PropsAnimatedNode for a view, so we would wrongly skip an animation. By storing the family pointer on the props node we can avoid that. Differential Revision: D89042963
1 parent 7cb9750 commit 9227dd7

File tree

4 files changed

+99
-96
lines changed

4 files changed

+99
-96
lines changed

packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp

Lines changed: 64 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,7 @@ void NativeAnimatedNodesManager::connectAnimatedNodeToShadowNodeFamily(
244244
react_native_assert(propsNodeTag);
245245
auto node = getAnimatedNode<PropsAnimatedNode>(propsNodeTag);
246246
if (node != nullptr && family != nullptr) {
247-
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
248-
tagToShadowNodeFamily_[family->getTag()] = family;
247+
node->connectToShadowNodeFamily(family);
249248
} else {
250249
LOG(WARNING)
251250
<< "Cannot ConnectAnimatedNodeToShadowNodeFamily, animated node has to be props type";
@@ -265,10 +264,6 @@ void NativeAnimatedNodesManager::disconnectAnimatedNodeFromView(
265264
std::lock_guard<std::mutex> lock(connectedAnimatedNodesMutex_);
266265
connectedAnimatedNodes_.erase(viewTag);
267266
}
268-
{
269-
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
270-
tagToShadowNodeFamily_.erase(viewTag);
271-
}
272267
updatedNodeTags_.insert(node->tag());
273268

274269
onManagedPropsRemoved(viewTag);
@@ -907,13 +902,14 @@ void NativeAnimatedNodesManager::schedulePropsCommit(
907902
Tag viewTag,
908903
const folly::dynamic& props,
909904
bool layoutStyleUpdated,
910-
bool forceFabricCommit) noexcept {
905+
bool forceFabricCommit,
906+
ShadowNodeFamily::Weak shadowNodeFamily) noexcept {
911907
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
912-
if (layoutStyleUpdated) {
913-
mergeObjects(updateViewProps_[viewTag], props);
914-
} else {
915-
mergeObjects(updateViewPropsDirect_[viewTag], props);
916-
}
908+
auto& current = layoutStyleUpdated
909+
? updateViewPropsForBackend_[viewTag]
910+
: updateViewPropsDirectForBackend_[viewTag];
911+
current.first = std::move(shadowNodeFamily);
912+
mergeObjects(current.second, props);
917913
return;
918914
}
919915

@@ -1007,49 +1003,39 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
10071003
}
10081004
}
10091005

1010-
{
1011-
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
1012-
for (auto& [tag, props] : updateViewPropsDirect_) {
1013-
auto familyIt = tagToShadowNodeFamily_.find(tag);
1014-
if (familyIt == tagToShadowNodeFamily_.end()) {
1015-
continue;
1016-
}
1017-
1018-
auto weakFamily = familyIt->second;
1019-
if (auto family = weakFamily.lock()) {
1020-
propsBuilder.storeDynamic(props);
1021-
mutations.batch.push_back(
1022-
AnimationMutation{
1023-
.tag = tag,
1024-
.family = family,
1025-
.props = propsBuilder.get(),
1026-
});
1027-
}
1028-
containsChange = true;
1006+
for (auto& [tag, update] : updateViewPropsDirectForBackend_) {
1007+
auto weakFamily = update.first;
1008+
1009+
if (auto family = weakFamily.lock()) {
1010+
propsBuilder.storeDynamic(update.second);
1011+
mutations.batch.push_back(
1012+
AnimationMutation{
1013+
.tag = tag,
1014+
.family = family,
1015+
.props = propsBuilder.get(),
1016+
});
10291017
}
1030-
for (auto& [tag, props] : updateViewProps_) {
1031-
auto familyIt = tagToShadowNodeFamily_.find(tag);
1032-
if (familyIt == tagToShadowNodeFamily_.end()) {
1033-
continue;
1034-
}
1035-
1036-
auto weakFamily = familyIt->second;
1037-
if (auto family = weakFamily.lock()) {
1038-
propsBuilder.storeDynamic(props);
1039-
mutations.batch.push_back(
1040-
AnimationMutation{
1041-
.tag = tag,
1042-
.family = family,
1043-
.props = propsBuilder.get(),
1044-
.hasLayoutUpdates = true,
1045-
});
1046-
}
1047-
containsChange = true;
1018+
containsChange = true;
1019+
}
1020+
for (auto& [tag, update] : updateViewPropsForBackend_) {
1021+
auto weakFamily = update.first;
1022+
1023+
if (auto family = weakFamily.lock()) {
1024+
propsBuilder.storeDynamic(update.second);
1025+
mutations.batch.push_back(
1026+
AnimationMutation{
1027+
.tag = tag,
1028+
.family = family,
1029+
.props = propsBuilder.get(),
1030+
.hasLayoutUpdates = true,
1031+
});
10481032
}
1033+
containsChange = true;
10491034
}
1035+
10501036
if (containsChange) {
1051-
updateViewPropsDirect_.clear();
1052-
updateViewProps_.clear();
1037+
updateViewPropsDirectForBackend_.clear();
1038+
updateViewPropsForBackend_.clear();
10531039
}
10541040
}
10551041

@@ -1076,46 +1062,36 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
10761062

10771063
isEventAnimationInProgress_ = false;
10781064

1079-
{
1080-
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
1081-
for (auto& [tag, props] : updateViewPropsDirect_) {
1082-
auto familyIt = tagToShadowNodeFamily_.find(tag);
1083-
if (familyIt == tagToShadowNodeFamily_.end()) {
1084-
continue;
1085-
}
1086-
1087-
auto weakFamily = familyIt->second;
1088-
if (auto family = weakFamily.lock()) {
1089-
propsBuilder.storeDynamic(props);
1090-
mutations.batch.push_back(
1091-
AnimationMutation{
1092-
.tag = tag,
1093-
.family = family,
1094-
.props = propsBuilder.get(),
1095-
});
1096-
}
1065+
for (auto& [tag, update] : updateViewPropsDirectForBackend_) {
1066+
auto weakFamily = update.first;
1067+
1068+
if (auto family = weakFamily.lock()) {
1069+
propsBuilder.storeDynamic(update.second);
1070+
mutations.batch.push_back(
1071+
AnimationMutation{
1072+
.tag = tag,
1073+
.family = family,
1074+
.props = propsBuilder.get(),
1075+
});
10971076
}
1098-
for (auto& [tag, props] : updateViewProps_) {
1099-
auto familyIt = tagToShadowNodeFamily_.find(tag);
1100-
if (familyIt == tagToShadowNodeFamily_.end()) {
1101-
continue;
1102-
}
1103-
1104-
auto weakFamily = familyIt->second;
1105-
if (auto family = weakFamily.lock()) {
1106-
propsBuilder.storeDynamic(props);
1107-
mutations.batch.push_back(
1108-
AnimationMutation{
1109-
.tag = tag,
1110-
.family = family,
1111-
.props = propsBuilder.get(),
1112-
.hasLayoutUpdates = true,
1113-
});
1114-
}
1077+
}
1078+
for (auto& [tag, update] : updateViewPropsForBackend_) {
1079+
auto weakFamily = update.first;
1080+
1081+
if (auto family = weakFamily.lock()) {
1082+
propsBuilder.storeDynamic(update.second);
1083+
mutations.batch.push_back(
1084+
AnimationMutation{
1085+
.tag = tag,
1086+
.family = family,
1087+
.props = propsBuilder.get(),
1088+
.hasLayoutUpdates = true,
1089+
});
11151090
}
11161091
}
1117-
updateViewProps_.clear();
1118-
updateViewPropsDirect_.clear();
1092+
1093+
updateViewPropsForBackend_.clear();
1094+
updateViewPropsDirectForBackend_.clear();
11191095
}
11201096
} else {
11211097
// There is no active animation. Stop the render callback.

packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ class NativeAnimatedNodesManager {
153153
Tag viewTag,
154154
const folly::dynamic &props,
155155
bool layoutStyleUpdated,
156-
bool forceFabricCommit) noexcept;
156+
bool forceFabricCommit,
157+
ShadowNodeFamily::Weak shadowNodeFamily = {}) noexcept;
157158

158159
/**
159160
* Commits all pending animated property updates to their respective views.
@@ -260,9 +261,8 @@ class NativeAnimatedNodesManager {
260261

261262
std::unordered_map<Tag, folly::dynamic> updateViewProps_{};
262263
std::unordered_map<Tag, folly::dynamic> updateViewPropsDirect_{};
263-
264-
mutable std::mutex tagToShadowNodeFamilyMutex_;
265-
std::unordered_map<Tag, std::weak_ptr<const ShadowNodeFamily>> tagToShadowNodeFamily_{};
264+
std::unordered_map<Tag, std::pair<ShadowNodeFamily::Weak, folly::dynamic>> updateViewPropsForBackend_{};
265+
std::unordered_map<Tag, std::pair<ShadowNodeFamily::Weak, folly::dynamic>> updateViewPropsDirectForBackend_{};
266266

267267
/*
268268
* Sometimes a view is not longer connected to a PropsAnimatedNode, but

packages/react-native/ReactCommon/react/renderer/animated/nodes/PropsAnimatedNode.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "PropsAnimatedNode.h"
1313

1414
#include <react/debug/react_native_assert.h>
15+
#include <react/featureflags/ReactNativeFeatureFlags.h>
1516
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
1617
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
1718
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
@@ -55,6 +56,11 @@ PropsAnimatedNode::PropsAnimatedNode(
5556
}
5657
}
5758

59+
void PropsAnimatedNode::connectToShadowNodeFamily(
60+
ShadowNodeFamily::Weak shadowNodeFamily) {
61+
shadowNodeFamily_ = std::move(shadowNodeFamily);
62+
}
63+
5864
void PropsAnimatedNode::connectToView(Tag viewTag) {
5965
react_native_assert(
6066
connectedViewTag_ == animated::undefinedAnimatedNodeIdentifier &&
@@ -67,15 +73,25 @@ void PropsAnimatedNode::disconnectFromView(Tag viewTag) {
6773
connectedViewTag_ == viewTag &&
6874
"Attempting to disconnect view that has not been connected with the given animated node.");
6975
connectedViewTag_ = animated::undefinedAnimatedNodeIdentifier;
76+
shadowNodeFamily_.reset();
7077
}
7178

7279
// restore the value to whatever the value was on the ShadowNode instead of in
7380
// the View hierarchy
7481
void PropsAnimatedNode::restoreDefaultValues() {
7582
// If node is already disconnected from View, we cannot restore default values
7683
if (connectedViewTag_ != animated::undefinedAnimatedNodeIdentifier) {
77-
manager_->schedulePropsCommit(
78-
connectedViewTag_, folly::dynamic::object(), false, false);
84+
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
85+
manager_->schedulePropsCommit(
86+
connectedViewTag_,
87+
folly::dynamic::object(),
88+
false,
89+
false,
90+
shadowNodeFamily_);
91+
} else {
92+
manager_->schedulePropsCommit(
93+
connectedViewTag_, folly::dynamic::object(), false, false);
94+
}
7995
}
8096
}
8197

@@ -147,8 +163,17 @@ void PropsAnimatedNode::update(bool forceFabricCommit) {
147163

148164
layoutStyleUpdated_ = isLayoutStyleUpdated(getConfig()["props"], *manager_);
149165

150-
manager_->schedulePropsCommit(
151-
connectedViewTag_, props_, layoutStyleUpdated_, forceFabricCommit);
166+
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
167+
manager_->schedulePropsCommit(
168+
connectedViewTag_,
169+
props_,
170+
layoutStyleUpdated_,
171+
forceFabricCommit,
172+
shadowNodeFamily_);
173+
} else {
174+
manager_->schedulePropsCommit(
175+
connectedViewTag_, props_, layoutStyleUpdated_, forceFabricCommit);
176+
}
152177
}
153178

154179
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/animated/nodes/PropsAnimatedNode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace facebook::react {
2121
class PropsAnimatedNode final : public AnimatedNode {
2222
public:
2323
PropsAnimatedNode(Tag tag, const folly::dynamic &config, NativeAnimatedNodesManager &manager);
24+
void connectToShadowNodeFamily(ShadowNodeFamily::Weak shadowNodeFamily);
2425
void connectToView(Tag viewTag);
2526
void disconnectFromView(Tag viewTag);
2627
void restoreDefaultValues();
@@ -51,6 +52,7 @@ class PropsAnimatedNode final : public AnimatedNode {
5152
bool layoutStyleUpdated_{false};
5253

5354
Tag connectedViewTag_{animated::undefinedAnimatedNodeIdentifier};
55+
ShadowNodeFamily::Weak shadowNodeFamily_;
5456

5557
// Needed for PlatformColor resolver
5658
SurfaceId connectedRootTag_{animated::undefinedAnimatedNodeIdentifier};

0 commit comments

Comments
 (0)