Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,6 @@ test('animated opacity', () => {
_opacityAnimation?.stop();
});

// TODO: T246961305 rendered output should be <rn-view opacity="0" /> at this point
expect(root.getRenderedOutput({props: ['opacity']}).toJSX()).toEqual(
<rn-view />,
);

// Re-render
Fantom.runTask(() => {
root.render(<MyApp />);
});

expect(root.getRenderedOutput({props: ['opacity']}).toJSX()).toEqual(
<rn-view opacity="0" />,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,7 @@ void NativeAnimatedNodesManager::connectAnimatedNodeToShadowNodeFamily(
react_native_assert(propsNodeTag);
auto node = getAnimatedNode<PropsAnimatedNode>(propsNodeTag);
if (node != nullptr && family != nullptr) {
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
tagToShadowNodeFamily_[family->getTag()] = family;
node->connectToShadowNodeFamily(family);
} else {
LOG(WARNING)
<< "Cannot ConnectAnimatedNodeToShadowNodeFamily, animated node has to be props type";
Expand All @@ -261,14 +260,13 @@ void NativeAnimatedNodesManager::disconnectAnimatedNodeFromView(
auto node = getAnimatedNode<PropsAnimatedNode>(propsNodeTag);
if (node != nullptr) {
node->disconnectFromView(viewTag);
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
node->disconnectFromShadowNodeFamily();
}
{
std::lock_guard<std::mutex> lock(connectedAnimatedNodesMutex_);
connectedAnimatedNodes_.erase(viewTag);
}
{
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
tagToShadowNodeFamily_.erase(viewTag);
}
updatedNodeTags_.insert(node->tag());

onManagedPropsRemoved(viewTag);
Expand Down Expand Up @@ -907,13 +905,17 @@ void NativeAnimatedNodesManager::schedulePropsCommit(
Tag viewTag,
const folly::dynamic& props,
bool layoutStyleUpdated,
bool forceFabricCommit) noexcept {
bool forceFabricCommit,
ShadowNodeFamily::Weak shadowNodeFamily) noexcept {
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
if (layoutStyleUpdated) {
mergeObjects(updateViewProps_[viewTag], props);
} else {
mergeObjects(updateViewPropsDirect_[viewTag], props);
if (forceFabricCommit) {
shouldRequestAsyncFlush_.insert(viewTag);
}
auto& current = layoutStyleUpdated
? updateViewPropsForBackend_[viewTag]
: updateViewPropsDirectForBackend_[viewTag];
current.first = std::move(shadowNodeFamily);
mergeObjects(current.second, props);
return;
}

Expand All @@ -940,6 +942,32 @@ void NativeAnimatedNodesManager::schedulePropsCommit(
}

#ifdef RN_USE_ANIMATION_BACKEND

void NativeAnimatedNodesManager::insertMutations(
std::unordered_map<Tag, std::pair<ShadowNodeFamily::Weak, folly::dynamic>>&
updates,
AnimationMutations& mutations,
AnimatedPropsBuilder& propsBuilder,
bool hasLayoutUpdates) {
for (auto& [tag, update] : updates) {
auto weakFamily = update.first;

if (auto family = weakFamily.lock()) {
propsBuilder.storeDynamic(update.second);
if (shouldRequestAsyncFlush_.contains(tag)) {
mutations.asyncFlushSurfaces.insert(family->getSurfaceId());
}
mutations.batch.push_back(
AnimationMutation{
.tag = tag,
.family = family,
.props = propsBuilder.get(),
.hasLayoutUpdates = hasLayoutUpdates,
});
}
}
}

AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
if (!ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
return {};
Expand All @@ -962,7 +990,7 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
task();
}

AnimationMutations mutations;
AnimationMutations mutations{};

// Step through the animation loop
if (isAnimationUpdateNeeded()) {
Expand Down Expand Up @@ -1007,49 +1035,18 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {
}
}

{
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
for (auto& [tag, props] : updateViewPropsDirect_) {
auto familyIt = tagToShadowNodeFamily_.find(tag);
if (familyIt == tagToShadowNodeFamily_.end()) {
continue;
}
insertMutations(
updateViewPropsDirectForBackend_, mutations, propsBuilder);

auto weakFamily = familyIt->second;
if (auto family = weakFamily.lock()) {
propsBuilder.storeDynamic(props);
mutations.batch.push_back(
AnimationMutation{
.tag = tag,
.family = family,
.props = propsBuilder.get(),
});
}
containsChange = true;
}
for (auto& [tag, props] : updateViewProps_) {
auto familyIt = tagToShadowNodeFamily_.find(tag);
if (familyIt == tagToShadowNodeFamily_.end()) {
continue;
}
insertMutations(
updateViewPropsForBackend_, mutations, propsBuilder, true);

containsChange = !updateViewPropsForBackend_.empty() ||
!updateViewPropsDirectForBackend_.empty();

auto weakFamily = familyIt->second;
if (auto family = weakFamily.lock()) {
propsBuilder.storeDynamic(props);
mutations.batch.push_back(
AnimationMutation{
.tag = tag,
.family = family,
.props = propsBuilder.get(),
.hasLayoutUpdates = true,
});
}
containsChange = true;
}
}
if (containsChange) {
updateViewPropsDirect_.clear();
updateViewProps_.clear();
updateViewPropsDirectForBackend_.clear();
updateViewPropsForBackend_.clear();
}
}

Expand All @@ -1076,51 +1073,20 @@ AnimationMutations NativeAnimatedNodesManager::pullAnimationMutations() {

isEventAnimationInProgress_ = false;

{
std::lock_guard<std::mutex> lock(tagToShadowNodeFamilyMutex_);
for (auto& [tag, props] : updateViewPropsDirect_) {
auto familyIt = tagToShadowNodeFamily_.find(tag);
if (familyIt == tagToShadowNodeFamily_.end()) {
continue;
}
insertMutations(
updateViewPropsDirectForBackend_, mutations, propsBuilder);

auto weakFamily = familyIt->second;
if (auto family = weakFamily.lock()) {
propsBuilder.storeDynamic(props);
mutations.batch.push_back(
AnimationMutation{
.tag = tag,
.family = family,
.props = propsBuilder.get(),
});
}
}
for (auto& [tag, props] : updateViewProps_) {
auto familyIt = tagToShadowNodeFamily_.find(tag);
if (familyIt == tagToShadowNodeFamily_.end()) {
continue;
}
insertMutations(
updateViewPropsForBackend_, mutations, propsBuilder, true);

auto weakFamily = familyIt->second;
if (auto family = weakFamily.lock()) {
propsBuilder.storeDynamic(props);
mutations.batch.push_back(
AnimationMutation{
.tag = tag,
.family = family,
.props = propsBuilder.get(),
.hasLayoutUpdates = true,
});
}
}
}
updateViewProps_.clear();
updateViewPropsDirect_.clear();
updateViewPropsForBackend_.clear();
updateViewPropsDirectForBackend_.clear();
}
} else {
// There is no active animation. Stop the render callback.
stopRenderCallbackIfNeeded(false);
}
shouldRequestAsyncFlush_.clear();
return mutations;
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ class NativeAnimatedNodesManager {
void setAnimatedNodeOffset(Tag tag, double offset);

#ifdef RN_USE_ANIMATION_BACKEND
void insertMutations(
std::unordered_map<Tag, std::pair<ShadowNodeFamily::Weak, folly::dynamic>> &updates,
AnimationMutations &mutations,
AnimatedPropsBuilder &propsBuilder,
bool hasLayoutUpdates = false);
AnimationMutations pullAnimationMutations();
#endif

Expand Down Expand Up @@ -153,7 +158,8 @@ class NativeAnimatedNodesManager {
Tag viewTag,
const folly::dynamic &props,
bool layoutStyleUpdated,
bool forceFabricCommit) noexcept;
bool forceFabricCommit,
ShadowNodeFamily::Weak shadowNodeFamily = {}) noexcept;

/**
* Commits all pending animated property updates to their respective views.
Expand Down Expand Up @@ -260,10 +266,9 @@ class NativeAnimatedNodesManager {

std::unordered_map<Tag, folly::dynamic> updateViewProps_{};
std::unordered_map<Tag, folly::dynamic> updateViewPropsDirect_{};

mutable std::mutex tagToShadowNodeFamilyMutex_;
std::unordered_map<Tag, std::weak_ptr<const ShadowNodeFamily>> tagToShadowNodeFamily_{};

std::unordered_map<Tag, std::pair<ShadowNodeFamily::Weak, folly::dynamic>> updateViewPropsForBackend_{};
std::unordered_map<Tag, std::pair<ShadowNodeFamily::Weak, folly::dynamic>> updateViewPropsDirectForBackend_{};
std::unordered_set<Tag> shouldRequestAsyncFlush_{};
/*
* Sometimes a view is not longer connected to a PropsAnimatedNode, but
* NativeAnimated has previously changed the view's props via direct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
std::move(stopOnRenderCallback_),
std::move(directManipulationCallback),
std::move(fabricCommitCallback),
uiManager);
uiManager,
jsInvoker);

nativeAnimatedNodesManager_ =
std::make_shared<NativeAnimatedNodesManager>(animationBackend_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "PropsAnimatedNode.h"

#include <react/debug/react_native_assert.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
Expand Down Expand Up @@ -55,6 +56,15 @@ PropsAnimatedNode::PropsAnimatedNode(
}
}

void PropsAnimatedNode::connectToShadowNodeFamily(
ShadowNodeFamily::Weak shadowNodeFamily) {
shadowNodeFamily_ = std::move(shadowNodeFamily);
}

void PropsAnimatedNode::disconnectFromShadowNodeFamily() {
shadowNodeFamily_.reset();
}

void PropsAnimatedNode::connectToView(Tag viewTag) {
react_native_assert(
connectedViewTag_ == animated::undefinedAnimatedNodeIdentifier &&
Expand All @@ -74,8 +84,17 @@ void PropsAnimatedNode::disconnectFromView(Tag viewTag) {
void PropsAnimatedNode::restoreDefaultValues() {
// If node is already disconnected from View, we cannot restore default values
if (connectedViewTag_ != animated::undefinedAnimatedNodeIdentifier) {
manager_->schedulePropsCommit(
connectedViewTag_, folly::dynamic::object(), false, false);
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
manager_->schedulePropsCommit(
connectedViewTag_,
folly::dynamic::object(),
false,
false,
shadowNodeFamily_);
} else {
manager_->schedulePropsCommit(
connectedViewTag_, folly::dynamic::object(), false, false);
}
}
}

Expand Down Expand Up @@ -147,8 +166,17 @@ void PropsAnimatedNode::update(bool forceFabricCommit) {

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

manager_->schedulePropsCommit(
connectedViewTag_, props_, layoutStyleUpdated_, forceFabricCommit);
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
manager_->schedulePropsCommit(
connectedViewTag_,
props_,
layoutStyleUpdated_,
forceFabricCommit,
shadowNodeFamily_);
} else {
manager_->schedulePropsCommit(
connectedViewTag_, props_, layoutStyleUpdated_, forceFabricCommit);
}
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ namespace facebook::react {
class PropsAnimatedNode final : public AnimatedNode {
public:
PropsAnimatedNode(Tag tag, const folly::dynamic &config, NativeAnimatedNodesManager &manager);

// Only called when `useSharedAnimatedBackend`==true
void connectToShadowNodeFamily(ShadowNodeFamily::Weak shadowNodeFamily);
void disconnectFromShadowNodeFamily();

void connectToView(Tag viewTag);
void disconnectFromView(Tag viewTag);
void restoreDefaultValues();
Expand Down Expand Up @@ -51,6 +56,7 @@ class PropsAnimatedNode final : public AnimatedNode {
bool layoutStyleUpdated_{false};

Tag connectedViewTag_{animated::undefinedAnimatedNodeIdentifier};
ShadowNodeFamily::Weak shadowNodeFamily_;

// Needed for PlatformColor resolver
SurfaceId connectedRootTag_{animated::undefinedAnimatedNodeIdentifier};
Expand Down
Loading