Skip to content

Commit 84e408c

Browse files
Bartlomiej Bloniarzmeta-codesync[bot]
authored andcommitted
Use dynamic for updates in Animated with Animation Backend (#54872)
Summary: Pull Request resolved: #54872 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. # Changelog [General] [Changed] - C++ animated now passes the calculated `folly::dynamic` directly to the backend, without repacking it into `AnimatedProp` Reviewed By: zeyap Differential Revision: D88743857 fbshipit-source-id: a9f715730e78f4278e95a2df0aa3b6d2628f1651
1 parent 62c567f commit 84e408c

6 files changed

Lines changed: 83 additions & 54 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 & 21 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>
@@ -60,17 +61,6 @@ static inline Props::Shared cloneProps(
6061
return newProps;
6162
}
6263

63-
static inline bool mutationHasLayoutUpdates(
64-
facebook::react::AnimationMutation& mutation) {
65-
for (auto& animatedProp : mutation.props.props) {
66-
// TODO: there should also be a check for the dynamic part
67-
if (layoutProps.contains(animatedProp->propName)) {
68-
return true;
69-
}
70-
}
71-
return false;
72-
}
73-
7464
AnimationBackend::AnimationBackend(
7565
StartOnRenderCallback&& startOnRenderCallback,
7666
StopOnRenderCallback&& stopOnRenderCallback,
@@ -89,27 +79,31 @@ void AnimationBackend::onAnimationFrame(double timestamp) {
8979
std::unordered_map<Tag, AnimatedProps> synchronousUpdates;
9080
std::unordered_map<SurfaceId, SurfaceUpdates> surfaceUpdates;
9181

92-
bool hasAnyLayoutUpdates = false;
9382
for (auto& callback : callbacks) {
9483
auto muatations = callback(static_cast<float>(timestamp));
95-
for (auto& mutation : muatations) {
96-
hasAnyLayoutUpdates |= mutationHasLayoutUpdates(mutation);
97-
const auto family = mutation.family;
98-
if (family != nullptr) {
84+
if (muatations.hasLayoutUpdates) {
85+
for (auto& mutation : muatations.batch) {
86+
const auto family = mutation.family;
87+
react_native_assert(family != nullptr);
88+
9989
auto& [families, updates] = surfaceUpdates[family->getSurfaceId()];
10090
families.insert(family.get());
10191
updates[mutation.tag] = std::move(mutation.props);
102-
} else {
92+
}
93+
} else {
94+
for (auto& mutation : muatations.batch) {
10395
synchronousUpdates[mutation.tag] = std::move(mutation.props);
10496
}
10597
}
10698
}
10799

108100
animatedPropsRegistry_->update(surfaceUpdates);
109101

110-
if (hasAnyLayoutUpdates) {
102+
if (!surfaceUpdates.empty()) {
111103
commitUpdates(surfaceUpdates);
112-
} else {
104+
}
105+
106+
if (!synchronousUpdates.empty()) {
113107
synchronouslyUpdateProps(synchronousUpdates);
114108
}
115109
}
@@ -175,8 +169,8 @@ void AnimationBackend::commitUpdates(
175169
void AnimationBackend::synchronouslyUpdateProps(
176170
const std::unordered_map<Tag, AnimatedProps>& updates) {
177171
for (auto& [tag, animatedProps] : updates) {
178-
// TODO: We shouldn't repack it into dynamic, but for that a rewrite of
179-
// directManipulationCallback_ is needed
172+
// TODO: We shouldn't repack it into dynamic, but for that a rewrite
173+
// of directManipulationCallback_ is needed
180174
auto dyn = animationbackend::packAnimatedProps(animatedProps);
181175
directManipulationCallback_(tag, std::move(dyn));
182176
}

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)