Skip to content

Commit

Permalink
Fix transition for different number of array items or different objec…
Browse files Browse the repository at this point in the history
…t keys
  • Loading branch information
MatiPl01 committed Jan 31, 2025
1 parent a8823ec commit 0417d4e
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,33 @@ void ArrayPropertiesInterpolator::updateKeyframesFromStyleChange(
jsi::Runtime &rt,
const jsi::Value &oldStyleValue,
const jsi::Value &newStyleValue) {
const size_t valuesCount = newStyleValue.isObject()
? newStyleValue.asObject(rt).asArray(rt).size(rt)
: oldStyleValue.asObject(rt).asArray(rt).size(rt);
auto getArrayFromStyle = [&rt](const jsi::Value &style) {
if (!style.isObject()) {
return jsi::Array(rt, 0);
}
auto obj = style.asObject(rt);
return obj.isArray(rt) ? obj.asArray(rt) : jsi::Array(rt, 0);
};

const auto oldStyleArray = getArrayFromStyle(oldStyleValue);
const auto newStyleArray = getArrayFromStyle(newStyleValue);

const size_t valuesCount =
std::max(oldStyleArray.size(rt), newStyleArray.size(rt));

resizeInterpolators(valuesCount);

for (size_t i = 0; i < valuesCount; ++i) {
interpolators_[i]->updateKeyframesFromStyleChange(
rt,
oldStyleValue.isObject()
? oldStyleValue.asObject(rt).asArray(rt).getValueAtIndex(rt, i)
: jsi::Value::undefined(),
newStyleValue.isObject()
? newStyleValue.asObject(rt).asArray(rt).getValueAtIndex(rt, i)
: jsi::Value::undefined());
// These index checks ensure that interpolation works between 2 arrays
// with different lengths
const auto oldValue = oldStyleArray.size(rt) > i
? oldStyleArray.getValueAtIndex(rt, i)
: jsi::Value::undefined();
const auto newValue = newStyleArray.size(rt) > i
? newStyleArray.getValueAtIndex(rt, i)
: jsi::Value::undefined();

interpolators_[i]->updateKeyframesFromStyleChange(rt, oldValue, newValue);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,9 @@ void RecordPropertiesInterpolator::updateKeyframes(
propertyNames.getValueAtIndex(rt, i).asString(rt).utf8(rt);
const jsi::Value &propertyKeyframes = keyframesObject.getProperty(
rt, jsi::PropNameID::forUtf8(rt, propertyName));
auto interpolatorIt = interpolators_.find(propertyName);

if (interpolatorIt == interpolators_.end()) {
const auto newInterpolator = createPropertyInterpolator(
propertyName,
propertyPath_,
factories_,
progressProvider_,
viewStylesRepository_);
interpolatorIt =
interpolators_.emplace(propertyName, newInterpolator).first;
}

interpolatorIt->second->updateKeyframes(rt, propertyKeyframes);
maybeCreateInterpolator(propertyName);
interpolators_.at(propertyName)->updateKeyframes(rt, propertyKeyframes);
}
}

Expand All @@ -76,35 +65,34 @@ void RecordPropertiesInterpolator::updateKeyframesFromStyleChange(
const jsi::Value &newStyleValue) {
// TODO - maybe add a possibility to remove interpolators that are no longer
// used (for now, for simplicity, we only add new ones)
const jsi::Array propertyNames = newStyleValue.isObject()
? newStyleValue.asObject(rt).getPropertyNames(rt)
: oldStyleValue.asObject(rt).getPropertyNames(rt);
const size_t propertiesCount = propertyNames.size(rt);

for (size_t i = 0; i < propertiesCount; ++i) {
const std::string propertyName =
propertyNames.getValueAtIndex(rt, i).asString(rt).utf8(rt);
auto interpolatorIt = interpolators_.find(propertyName);

if (interpolatorIt == interpolators_.end()) {
const auto newInterpolator = createPropertyInterpolator(
propertyName,
propertyPath_,
factories_,
progressProvider_,
viewStylesRepository_);
interpolatorIt =
interpolators_.emplace(propertyName, newInterpolator).first;
const auto oldStyleObject =
oldStyleValue.isObject() ? oldStyleValue.asObject(rt) : jsi::Object(rt);
const auto newStyleObject =
newStyleValue.isObject() ? newStyleValue.asObject(rt) : jsi::Object(rt);

std::unordered_set<std::string> propertyNamesSet;
const jsi::Object *objects[] = {&oldStyleObject, &newStyleObject};
for (const auto *styleObject : objects) {
const auto propertyNames = styleObject->getPropertyNames(rt);
for (size_t i = 0; i < propertyNames.size(rt); ++i) {
propertyNamesSet.insert(
propertyNames.getValueAtIndex(rt, i).asString(rt).utf8(rt));
}
}

interpolatorIt->second->updateKeyframesFromStyleChange(
rt,
oldStyleValue.isObject()
? oldStyleValue.asObject(rt).getProperty(rt, propertyName.c_str())
: jsi::Value::undefined(),
newStyleValue.isObject()
? newStyleValue.asObject(rt).getProperty(rt, propertyName.c_str())
: jsi::Value::undefined());
for (const auto &propertyName : propertyNamesSet) {
maybeCreateInterpolator(propertyName);

auto getValue = [&](const jsi::Object &obj) {
return obj.hasProperty(rt, propertyName.c_str())
? obj.getProperty(rt, jsi::PropNameID::forUtf8(rt, propertyName))
: jsi::Value::undefined();
};

interpolators_.at(propertyName)
->updateKeyframesFromStyleChange(
rt, getValue(oldStyleObject), getValue(newStyleObject));
}
}

Expand All @@ -121,6 +109,19 @@ jsi::Value RecordPropertiesInterpolator::mapInterpolators(
return result;
}

void RecordPropertiesInterpolator::maybeCreateInterpolator(
const std::string &propertyName) {
if (interpolators_.find(propertyName) == interpolators_.end()) {
const auto newInterpolator = createPropertyInterpolator(
propertyName,
propertyPath_,
factories_,
progressProvider_,
viewStylesRepository_);
interpolators_.emplace(propertyName, newInterpolator);
}
}

} // namespace reanimated

#endif // RCT_NEW_ARCH_ENABLED
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class RecordPropertiesInterpolator : public GroupPropertiesInterpolator {
const std::function<jsi::Value(PropertyInterpolator &)> &callback)
const override;

void maybeCreateInterpolator(const std::string &propertyName);

private:
const InterpolatorFactoriesRecord &factories_;
PropertyInterpolatorsRecord interpolators_;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#ifdef RCT_NEW_ARCH_ENABLED
#include <reanimated/CSS/registry/CSSTransitionsRegistry.h>

#include <worklets/Tools/JSISerializer.h>

namespace reanimated {

using namespace worklets;

CSSTransitionsRegistry::CSSTransitionsRegistry(
const std::shared_ptr<StaticPropsRegistry> &staticPropsRegistry,
const GetAnimationTimestampFunction &getCurrentTimestamp)
Expand Down Expand Up @@ -139,6 +143,9 @@ PropsObserver CSSTransitionsRegistry::createPropsObserver(const Tag viewTag) {
return;
}

LOG(INFO) << "oldProps: " << stringifyJSIValue(rt, changedProps.oldProps);
LOG(INFO) << "newProps: " << stringifyJSIValue(rt, changedProps.newProps);

{
std::lock_guard<std::mutex> lock{strongThis->mutex_};

Expand Down

0 comments on commit 0417d4e

Please sign in to comment.