Skip to content
Open
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
6 changes: 3 additions & 3 deletions apps/fabric-example/ios/Podfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ void CSSLoopTransition::runProperty(
const double timestamp) {
properties_.insert(propertyName);

// Update the transition style interpolator
const auto &valueChange = propertySettings.value;

bool isReversed;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,50 @@
#include <reanimated/CSS/core/transition/CSSPlatformTransition.h>

#include <reanimated/CSS/utils/reversingShortening.h>

#include <utility>

namespace reanimated::css {

CSSPlatformTransition::CSSPlatformTransition(
const Tag viewTag,
const std::shared_ptr<CSSPlatformTransitionProxy> &proxy)
: viewTag_(viewTag), proxy_(proxy) {}

folly::dynamic CSSPlatformTransition::run(const CSSPlatformTransitionConfig &config) {
folly::dynamic initialUpdate = folly::dynamic::object();

for (const auto &propertyConfig : config.changedProperties) {
// The model layer needs to settle on the toValue so RN's view stays at
// the final state once the native animation completes.
initialUpdate[propertyConfig.propertyName] = propertyConfig.toValue;
proxy_->run(propertyConfig);
activeProperties_.insert(propertyConfig.propertyName);
void CSSPlatformTransition::run(jsi::Runtime &rt, const CSSTransitionConfig &config, const double timestamp) {
for (const auto &[propertyName, settings] : config.changedProperties) {
runProperty(rt, propertyName, settings, timestamp);
}

for (const auto &propertyName : config.removedProperties) {
cancel(propertyName);
}
}

return initialUpdate;
void CSSPlatformTransition::runProperty(
jsi::Runtime &rt,
const std::string &propertyName,
const CSSTransitionPropertySettings &settings,
const double timestamp) {
// null/undefined endpoints are resolved to the property's default inside
// parsePlatformValue; type mismatches and unsupported properties throw.
auto fromValue = parsePlatformValue(rt, propertyName, settings.value.first);
auto toValue = parsePlatformValue(rt, propertyName, settings.value.second);

const auto activeIt = activeProperties_.find(propertyName);
auto *prev =
activeIt != activeProperties_.end() && toValue == activeIt->second.adjustedStart ? &activeIt->second : nullptr;
auto rs = prev ? reverseShorten(prev->previous, timestamp, settings.duration, settings.delay, settings.easingConfig)
: makeReversingState(timestamp, settings.duration, settings.delay, settings.easingConfig);

proxy_->run(CSSPlatformTransitionPropertyConfig{
viewTag_, propertyName, fromValue, toValue, rs.duration, rs.startTimestamp, settings.easingConfig});

activeProperties_[propertyName] = ActiveProperty{
prev ? std::move(prev->adjustedEnd) : std::move(fromValue),
std::move(toValue),
std::move(rs),
};
}

void CSSPlatformTransition::cancel(const std::string &propertyName) {
Expand All @@ -32,7 +54,7 @@ void CSSPlatformTransition::cancel(const std::string &propertyName) {
}

void CSSPlatformTransition::cancelAll() {
for (const auto &propertyName : activeProperties_) {
for (const auto &[propertyName, _] : activeProperties_) {
proxy_->remove(viewTag_, propertyName);
}
activeProperties_.clear();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#pragma once

#include <reanimated/CSS/core/transition/CSSPlatformTransitionProxy.h>
#include <reanimated/CSS/utils/platform.h>
#include <reanimated/CSS/utils/reversingShortening.h>

#include <folly/dynamic.h>
#include <jsi/jsi.h>
#include <react/renderer/core/ReactPrimitives.h>

#include <memory>
#include <string>
#include <unordered_set>
#include <unordered_map>

namespace reanimated::css {

Expand All @@ -20,15 +22,27 @@ class CSSPlatformTransition {

CSSPlatformTransition(const CSSPlatformTransition &) = delete;

folly::dynamic run(const CSSPlatformTransitionConfig &config);
void run(jsi::Runtime &rt, const CSSTransitionConfig &config, double timestamp);

void cancel(const std::string &propertyName);
void cancelAll();

private:
struct ActiveProperty {
PlatformValue adjustedStart;
PlatformValue adjustedEnd;
ReversingState previous;
};

void runProperty(
jsi::Runtime &rt,
const std::string &propertyName,
const CSSTransitionPropertySettings &settings,
double timestamp);

const Tag viewTag_;
const std::shared_ptr<CSSPlatformTransitionProxy> proxy_;
std::unordered_set<std::string> activeProperties_;
std::unordered_map<std::string, ActiveProperty> activeProperties_;
};

} // namespace reanimated::css
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include <reanimated/CSS/core/transition/CSSPlatformTransitionProxy.h>

#include <jsi/JSIDynamic.h>

#include <utility>

namespace reanimated::css {
Expand All @@ -14,8 +12,8 @@ CSSPlatformTransitionProxy::CSSPlatformTransitionProxy(
applyTransition_(std::move(applyTransition)),
removeTransition_(std::move(removeTransition)) {}

bool CSSPlatformTransitionProxy::canRoute(const std::string &propertyName) const {
return canRoute_ && canRoute_(propertyName);
bool CSSPlatformTransitionProxy::canRoute(const std::string &propertyName, const EasingConfig &easing) const {
return canRoute_ && canRoute_(propertyName, easing);
}

void CSSPlatformTransitionProxy::run(const CSSPlatformTransitionPropertyConfig &config) const {
Expand All @@ -30,32 +28,25 @@ void CSSPlatformTransitionProxy::remove(const Tag viewTag, const std::string &pr
}
}

// Splits the new config into loop/platform buckets. result.routing starts as
// a copy of the previous call's routing and is updated as we route each prop;
// erasing from the *other* side's set returns nonzero exactly when the prop
// is migrating sides - that's how we emit cancels.
CSSPlatformTransitionProxy::ProcessedConfig CSSPlatformTransitionProxy::processConfig(
jsi::Runtime &rt,
const Tag viewTag,
CSSTransitionConfig &&config,
const CSSTransitionRouting &previousRouting) const {
ProcessedConfig result;
result.routing = previousRouting;

// extract() preserves move-only PropertySettings (jsi::Value).
// Drain via extract() so move-only PropertySettings (jsi::Value) can be
// moved into the matching bucket.
while (!config.changedProperties.empty()) {
auto node = config.changedProperties.extract(config.changedProperties.begin());
const auto &propertyName = node.key();

if (canRoute(propertyName)) {
// loop -> platform migration: cancel on loop.
if (canRoute(propertyName, node.mapped().easingConfig)) {
if (result.routing.loop.erase(propertyName) > 0) {
result.loop.removedProperties.push_back(propertyName);
}
result.routing.platform.insert(propertyName);
result.platform.changedProperties.push_back(buildPropertyConfig(rt, viewTag, propertyName, node.mapped()));
result.platform.changedProperties.insert(std::move(node));
} else {
// platform -> loop migration: cancel on platform.
if (result.routing.platform.erase(propertyName) > 0) {
result.platform.removedProperties.push_back(propertyName);
}
Expand All @@ -77,18 +68,4 @@ CSSPlatformTransitionProxy::ProcessedConfig CSSPlatformTransitionProxy::processC
return result;
}

CSSPlatformTransitionPropertyConfig CSSPlatformTransitionProxy::buildPropertyConfig(
jsi::Runtime &rt,
const Tag viewTag,
const std::string &propertyName,
const CSSTransitionPropertySettings &propertySettings) const {
return CSSPlatformTransitionPropertyConfig{
viewTag,
propertyName,
jsi::dynamicFromValue(rt, propertySettings.value.second),
propertySettings.duration,
propertySettings.delay,
propertySettings.easingConfig};
}

} // namespace reanimated::css
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
#include <reanimated/CSS/common/definitions.h>
#include <reanimated/CSS/configs/CSSTransitionConfig.h>
#include <reanimated/CSS/easing/EasingConfigs.h>
#include <reanimated/CSS/utils/platform.h>

#include <folly/dynamic.h>
#include <jsi/jsi.h>
#include <react/renderer/core/ReactPrimitives.h>

#include <functional>
#include <string>
#include <vector>

namespace reanimated::css {

Expand All @@ -20,15 +18,14 @@ using namespace react;
struct CSSPlatformTransitionPropertyConfig {
Tag viewTag;
std::string propertyName;
folly::dynamic toValue;
double duration; // ms
double delay; // ms
PlatformValue fromValue;
PlatformValue toValue;
double durationMs;
double startTimestampMs;
EasingConfig easing;
};

using CSSPlatformTransitionConfig = CSSTransitionConfigBase<std::vector<CSSPlatformTransitionPropertyConfig>>;

using CSSCanRoutePropertyFunction = std::function<bool(const std::string &propertyName)>;
using CSSCanRoutePropertyFunction = std::function<bool(const std::string &propertyName, const EasingConfig &easing)>;
using CSSApplyTransitionFunction = std::function<void(const CSSPlatformTransitionPropertyConfig &config)>;
using CSSRemoveTransitionFunction = std::function<void(Tag viewTag, const std::string &propertyName)>;

Expand All @@ -41,7 +38,7 @@ class CSSPlatformTransitionProxy {
public:
struct ProcessedConfig {
CSSTransitionConfig loop;
CSSPlatformTransitionConfig platform;
CSSTransitionConfig platform;
CSSTransitionRouting routing;
};

Expand All @@ -53,23 +50,14 @@ class CSSPlatformTransitionProxy {
void run(const CSSPlatformTransitionPropertyConfig &config) const;
void remove(Tag viewTag, const std::string &propertyName) const;

// Splits the new config across loop/platform sides given the previous
// call's routing decisions. When a property's side flips compared to
// previousRouting, the old side receives an implicit cancel so two engines
// never drive the same prop.
ProcessedConfig processConfig(
jsi::Runtime &rt,
Tag viewTag,
CSSTransitionConfig &&config,
const CSSTransitionRouting &previousRouting) const;
// Filters the incoming config into loop/platform buckets and emits implicit
// cancels on the old side when a property migrates compared to
// previousRouting. No value conversion or timing math here - the platform
// side does its own building inside CSSPlatformTransition::run.
ProcessedConfig processConfig(CSSTransitionConfig &&config, const CSSTransitionRouting &previousRouting) const;

private:
bool canRoute(const std::string &propertyName) const;
CSSPlatformTransitionPropertyConfig buildPropertyConfig(
jsi::Runtime &rt,
Tag viewTag,
const std::string &propertyName,
const CSSTransitionPropertySettings &propertySettings) const;
bool canRoute(const std::string &propertyName, const EasingConfig &easing) const;

CSSCanRoutePropertyFunction canRoute_;
CSSApplyTransitionFunction applyTransition_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,11 @@ folly::dynamic CSSTransition::run(
const folly::dynamic emptyObject = folly::dynamic::object();
const folly::dynamic &lastUpdates = lastUpdateValue.empty() ? emptyObject : lastUpdateValue;

auto processed = platformTransitionProxy_->processConfig(rt, shadowNode_->getTag(), std::move(config), routing_);
auto processed = platformTransitionProxy_->processConfig(std::move(config), routing_);
routing_ = std::move(processed.routing);

folly::dynamic initialUpdate = folly::dynamic::object();
initialUpdate.update(runLoop(rt, processed.loop, lastUpdates, timestamp));
initialUpdate.update(runPlatform(processed.platform));
return initialUpdate;
runPlatform(rt, processed.platform, timestamp);
return runLoop(rt, processed.loop, lastUpdates, timestamp);
}

folly::dynamic CSSTransition::computeCurrentLoopStyle() {
Expand All @@ -78,11 +76,11 @@ folly::dynamic CSSTransition::runLoop(
return loopTransition_->run(rt, shadowNode_, config, lastUpdates, timestamp);
}

folly::dynamic CSSTransition::runPlatform(const CSSPlatformTransitionConfig &config) {
void CSSTransition::runPlatform(jsi::Runtime &rt, const CSSTransitionConfig &config, const double timestamp) {
if (!platformTransition_) {
platformTransition_ = std::make_unique<CSSPlatformTransition>(shadowNode_->getTag(), platformTransitionProxy_);
}
return platformTransition_->run(config);
platformTransition_->run(rt, config, timestamp);
}

} // namespace reanimated::css
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class CSSTransition {
private:
folly::dynamic
runLoop(jsi::Runtime &rt, const CSSTransitionConfig &config, const folly::dynamic &lastUpdates, double timestamp);
folly::dynamic runPlatform(const CSSPlatformTransitionConfig &config);
void runPlatform(jsi::Runtime &rt, const CSSTransitionConfig &config, double timestamp);

const std::shared_ptr<const ShadowNode> shadowNode_;
const std::shared_ptr<ViewStylesRepository> viewStylesRepository_;
Expand Down
Loading
Loading