Files
Schnappix/node_modules/react-native-reanimated/Common/cpp/reanimated/CSS/utils/props.cpp
T

160 lines
4.5 KiB
C++

#include <reanimated/CSS/utils/props.h>
namespace reanimated::css {
bool isDiscreteProperty(
const std::string &propName,
const std::string &componentName) {
const auto &interpolators = getComponentInterpolators(componentName);
const auto it = interpolators.find(propName);
if (it == interpolators.end()) {
return false;
}
return it->second->isDiscreteProperty();
}
bool areArraysDifferentRecursive(
const folly::dynamic &oldArray,
const folly::dynamic &newArray) {
if (oldArray.size() != newArray.size()) {
return true;
}
for (size_t i = 0; i < oldArray.size(); i++) {
const auto [oldChangedProp, newChangedProp] =
getChangedPropsRecursive(oldArray[i], newArray[i]);
if (!oldChangedProp.isNull() || !newChangedProp.isNull()) {
return true;
}
}
return false;
}
std::pair<folly::dynamic, folly::dynamic> getChangedPropsRecursive(
const folly::dynamic &oldProp,
const folly::dynamic &newProp) {
if (!oldProp.isObject() || !newProp.isObject()) {
// Primitive values comparison
if (oldProp != newProp) {
return {oldProp, newProp};
}
return {folly::dynamic(), folly::dynamic()};
}
if (oldProp.isArray() && newProp.isArray()) {
// Arrays comparison
if (areArraysDifferentRecursive(oldProp, newProp)) {
return {oldProp, newProp};
}
return {folly::dynamic(), folly::dynamic()};
}
folly::dynamic oldResult = folly::dynamic::object;
folly::dynamic newResult = folly::dynamic::object;
bool oldHasChanges = false;
bool newHasChanges = false;
// Check for removed properties
for (const auto &item : oldProp.items()) {
const auto &propName = item.first.asString();
if (!newProp.count(propName)) {
const auto &oldValue = item.second;
oldResult[propName] = oldValue;
oldHasChanges = true;
}
}
// Check for new and changed properties
for (const auto &item : newProp.items()) {
const auto &propName = item.first.asString();
const auto &newValue = item.second;
if (oldProp.count(propName)) {
const auto &oldValue = oldProp[propName];
auto [oldChangedProp, newChangedProp] =
getChangedPropsRecursive(oldValue, newValue);
if (!oldChangedProp.isNull() && !newChangedProp.isNull()) {
oldResult[propName] = std::move(oldChangedProp);
newResult[propName] = std::move(newChangedProp);
oldHasChanges = true;
newHasChanges = true;
}
} else {
newResult[propName] = newValue;
newHasChanges = true;
}
}
return {
oldHasChanges ? std::move(oldResult) : folly::dynamic(),
newHasChanges ? std::move(newResult) : folly::dynamic()};
}
std::pair<folly::dynamic, folly::dynamic> getChangedValueForProp(
const folly::dynamic &oldObject,
const folly::dynamic &newObject,
const std::string &propName) {
const bool oldHasProperty = oldObject.count(propName);
const bool newHasProperty = newObject.count(propName);
if (oldHasProperty && newHasProperty) {
const auto &oldVal = oldObject[propName];
const auto &newVal = newObject[propName];
if (oldVal.isObject() && newVal.isObject()) {
return getChangedPropsRecursive(oldVal, newVal);
} else if (oldVal != newVal) {
return {oldVal, newVal};
}
return {folly::dynamic(), folly::dynamic()};
}
if (oldHasProperty) {
const auto &oldVal = oldObject[propName];
return {oldVal, folly::dynamic()};
} else if (newHasProperty) {
const auto &newVal = newObject[propName];
return {folly::dynamic(), newVal};
}
return {folly::dynamic(), folly::dynamic()};
}
ChangedProps getChangedProps(
const folly::dynamic &oldProps,
const folly::dynamic &newProps,
const PropertyNames &allowedProperties) {
folly::dynamic oldResult = folly::dynamic::object;
folly::dynamic newResult = folly::dynamic::object;
PropertyNames changedPropertyNames;
for (const auto &propName : allowedProperties) {
auto [oldChangedProp, newChangedProp] =
getChangedValueForProp(oldProps, newProps, propName);
const auto hasOldChangedProp = !oldChangedProp.isNull();
const auto hasNewChangedProp = !newChangedProp.isNull();
if (hasOldChangedProp) {
oldResult[propName] = std::move(oldChangedProp);
}
if (hasNewChangedProp) {
newResult[propName] = std::move(newChangedProp);
}
if (hasOldChangedProp || hasNewChangedProp) {
changedPropertyNames.push_back(propName);
}
}
return {
std::move(oldResult),
std::move(newResult),
std::move(changedPropertyNames)};
}
} // namespace reanimated::css