11#include < reanimated/CSS/core/transition/CSSPlatformTransitionProxy.h>
2- #include < reanimated/Tools/FeatureFlags.h>
32
43#include < react/debug/react_native_assert.h>
54
@@ -9,19 +8,33 @@ namespace reanimated::css {
98
109CSSPlatformTransitionProxy::CSSPlatformTransitionProxy (
1110 CSSCanRoutePropertyFunction canRoute,
11+ CSSParseValueFunction parseValue,
12+ CSSParseDynamicValueFunction parseDynamicValue,
1213 CSSApplyTransitionFunction applyTransition,
1314 CSSRemoveTransitionFunction removeTransition)
1415 : canRoute_(std::move(canRoute)),
16+ parseValue_ (std::move(parseValue)),
17+ parseDynamicValue_(std::move(parseDynamicValue)),
1518 applyTransition_(std::move(applyTransition)),
1619 removeTransition_(std::move(removeTransition)) {}
1720
1821bool CSSPlatformTransitionProxy::canRoute (const std::string &propertyName, const EasingConfig &easing) const {
19- if constexpr (!StaticFeatureFlags::getFlag (" IOS_CSS_CORE_ANIMATION" )) {
20- return false ;
21- }
2222 return canRoute_ && canRoute_ (propertyName, easing);
2323}
2424
25+ std::optional<PlatformValue> CSSPlatformTransitionProxy::parseValue (
26+ jsi::Runtime &rt,
27+ const std::string &propertyName,
28+ const jsi::Value &value) const {
29+ return parseValue_ ? parseValue_ (rt, propertyName, value) : std::nullopt ;
30+ }
31+
32+ std::optional<PlatformValue> CSSPlatformTransitionProxy::parseDynamicValue (
33+ const std::string &propertyName,
34+ const folly::dynamic &value) const {
35+ return parseDynamicValue_ ? parseDynamicValue_ (propertyName, value) : std::nullopt ;
36+ }
37+
2538void CSSPlatformTransitionProxy::run (const CSSPlatformTransitionPropertyConfig &config) const {
2639 if (applyTransition_) {
2740 applyTransition_ (config);
@@ -34,35 +47,42 @@ void CSSPlatformTransitionProxy::remove(const Tag viewTag, const std::string &pr
3447 }
3548}
3649
37- // Splits the new split-shape config into loop / platform buckets. result.routing
38- // starts as a copy of the previous call's routing and is updated as we route
39- // each prop; erasing from the *other* side's set returns nonzero exactly when
40- // the prop is migrating sides - that's how we emit cancels.
50+ // Erasing from the other side's routing set returns nonzero exactly when the
51+ // property migrates sides - that's when the old side gets a cancel.
4152CSSPlatformTransitionProxy::ProcessedConfig CSSPlatformTransitionProxy::processConfig (
53+ jsi::Runtime &rt,
4254 CSSTransitionConfig &&config,
4355 const CSSTransitionRouting &previousRouting) const {
4456 ProcessedConfig result;
4557 result.routing = previousRouting;
4658
47- // Drain changedPropertiesSettings; for each, decide routing and bucket.
48- // extract() preserves move-only PropertyValueDiff (jsi::Value pair).
59+ // extract() preserves the move-only jsi::Value diffs.
4960 while (!config.changedPropertiesSettings .empty ()) {
5061 auto settingsNode = config.changedPropertiesSettings .extract (config.changedPropertiesSettings .begin ());
5162 const auto &propertyName = settingsNode.key ();
5263 const auto &settings = settingsNode.mapped ();
5364 const auto valueIt = config.changedProperties .find (propertyName);
5465
55- if (canRoute (propertyName, settings.easingConfig )) {
66+ bool routable = canRoute (propertyName, settings.easingConfig );
67+ std::optional<PlatformValue> fromValue;
68+ std::optional<PlatformValue> toValue;
69+ if (routable && valueIt != config.changedProperties .end ()) {
70+ fromValue = parseValue (rt, propertyName, valueIt->second .first );
71+ toValue = parseValue (rt, propertyName, valueIt->second .second );
72+ routable = fromValue.has_value () && toValue.has_value ();
73+ }
74+
75+ if (routable) {
5676 // loop -> platform migration: cancel on loop.
5777 if (result.routing .loop .erase (propertyName) > 0 ) {
5878 result.loop .removedProperties .push_back (propertyName);
5979 }
6080 result.routing .platform .insert (propertyName);
6181
6282 if (valueIt != config.changedProperties .end ()) {
63- auto valueNode = config.changedProperties .extract (valueIt);
83+ config.changedProperties .erase (valueIt);
6484 result.platform .changedProperties .push_back (
65- CSSPlatformTransitionRawEntry {propertyName, std::move (valueNode. mapped ()) , settings});
85+ CSSPlatformTransitionEntry {propertyName, *fromValue, *toValue , settings});
6686 }
6787 result.platform .changedPropertiesSettings .insert (std::move (settingsNode));
6888 } else {
@@ -84,8 +104,7 @@ CSSPlatformTransitionProxy::ProcessedConfig CSSPlatformTransitionProxy::processC
84104 // have consumed all of changedProperties.
85105 react_native_assert (config.changedProperties .empty () && " [Reanimated] CSS transition value diff without settings" );
86106
87- // Props JS asked to stop transitioning: look up the owning side in routing
88- // and forward the cancel there.
107+ // Forward removal cancels to the side that owns the property.
89108 for (auto &propertyName : config.removedProperties ) {
90109 if (result.routing .platform .erase (propertyName) > 0 ) {
91110 result.platform .removedProperties .push_back (std::move (propertyName));
@@ -97,4 +116,25 @@ CSSPlatformTransitionProxy::ProcessedConfig CSSPlatformTransitionProxy::processC
97116 return result;
98117}
99118
119+ CSSPlatformTransitionProxy::ProcessedDynamicDiffs CSSPlatformTransitionProxy::processDynamicDiffs (
120+ const CSSTransitionRouting &routing,
121+ const PropertyValueDynamicDiffsMap &propertyDiffs) const {
122+ ProcessedDynamicDiffs result;
123+ for (const auto &[propertyName, propertyDiff] : propertyDiffs) {
124+ // The routing was decided when the transition was registered; here we only
125+ // re-parse the toggled endpoints. Values the platform cannot express fall
126+ // back to the loop.
127+ if (routing.platform .contains (propertyName)) {
128+ auto fromValue = parseDynamicValue (propertyName, propertyDiff.first );
129+ auto toValue = parseDynamicValue (propertyName, propertyDiff.second );
130+ if (fromValue && toValue) {
131+ result.platform .emplace (propertyName, std::make_pair (*fromValue, *toValue));
132+ continue ;
133+ }
134+ }
135+ result.loop .emplace (propertyName, propertyDiff);
136+ }
137+ return result;
138+ }
139+
100140} // namespace reanimated::css
0 commit comments