remove use of shared_ptr from AnimatedNode (#51588)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51588

changelog: [internal]

AnimatedNode never outlive NativeAnimatedNodesManager. We can safely use raw pointer here instead of shared_ptr.

This improves a C++ binary size a little bit.

Reviewed By: rshest

Differential Revision: D75148487

fbshipit-source-id: 4c2f6dc6e4de670be37dd3b65dc3a8d63d546150
This commit is contained in:
Samuel Susla
2025-05-25 04:20:59 -07:00
committed by Facebook GitHub Bot
parent 1db4874bb3
commit 44ebf31f3b
31 changed files with 237 additions and 290 deletions
@@ -95,47 +95,33 @@ std::unique_ptr<AnimatedNode> NativeAnimatedNodesManager::animatedNode(
switch (type.value()) {
case AnimatedNodeType::Style:
return std::make_unique<StyleAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<StyleAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Value:
return std::make_unique<ValueAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<ValueAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Color:
return std::make_unique<ColorAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<ColorAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Props:
return std::make_unique<PropsAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<PropsAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Tracking:
return std::make_unique<TrackingAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<TrackingAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Interpolation:
return std::make_unique<InterpolationAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<InterpolationAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Transform:
return std::make_unique<TransformAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<TransformAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Subtraction:
return std::make_unique<SubtractionAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<SubtractionAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Addition:
return std::make_unique<AdditionAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<AdditionAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Multiplication:
return std::make_unique<MultiplicationAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<MultiplicationAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Division:
return std::make_unique<DivisionAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<DivisionAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Modulus:
return std::make_unique<ModulusAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<ModulusAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Diffclamp:
return std::make_unique<DiffClampAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<DiffClampAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Round:
return std::make_unique<RoundAnimatedNode>(
tag, config, shared_from_this());
return std::make_unique<RoundAnimatedNode>(tag, config, *this);
default:
LOG(WARNING) << "Cannot create AnimatedNode of type " << typeName
<< ", it's not implemented yet";
@@ -18,13 +18,11 @@ namespace facebook::react {
void AdditionAnimatedNode::update() {
auto rawValue = 0.0;
if (const auto manager = manager_.lock()) {
for (const auto tag : inputNodes_) {
const auto node = manager->getAnimatedNode<ValueAnimatedNode>(tag);
react_native_assert(
node && "Invalid node tag set as input for AdditionAnimatedNode");
rawValue += node->value();
}
for (const auto tag : inputNodes_) {
const auto node = manager_->getAnimatedNode<ValueAnimatedNode>(tag);
react_native_assert(
node && "Invalid node tag set as input for AdditionAnimatedNode");
rawValue += node->value();
}
setRawValue(rawValue);
}
@@ -20,7 +20,7 @@ class AdditionAnimatedNode final : public OperatorAnimatedNode {
AdditionAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: OperatorAnimatedNode(tag, config, manager) {}
void update() override;
@@ -19,9 +19,9 @@ namespace facebook::react {
AnimatedNode::AnimatedNode(
Tag tag,
folly::dynamic config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager,
NativeAnimatedNodesManager& manager,
AnimatedNodeType type)
: tag_(tag), manager_(manager), type_(type), config_(std::move(config)) {}
: tag_(tag), manager_(&manager), type_(type), config_(std::move(config)) {}
void AnimatedNode::addChild(const Tag animatedNodeTag) {
children_.insert(animatedNodeTag);
@@ -36,10 +36,8 @@ void AnimatedNode::removeChild(const Tag tag) {
}
AnimatedNode* AnimatedNode::getChildNode(Tag tag) {
if (const auto manager = manager_.lock()) {
if (children_.find(tag) != children_.end()) {
return manager->getAnimatedNode<AnimatedNode>(tag);
}
if (children_.find(tag) != children_.end()) {
return manager_->getAnimatedNode<AnimatedNode>(tag);
}
return nullptr;
@@ -14,7 +14,6 @@
#include <folly/dynamic.h>
#include <react/debug/flags.h>
#include <react/renderer/core/ReactPrimitives.h>
#include <memory>
namespace facebook::react {
@@ -44,7 +43,7 @@ class AnimatedNode {
folly::dynamic config,
// TODO: T190028913 maybe pass in strongly typed data when constructing
// AnimatedNode
const std::shared_ptr<NativeAnimatedNodesManager>& manager,
NativeAnimatedNodesManager& manager,
AnimatedNodeType type);
// Detach Node
@@ -99,7 +98,7 @@ class AnimatedNode {
protected:
AnimatedNode* getChildNode(Tag tag);
Tag tag_{0};
std::weak_ptr<NativeAnimatedNodesManager> manager_;
NativeAnimatedNodesManager* manager_;
AnimatedNodeType type_;
std::unordered_set<Tag> children_{};
@@ -18,10 +18,10 @@ namespace facebook::react {
namespace {
uint8_t getColorValue(
std::shared_ptr<NativeAnimatedNodesManager> manager,
const NativeAnimatedNodesManager& manager,
Tag nodeTag,
bool isDecimal = false) {
if (const auto node = manager->getAnimatedNode<ValueAnimatedNode>(nodeTag)) {
if (const auto node = manager.getAnimatedNode<ValueAnimatedNode>(nodeTag)) {
if (isDecimal) {
return std::clamp(static_cast<uint32_t>(node->value() * 255), 0u, 255u);
} else {
@@ -31,9 +31,7 @@ uint8_t getColorValue(
return 0;
}
uint8_t getAlphaValue(
std::shared_ptr<NativeAnimatedNodesManager> manager,
Tag nodeTag) {
uint8_t getAlphaValue(const NativeAnimatedNodesManager& manager, Tag nodeTag) {
return getColorValue(manager, nodeTag, true);
}
@@ -42,7 +40,7 @@ uint8_t getAlphaValue(
ColorAnimatedNode::ColorAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: AnimatedNode(tag, config, manager, AnimatedNodeType::Color),
rNodeTag_(static_cast<Tag>(getConfig()["r"].asInt())),
gNodeTag_(static_cast<Tag>(getConfig()["g"].asInt())),
@@ -50,23 +48,19 @@ ColorAnimatedNode::ColorAnimatedNode(
aNodeTag_(static_cast<Tag>(getConfig()["a"].asInt())) {}
void ColorAnimatedNode::update() {
if (const auto manager = manager_.lock()) {
color_ = *colorFromRGBA(
getColorValue(manager, rNodeTag_),
getColorValue(manager, gNodeTag_),
getColorValue(manager, bNodeTag_),
getAlphaValue(manager, aNodeTag_));
}
color_ = *colorFromRGBA(
getColorValue(*manager_, rNodeTag_),
getColorValue(*manager_, gNodeTag_),
getColorValue(*manager_, bNodeTag_),
getAlphaValue(*manager_, aNodeTag_));
}
Color ColorAnimatedNode::getColor() {
if (const auto manager = manager_.lock()) {
if (manager->updatedNodeTags_.contains(tag_)) {
update();
manager->updatedNodeTags_.erase(tag_);
}
return color_;
if (manager_->updatedNodeTags_.contains(tag_)) {
update();
manager_->updatedNodeTags_.erase(tag_);
}
return color_;
return 0;
}
@@ -21,7 +21,7 @@ class ColorAnimatedNode final : public AnimatedNode {
ColorAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void update() override;
@@ -18,21 +18,19 @@ namespace facebook::react {
DiffClampAnimatedNode::DiffClampAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: ValueAnimatedNode(tag, config, manager),
inputNodeTag_(static_cast<Tag>(getConfig()["input"].asDouble())),
min_(getConfig()["min"].asDouble()),
max_(getConfig()["max"].asDouble()) {}
void DiffClampAnimatedNode::update() {
if (const auto manager = manager_.lock()) {
if (const auto node =
manager->getAnimatedNode<ValueAnimatedNode>(inputNodeTag_)) {
const auto value = node->value();
const auto diff = value - lastValue_;
lastValue_ = value;
setRawValue(std::clamp(this->value() + diff, min_, max_));
}
if (const auto node =
manager_->getAnimatedNode<ValueAnimatedNode>(inputNodeTag_)) {
const auto value = node->value();
const auto diff = value - lastValue_;
lastValue_ = value;
setRawValue(std::clamp(this->value() + diff, min_, max_));
}
}
@@ -20,7 +20,7 @@ class DiffClampAnimatedNode final : public ValueAnimatedNode {
DiffClampAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void update() override;
@@ -18,20 +18,18 @@ namespace facebook::react {
void DivisionAnimatedNode::update() {
auto rawValue = 0.0;
if (const auto manager = manager_.lock()) {
int count = 0;
for (const auto tag : inputNodes_) {
const auto node = manager->getAnimatedNode<ValueAnimatedNode>(tag);
react_native_assert(
node && "Invalid node tag set as input for DivisionAnimatedNode");
if (count == 0) {
rawValue = node->value();
} else {
rawValue /= node->value();
}
count++;
int count = 0;
for (const auto tag : inputNodes_) {
const auto node = manager_->getAnimatedNode<ValueAnimatedNode>(tag);
react_native_assert(
node && "Invalid node tag set as input for DivisionAnimatedNode");
if (count == 0) {
rawValue = node->value();
} else {
rawValue /= node->value();
}
count++;
}
setRawValue(rawValue);
}
@@ -20,7 +20,7 @@ class DivisionAnimatedNode final : public OperatorAnimatedNode {
DivisionAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: OperatorAnimatedNode(tag, config, manager) {}
void update() override;
@@ -21,7 +21,7 @@ namespace facebook::react {
InterpolationAnimatedNode::InterpolationAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: ValueAnimatedNode(tag, config, manager) {
// inputRange example: [0, 1, 10], [1, 1.4, 1.5]
const auto& nodeConfig = getConfig();
@@ -51,14 +51,12 @@ void InterpolationAnimatedNode::update() {
return;
}
if (const auto manager = manager_.lock()) {
if (const auto node =
manager->getAnimatedNode<ValueAnimatedNode>(parentTag_)) {
if (isColorValue_) {
setRawValue(interpolateColor(node->value()));
} else {
setRawValue(interpolateValue(node->value()));
}
if (const auto node =
manager_->getAnimatedNode<ValueAnimatedNode>(parentTag_)) {
if (isColorValue_) {
setRawValue(interpolateColor(node->value()));
} else {
setRawValue(interpolateValue(node->value()));
}
}
}
@@ -23,7 +23,7 @@ class InterpolationAnimatedNode final : public ValueAnimatedNode {
InterpolationAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void update() override;
void onDetachedFromNode(Tag animatedNodeTag) override;
@@ -18,17 +18,15 @@ namespace facebook::react {
ModulusAnimatedNode::ModulusAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: ValueAnimatedNode(tag, config, manager),
inputNodeTag_(static_cast<Tag>(getConfig()["input"].asInt())),
modulus_(getConfig()["modulus"].asDouble()) {}
void ModulusAnimatedNode::update() {
if (const auto manager = manager_.lock()) {
if (const auto node =
manager->getAnimatedNode<ValueAnimatedNode>(inputNodeTag_)) {
setRawValue(std::fmod(node->value(), modulus_));
}
if (const auto node =
manager_->getAnimatedNode<ValueAnimatedNode>(inputNodeTag_)) {
setRawValue(std::fmod(node->value(), modulus_));
}
}
@@ -20,7 +20,7 @@ class ModulusAnimatedNode final : public ValueAnimatedNode {
ModulusAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void update() override;
@@ -18,20 +18,17 @@ namespace facebook::react {
void MultiplicationAnimatedNode::update() {
auto rawValue = 0.0;
if (const auto manager = manager_.lock()) {
int count = 0;
for (const auto tag : inputNodes_) {
const auto node = manager->getAnimatedNode<ValueAnimatedNode>(tag);
react_native_assert(
node &&
"Invalid node tag set as input for MultiplicationAnimatedNode");
if (count == 0) {
rawValue = node->value();
} else {
rawValue *= node->value();
}
count++;
int count = 0;
for (const auto tag : inputNodes_) {
const auto node = manager_->getAnimatedNode<ValueAnimatedNode>(tag);
react_native_assert(
node && "Invalid node tag set as input for MultiplicationAnimatedNode");
if (count == 0) {
rawValue = node->value();
} else {
rawValue *= node->value();
}
count++;
}
setRawValue(rawValue);
}
@@ -20,7 +20,7 @@ class MultiplicationAnimatedNode final : public OperatorAnimatedNode {
MultiplicationAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: OperatorAnimatedNode(tag, config, manager) {}
void update() override;
@@ -24,13 +24,13 @@ namespace {
bool isLayoutStyleUpdated(
const folly::dynamic& props,
const std::shared_ptr<NativeAnimatedNodesManager>& manager) {
NativeAnimatedNodesManager& manager) {
for (const auto& entry : props.items()) {
auto nodeTag = static_cast<Tag>(entry.second.asInt());
if (const auto& node = manager->getAnimatedNode<AnimatedNode>(nodeTag)) {
if (const auto& node = manager.getAnimatedNode<AnimatedNode>(nodeTag)) {
if (node->type() == AnimatedNodeType::Style) {
if (const auto& styleNode =
manager->getAnimatedNode<StyleAnimatedNode>(nodeTag)) {
manager.getAnimatedNode<StyleAnimatedNode>(nodeTag)) {
auto& styleNodeProps = styleNode->getProps();
for (const auto& styleNodeProp : styleNodeProps.items()) {
if (getDirectManipulationAllowlist().count(
@@ -51,7 +51,7 @@ bool isLayoutStyleUpdated(
PropsAnimatedNode::PropsAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: AnimatedNode(tag, config, manager, AnimatedNodeType::Props),
props_(folly::dynamic::object()),
layoutStyleUpdated_(isLayoutStyleUpdated(getConfig()["props"], manager)) {
@@ -76,10 +76,8 @@ void PropsAnimatedNode::disconnectFromView(Tag viewTag) {
void PropsAnimatedNode::restoreDefaultValues() {
// If node is already disconnected from View, we cannot restore default values
if (connectedViewTag_ != animated::undefinedAnimatedNodeIdentifier) {
if (const auto manager = manager_.lock()) {
manager->schedulePropsCommit(
connectedViewTag_, folly::dynamic::object(), false, false);
}
manager_->schedulePropsCommit(
connectedViewTag_, folly::dynamic::object(), false, false);
}
}
@@ -95,63 +93,59 @@ void PropsAnimatedNode::update(bool forceFabricCommit) {
// TODO: T190192206 consolidate shared update logic between
// Props/StyleAnimatedNode
std::lock_guard<std::mutex> lock(propsMutex_);
if (const auto manager = manager_.lock()) {
const auto& configProps = getConfig()["props"];
for (const auto& entry : configProps.items()) {
auto propName = entry.first.asString();
auto nodeTag = static_cast<Tag>(entry.second.asInt());
if (auto node = manager->getAnimatedNode<AnimatedNode>(nodeTag)) {
switch (node->type()) {
case AnimatedNodeType::Value:
case AnimatedNodeType::Interpolation:
case AnimatedNodeType::Modulus:
case AnimatedNodeType::Round:
case AnimatedNodeType::Diffclamp:
// Operators
case AnimatedNodeType::Addition:
case AnimatedNodeType::Subtraction:
case AnimatedNodeType::Multiplication:
case AnimatedNodeType::Division: {
if (const auto& valueNode =
manager->getAnimatedNode<ValueAnimatedNode>(nodeTag)) {
if (valueNode->isColorValue()) {
props_.insert(
propName.c_str(), static_cast<int32_t>(valueNode->value()));
} else {
props_.insert(propName.c_str(), valueNode->value());
}
}
} break;
case AnimatedNodeType::Color: {
if (const auto& colorNode =
manager->getAnimatedNode<ColorAnimatedNode>(nodeTag)) {
const auto& configProps = getConfig()["props"];
for (const auto& entry : configProps.items()) {
auto propName = entry.first.asString();
auto nodeTag = static_cast<Tag>(entry.second.asInt());
if (auto node = manager_->getAnimatedNode<AnimatedNode>(nodeTag)) {
switch (node->type()) {
case AnimatedNodeType::Value:
case AnimatedNodeType::Interpolation:
case AnimatedNodeType::Modulus:
case AnimatedNodeType::Round:
case AnimatedNodeType::Diffclamp:
// Operators
case AnimatedNodeType::Addition:
case AnimatedNodeType::Subtraction:
case AnimatedNodeType::Multiplication:
case AnimatedNodeType::Division: {
if (const auto& valueNode =
manager_->getAnimatedNode<ValueAnimatedNode>(nodeTag)) {
if (valueNode->isColorValue()) {
props_.insert(
propName.c_str(),
static_cast<int32_t>(colorNode->getColor()));
propName.c_str(), static_cast<int32_t>(valueNode->value()));
} else {
props_.insert(propName.c_str(), valueNode->value());
}
} break;
case AnimatedNodeType::Style: {
if (const auto& styleNode =
manager->getAnimatedNode<StyleAnimatedNode>(nodeTag)) {
styleNode->update();
auto& styleNodeProps = styleNode->getProps();
for (const auto& styleNodeProp : styleNodeProps.items()) {
props_.insert(
styleNodeProp.first.c_str(), styleNodeProp.second);
}
}
} break;
case AnimatedNodeType::Color: {
if (const auto& colorNode =
manager_->getAnimatedNode<ColorAnimatedNode>(nodeTag)) {
props_.insert(
propName.c_str(), static_cast<int32_t>(colorNode->getColor()));
}
} break;
case AnimatedNodeType::Style: {
if (const auto& styleNode =
manager_->getAnimatedNode<StyleAnimatedNode>(nodeTag)) {
styleNode->update();
auto& styleNodeProps = styleNode->getProps();
for (const auto& styleNodeProp : styleNodeProps.items()) {
props_.insert(styleNodeProp.first.c_str(), styleNodeProp.second);
}
} break;
case AnimatedNodeType::Props:
case AnimatedNodeType::Tracking:
case AnimatedNodeType::Transform:
break;
}
}
} break;
case AnimatedNodeType::Props:
case AnimatedNodeType::Tracking:
case AnimatedNodeType::Transform:
break;
}
}
manager->schedulePropsCommit(
connectedViewTag_, props_, layoutStyleUpdated_, forceFabricCommit);
}
manager_->schedulePropsCommit(
connectedViewTag_, props_, layoutStyleUpdated_, forceFabricCommit);
}
} // namespace facebook::react
@@ -22,7 +22,7 @@ class PropsAnimatedNode final : public AnimatedNode {
PropsAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void connectToView(Tag viewTag);
void disconnectFromView(Tag viewTag);
void restoreDefaultValues();
@@ -19,7 +19,7 @@ namespace facebook::react {
RoundAnimatedNode::RoundAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: ValueAnimatedNode(tag, config, manager),
inputNodeTag_(static_cast<Tag>(getConfig()["input"].asInt())),
nearest_(getConfig()["input"].asDouble()) {
@@ -29,12 +29,10 @@ RoundAnimatedNode::RoundAnimatedNode(
}
void RoundAnimatedNode::update() {
if (auto manager = manager_.lock()) {
auto node = manager->getAnimatedNode<ValueAnimatedNode>(inputNodeTag_);
react_native_assert(
node && "Illegal node ID set as an input for Animated.round node");
setRawValue(round(node->value() / nearest_) * nearest_);
}
auto node = manager_->getAnimatedNode<ValueAnimatedNode>(inputNodeTag_);
react_native_assert(
node && "Illegal node ID set as an input for Animated.round node");
setRawValue(round(node->value() / nearest_) * nearest_);
}
} // namespace facebook::react
@@ -26,7 +26,7 @@ class RoundAnimatedNode : public ValueAnimatedNode {
RoundAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void update() override;
@@ -20,62 +20,59 @@ namespace facebook::react {
StyleAnimatedNode::StyleAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: AnimatedNode(tag, config, manager, AnimatedNodeType::Style),
props_(folly::dynamic::object()) {}
void StyleAnimatedNode::update() {
if (const auto manager = manager_.lock()) {
const auto& style = getConfig()["style"];
for (const auto& styleProp : style.items()) {
auto propName = styleProp.first.asString();
const auto nodeTag = static_cast<Tag>(styleProp.second.asInt());
if (auto node = manager->getAnimatedNode<AnimatedNode>(nodeTag)) {
switch (node->type()) {
case AnimatedNodeType::Transform: {
if (const auto transformNode =
manager->getAnimatedNode<TransformAnimatedNode>(nodeTag)) {
transformNode->update();
auto& transformNodeProps = transformNode->getProps();
for (const auto& styleNodeProp : transformNodeProps.items()) {
props_.insert(
styleNodeProp.first.c_str(), styleNodeProp.second);
}
const auto& style = getConfig()["style"];
for (const auto& styleProp : style.items()) {
auto propName = styleProp.first.asString();
const auto nodeTag = static_cast<Tag>(styleProp.second.asInt());
if (auto node = manager_->getAnimatedNode<AnimatedNode>(nodeTag)) {
switch (node->type()) {
case AnimatedNodeType::Transform: {
if (const auto transformNode =
manager_->getAnimatedNode<TransformAnimatedNode>(nodeTag)) {
transformNode->update();
auto& transformNodeProps = transformNode->getProps();
for (const auto& styleNodeProp : transformNodeProps.items()) {
props_.insert(styleNodeProp.first.c_str(), styleNodeProp.second);
}
} break;
case AnimatedNodeType::Value:
case AnimatedNodeType::Interpolation:
case AnimatedNodeType::Modulus:
case AnimatedNodeType::Round:
case AnimatedNodeType::Diffclamp:
// Operators
case AnimatedNodeType::Addition:
case AnimatedNodeType::Subtraction:
case AnimatedNodeType::Multiplication:
case AnimatedNodeType::Division: {
if (const auto valueNode =
manager->getAnimatedNode<ValueAnimatedNode>(nodeTag)) {
if (valueNode->isColorValue()) {
props_.insert(
propName.c_str(), static_cast<int32_t>(valueNode->value()));
} else {
props_.insert(propName.c_str(), valueNode->value());
}
}
} break;
case AnimatedNodeType::Color: {
if (const auto colorAnimNode =
manager->getAnimatedNode<ColorAnimatedNode>(nodeTag)) {
}
} break;
case AnimatedNodeType::Value:
case AnimatedNodeType::Interpolation:
case AnimatedNodeType::Modulus:
case AnimatedNodeType::Round:
case AnimatedNodeType::Diffclamp:
// Operators
case AnimatedNodeType::Addition:
case AnimatedNodeType::Subtraction:
case AnimatedNodeType::Multiplication:
case AnimatedNodeType::Division: {
if (const auto valueNode =
manager_->getAnimatedNode<ValueAnimatedNode>(nodeTag)) {
if (valueNode->isColorValue()) {
props_.insert(
propName.c_str(),
static_cast<int32_t>(colorAnimNode->getColor()));
propName.c_str(), static_cast<int32_t>(valueNode->value()));
} else {
props_.insert(propName.c_str(), valueNode->value());
}
} break;
case AnimatedNodeType::Tracking:
case AnimatedNodeType::Style:
case AnimatedNodeType::Props:
break;
}
}
} break;
case AnimatedNodeType::Color: {
if (const auto colorAnimNode =
manager_->getAnimatedNode<ColorAnimatedNode>(nodeTag)) {
props_.insert(
propName.c_str(),
static_cast<int32_t>(colorAnimNode->getColor()));
}
} break;
case AnimatedNodeType::Tracking:
case AnimatedNodeType::Style:
case AnimatedNodeType::Props:
break;
}
}
}
@@ -21,7 +21,7 @@ class StyleAnimatedNode final : public AnimatedNode {
StyleAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void update() override;
const folly::dynamic& getProps() const {
@@ -18,20 +18,18 @@ namespace facebook::react {
void SubtractionAnimatedNode::update() {
auto rawValue = 0.0;
if (const auto manager = manager_.lock()) {
int count = 0;
for (const auto& tag : inputNodes_) {
const auto node = manager->getAnimatedNode<ValueAnimatedNode>(tag);
react_native_assert(
node && "Invalid node tag set as input for SubtractionAnimatedNode");
if (count == 0) {
rawValue = node->value();
} else {
rawValue -= node->value();
}
count++;
int count = 0;
for (const auto& tag : inputNodes_) {
const auto node = manager_->getAnimatedNode<ValueAnimatedNode>(tag);
react_native_assert(
node && "Invalid node tag set as input for SubtractionAnimatedNode");
if (count == 0) {
rawValue = node->value();
} else {
rawValue -= node->value();
}
count++;
}
setRawValue(rawValue);
}
@@ -21,7 +21,7 @@ class SubtractionAnimatedNode final : public OperatorAnimatedNode {
SubtractionAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: OperatorAnimatedNode(tag, config, manager) {}
void update() override;
@@ -19,26 +19,24 @@ namespace facebook::react {
TrackingAnimatedNode::TrackingAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: AnimatedNode(tag, config, manager, AnimatedNodeType::Tracking),
animationId_(static_cast<int>(getConfig()["animationId"].asInt())),
toValueNodeId_(static_cast<Tag>(getConfig()["toValue"].asInt())),
valueNodeId_(static_cast<Tag>(getConfig()["value"].asInt())) {}
void TrackingAnimatedNode::update() {
if (const auto manager = manager_.lock()) {
if (const auto toValueNode =
manager->getAnimatedNode<ValueAnimatedNode>(toValueNodeId_)) {
// In case the animation is already running, we need to stop it to free up
// the animationId key in the active animations map in the animation
// manager.
manager->stopAnimation(animationId_, true);
auto animationConfig = getConfig()["animationConfig"];
animationConfig["toValue"] = toValueNode->value();
if (const auto toValueNode =
manager_->getAnimatedNode<ValueAnimatedNode>(toValueNodeId_)) {
// In case the animation is already running, we need to stop it to free up
// the animationId key in the active animations map in the animation
// manager.
manager_->stopAnimation(animationId_, true);
auto animationConfig = getConfig()["animationConfig"];
animationConfig["toValue"] = toValueNode->value();
manager->startAnimatingNode(
animationId_, valueNodeId_, animationConfig, std::nullopt);
}
manager_->startAnimatingNode(
animationId_, valueNodeId_, animationConfig, std::nullopt);
}
};
@@ -20,7 +20,7 @@ class TrackingAnimatedNode final : public AnimatedNode {
TrackingAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void update() override;
@@ -29,33 +29,31 @@ static constexpr std::string_view sTransformPropName{"transform"};
TransformAnimatedNode::TransformAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: AnimatedNode(tag, config, manager, AnimatedNodeType::Transform),
props_(folly::dynamic::object()) {}
void TransformAnimatedNode::update() {
folly::dynamic transforms = folly::dynamic::array();
if (const auto manager = manager_.lock()) {
auto transformsArray = getConfig()[sTransformsName];
react_native_assert(transformsArray.type() == folly::dynamic::ARRAY);
for (const auto& transform : transformsArray) {
std::optional<double> value;
if (transform[sTypeName].asString() == sAnimatedName) {
const auto inputTag = static_cast<Tag>(transform[sNodeTagName].asInt());
if (const auto node =
manager->getAnimatedNode<ValueAnimatedNode>(inputTag)) {
value = node->value();
}
} else {
value = transform[sValueName].asDouble();
}
if (value) {
const auto property = transform[sPropertyName].asString();
transforms.push_back(folly::dynamic::object(property, value.value()));
auto transformsArray = getConfig()[sTransformsName];
react_native_assert(transformsArray.type() == folly::dynamic::ARRAY);
for (const auto& transform : transformsArray) {
std::optional<double> value;
if (transform[sTypeName].asString() == sAnimatedName) {
const auto inputTag = static_cast<Tag>(transform[sNodeTagName].asInt());
if (const auto node =
manager_->getAnimatedNode<ValueAnimatedNode>(inputTag)) {
value = node->value();
}
} else {
value = transform[sValueName].asDouble();
}
if (value) {
const auto property = transform[sPropertyName].asString();
transforms.push_back(folly::dynamic::object(property, value.value()));
}
props_[sTransformPropName] = std::move(transforms);
}
props_[sTransformPropName] = std::move(transforms);
}
const folly::dynamic& TransformAnimatedNode::getProps() {
@@ -27,7 +27,7 @@ class TransformAnimatedNode final : public AnimatedNode {
TransformAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
void update() override;
@@ -18,7 +18,7 @@ namespace facebook::react {
ValueAnimatedNode::ValueAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: AnimatedNode(tag, config, manager, AnimatedNodeType::Value) {
auto value = 0.0;
auto offset = 0.0;
@@ -87,7 +87,7 @@ void ValueAnimatedNode::setValueListener(ValueListenerCallback&& callback) {
OperatorAnimatedNode::OperatorAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager)
NativeAnimatedNodesManager& manager)
: ValueAnimatedNode(tag, config, manager) {
const auto& input = getConfig()["input"];
react_native_assert(
@@ -24,7 +24,7 @@ class ValueAnimatedNode : public AnimatedNode {
ValueAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
double value();
double rawValue();
bool setRawValue(double value);
@@ -54,7 +54,7 @@ class OperatorAnimatedNode : public ValueAnimatedNode {
OperatorAnimatedNode(
Tag tag,
const folly::dynamic& config,
const std::shared_ptr<NativeAnimatedNodesManager>& manager);
NativeAnimatedNodesManager& manager);
protected:
std::vector<Tag> inputNodes_{};