Skip to content

Commit c46fd03

Browse files
Bartlomiej Bloniarzfacebook-github-bot
authored andcommitted
Use dynamic for updates in Animated with Animation Backend (#54872)
Summary: For the testing purposes, during the development of Animation Backend, we changed the way props are modified from animated, to use the AnimatedProps. As these would currently not benefit c++ Animated, this diff reverts that to use `folly::dynamic` again. Reviewed By: zeyap Differential Revision: D88743857
1 parent f9346fb commit c46fd03

6 files changed

Lines changed: 83 additions & 57 deletions

File tree

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

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,9 +1008,21 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
10081008
}
10091009

10101010
for (auto& [tag, props] : updateViewPropsDirect_) {
1011-
propsBuilder.storeDynamic(props);
1012-
mutations.push_back(
1013-
AnimationMutation{tag, nullptr, propsBuilder.get()});
1011+
auto familyIt = tagToShadowNodeFamily_.find(tag);
1012+
if (familyIt == tagToShadowNodeFamily_.end()) {
1013+
continue;
1014+
}
1015+
1016+
auto weakFamily = familyIt->second;
1017+
if (auto family = weakFamily.lock()) {
1018+
propsBuilder.storeDynamic(props);
1019+
mutations.batch.push_back(
1020+
AnimationMutation{
1021+
.tag = tag,
1022+
.family = family,
1023+
.props = propsBuilder.get(),
1024+
});
1025+
}
10141026
containsChange = true;
10151027
}
10161028
{
@@ -1020,22 +1032,12 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
10201032
if (familyIt == tagToShadowNodeFamily_.end()) {
10211033
continue;
10221034
}
1023-
if (auto family = familyIt->second.lock()) {
1024-
// C++ Animated produces props in the form of a folly::dynamic, so
1025-
// it wouldn't make sense to unpack it here. However, for the
1026-
// purposes of testing, we want to be able to use the statically
1027-
// typed AnimationMutation. At a later stage we will instead just
1028-
// pass the dynamic directly to propsBuilder and the new API could
1029-
// be used by 3rd party libraries or in the fututre by Animated.
1030-
if (props.find("width") != props.items().end()) {
1031-
propsBuilder.setWidth(
1032-
yoga::Style::SizeLength::points(props["width"].asDouble()));
1033-
}
1034-
if (props.find("height") != props.items().end()) {
1035-
propsBuilder.setHeight(
1036-
yoga::Style::SizeLength::points(props["height"].asDouble()));
1037-
}
1038-
mutations.push_back(
1035+
1036+
auto weakFamily = familyIt->second;
1037+
if (auto family = weakFamily.lock()) {
1038+
propsBuilder.storeDynamic(props);
1039+
mutations.hasLayoutUpdates = true;
1040+
mutations.batch.push_back(
10391041
AnimationMutation{
10401042
.tag = tag,
10411043
.family = family,
@@ -1075,13 +1077,21 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
10751077
isEventAnimationInProgress_ = false;
10761078

10771079
for (auto& [tag, props] : updateViewPropsDirect_) {
1078-
propsBuilder.storeDynamic(props);
1079-
mutations.push_back(
1080-
AnimationMutation{
1081-
.tag = tag,
1082-
.family = nullptr,
1083-
.props = propsBuilder.get(),
1084-
});
1080+
auto familyIt = tagToShadowNodeFamily_.find(tag);
1081+
if (familyIt == tagToShadowNodeFamily_.end()) {
1082+
continue;
1083+
}
1084+
1085+
auto weakFamily = familyIt->second;
1086+
if (auto family = weakFamily.lock()) {
1087+
propsBuilder.storeDynamic(props);
1088+
mutations.batch.push_back(
1089+
AnimationMutation{
1090+
.tag = tag,
1091+
.family = family,
1092+
.props = propsBuilder.get(),
1093+
});
1094+
}
10851095
}
10861096
{
10871097
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
@@ -1090,9 +1100,12 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
10901100
if (familyIt == tagToShadowNodeFamily_.end()) {
10911101
continue;
10921102
}
1093-
if (auto family = familyIt->second.lock()) {
1103+
1104+
auto weakFamily = familyIt->second;
1105+
if (auto family = weakFamily.lock()) {
10941106
propsBuilder.storeDynamic(props);
1095-
mutations.push_back(
1107+
mutations.hasLayoutUpdates = true;
1108+
mutations.batch.push_back(
10961109
AnimationMutation{
10971110
.tag = tag,
10981111
.family = family,

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ void AnimatedPropsRegistry::update(
3535
auto& snapshot = it->second;
3636
auto& viewProps = snapshot->props;
3737

38+
if (animatedProps.rawProps) {
39+
const auto& newRawProps = *animatedProps.rawProps;
40+
auto& currentRawProps = snapshot->rawProps;
41+
42+
if (currentRawProps) {
43+
auto newRawPropsDynamic = newRawProps.toDynamic();
44+
currentRawProps->merge_patch(newRawPropsDynamic);
45+
} else {
46+
currentRawProps =
47+
std::make_unique<folly::dynamic>(newRawProps.toDynamic());
48+
}
49+
}
3850
for (const auto& animatedProp : animatedProps.props) {
3951
snapshot->propNames.insert(animatedProp->propName);
4052
cloneProp(viewProps, *animatedProp);

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimatedPropsRegistry.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace facebook::react {
1919
struct PropsSnapshot {
2020
BaseViewProps props;
2121
std::unordered_set<PropName> propNames;
22+
std::unique_ptr<folly::dynamic> rawProps;
2223
};
2324

2425
struct SurfaceContext {

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include "AnimationBackend.h"
9+
#include <react/debug/react_native_assert.h>
910
#include <react/renderer/animationbackend/AnimatedPropsSerializer.h>
1011
#include <react/renderer/graphics/Color.h>
1112
#include <chrono>
@@ -49,20 +50,6 @@ static inline Props::Shared cloneProps(
4950
return newProps;
5051
}
5152

52-
static inline bool mutationHasLayoutUpdates(
53-
facebook::react::AnimationMutation& mutation) {
54-
for (auto& animatedProp : mutation.props.props) {
55-
// TODO: there should also be a check for the dynamic part
56-
if (animatedProp->propName == WIDTH || animatedProp->propName == HEIGHT ||
57-
animatedProp->propName == FLEX || animatedProp->propName == MARGIN ||
58-
animatedProp->propName == PADDING ||
59-
animatedProp->propName == POSITION) {
60-
return true;
61-
}
62-
}
63-
return false;
64-
}
65-
6653
AnimationBackend::AnimationBackend(
6754
StartOnRenderCallback&& startOnRenderCallback,
6855
StopOnRenderCallback&& stopOnRenderCallback,
@@ -81,27 +68,31 @@ void AnimationBackend::onAnimationFrame(double timestamp) {
8168
std::unordered_map<Tag, AnimatedProps> synchronousUpdates;
8269
std::unordered_map<SurfaceId, SurfaceUpdates> surfaceUpdates;
8370

84-
bool hasAnyLayoutUpdates = false;
8571
for (auto& callback : callbacks) {
8672
auto muatations = callback(static_cast<float>(timestamp));
87-
for (auto& mutation : muatations) {
88-
hasAnyLayoutUpdates |= mutationHasLayoutUpdates(mutation);
89-
const auto family = mutation.family;
90-
if (family != nullptr) {
73+
if (muatations.hasLayoutUpdates) {
74+
for (auto& mutation : muatations.batch) {
75+
const auto family = mutation.family;
76+
react_native_assert(family != nullptr);
77+
9178
auto& [families, updates] = surfaceUpdates[family->getSurfaceId()];
9279
families.insert(family.get());
9380
updates[mutation.tag] = std::move(mutation.props);
94-
} else {
81+
}
82+
} else {
83+
for (auto& mutation : muatations.batch) {
9584
synchronousUpdates[mutation.tag] = std::move(mutation.props);
9685
}
9786
}
9887
}
9988

10089
animatedPropsRegistry_->update(surfaceUpdates);
10190

102-
if (hasAnyLayoutUpdates) {
91+
if (!surfaceUpdates.empty()) {
10392
commitUpdates(surfaceUpdates);
104-
} else {
93+
}
94+
95+
if (!synchronousUpdates.empty()) {
10596
synchronouslyUpdateProps(synchronousUpdates);
10697
}
10798
}
@@ -167,8 +158,8 @@ void AnimationBackend::commitUpdates(
167158
void AnimationBackend::synchronouslyUpdateProps(
168159
const std::unordered_map<Tag, AnimatedProps>& updates) {
169160
for (auto& [tag, animatedProps] : updates) {
170-
// TODO: We shouldn't repack it into dynamic, but for that a rewrite of
171-
// directManipulationCallback_ is needed
161+
// TODO: We shouldn't repack it into dynamic, but for that a rewrite
162+
// of directManipulationCallback_ is needed
172163
auto dyn = animationbackend::packAnimatedProps(animatedProps);
173164
directManipulationCallback_(tag, std::move(dyn));
174165
}

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ struct AnimationMutation {
3838
AnimatedProps props;
3939
};
4040

41-
using AnimationMutations = std::vector<AnimationMutation>;
41+
struct AnimationMutations {
42+
std::vector<AnimationMutation> batch;
43+
bool hasLayoutUpdates{false};
44+
};
4245

4346
class AnimationBackend : public UIManagerAnimationBackend {
4447
public:

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackendCommitHook.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,19 @@ RootShadowNode::Unshared AnimationBackendCommitHook::shadowTreeWillCommit(
4343
if (surfaceFamilies.contains(&shadowNode.getFamily()) &&
4444
updates.contains(shadowNode.getTag())) {
4545
auto& snapshot = updates.at(shadowNode.getTag());
46-
if (!snapshot->propNames.empty()) {
46+
if (!snapshot->propNames.empty() || snapshot->rawProps) {
4747
PropsParserContext propsParserContext{
4848
shadowNode.getSurfaceId(),
4949
*shadowNode.getContextContainer()};
50-
51-
newProps = shadowNode.getComponentDescriptor().cloneProps(
52-
propsParserContext, shadowNode.getProps(), {});
50+
if (snapshot->rawProps) {
51+
newProps = shadowNode.getComponentDescriptor().cloneProps(
52+
propsParserContext,
53+
shadowNode.getProps(),
54+
RawProps(*snapshot->rawProps));
55+
} else {
56+
newProps = shadowNode.getComponentDescriptor().cloneProps(
57+
propsParserContext, shadowNode.getProps(), {});
58+
}
5359
viewProps = std::const_pointer_cast<BaseViewProps>(
5460
std::static_pointer_cast<const BaseViewProps>(newProps));
5561
}

0 commit comments

Comments
 (0)