Upd reanimated override in pnpm-workspace.yaml
This commit is contained in:
@@ -1,65 +0,0 @@
|
|||||||
# react-native-reanimated@4.4.2.patch
|
|
||||||
|
|
||||||
Backports of two merged upstream PRs:
|
|
||||||
|
|
||||||
1. PR 9901 (`LayoutAnimation.configureNext` compatibility)
|
|
||||||
2. PR 9971 (stale `settledProps` on worklet re-animation / after app resume)
|
|
||||||
|
|
||||||
## 1. Backport of PR 9901
|
|
||||||
|
|
||||||
Backport of https://github.com/software-mansion/react-native-reanimated/pull/9901
|
|
||||||
("refactor(LayoutAnimations): stop taking over UIManagerAnimationDelegate").
|
|
||||||
|
|
||||||
Reanimated's legacy `LayoutAnimationsProxy_Legacy` registered itself as the
|
|
||||||
`UIManagerAnimationDelegate` only to receive `stopSurface`. Occupying that slot
|
|
||||||
overwrites the `LayoutAnimationDriver` that React Native installs there, which
|
|
||||||
silently breaks `LayoutAnimation.configureNext` for the whole app.
|
|
||||||
|
|
||||||
The patch makes the proxy detect surface teardown itself via a
|
|
||||||
`UIManagerCommitHook` (a commit with an empty root marks the surface in
|
|
||||||
`surfacesToRemove_`), frees the animation-delegate slot, and drops final
|
|
||||||
keyframe `Update` mutations for views deleted in the same transaction (a
|
|
||||||
deterministic `configureNext` delete-animation crash found in this app).
|
|
||||||
`uiManager` moves from Android-only to shared constructor args since the hook
|
|
||||||
registration needs it on both platforms.
|
|
||||||
|
|
||||||
Only the `packages/react-native-reanimated` part of the PR is included (the
|
|
||||||
`apps/fabric-example` hunk is not part of the published package), and the
|
|
||||||
include hunk in `LayoutAnimationsProxy_Legacy.cpp` was adjusted to the 4.3.2
|
|
||||||
release sources.
|
|
||||||
|
|
||||||
## 2. Backport of PR 9971 (stale `settledProps`)
|
|
||||||
|
|
||||||
Verbatim application of
|
|
||||||
https://github.com/software-mansion/react-native-reanimated/pull/9971, the
|
|
||||||
4.3-stable cherry-pick of
|
|
||||||
https://github.com/software-mansion/react-native-reanimated/pull/9527
|
|
||||||
("Fix stale settledProps on worklet re-animation"). Fixes the Android DM
|
|
||||||
composer "phantom jump"
|
|
||||||
(https://github.com/software-mansion/react-native-reanimated/issues/9574).
|
|
||||||
|
|
||||||
Background: with `FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS`, once an
|
|
||||||
animation settles its final props are handed to JS (polled every 500 ms by
|
|
||||||
`PropsRegistryGarbageCollector`) and stored in React component state
|
|
||||||
(`settledProps`), after which the React-side snapshot becomes the sole owner
|
|
||||||
of the value.
|
|
||||||
|
|
||||||
The PR replaces `getUpdatesOlderThanTimestamp` (which evicted registry
|
|
||||||
entries on a wall-clock 1 s/2 s window) with `collectSettledUpdates`:
|
|
||||||
|
|
||||||
- `syncedTags_` / `invalidatedTags_` track which tags React already has a
|
|
||||||
snapshot for; when a previously-synced view re-animates, its stale snapshot
|
|
||||||
is refreshed on the next GC tick instead of waiting for the new value to
|
|
||||||
settle.
|
|
||||||
- Eviction is no longer time-based. An entry is only evicted on the tick
|
|
||||||
*after* it was returned to JS (once its `settledProps` commit is
|
|
||||||
guaranteed), so a missed timer window (app backgrounded, JS thread blocked)
|
|
||||||
can no longer destroy a settled value before it reaches React. This
|
|
||||||
replaces the ad-hoc eviction guard an earlier version of this patch added
|
|
||||||
on top of the pre-merge PR 9527.
|
|
||||||
- `PropsRegistryGarbageCollector` drops the separate `viewsCount` counter
|
|
||||||
(which could desync when nested animated components unregister a tag that
|
|
||||||
was never registered, stopping the GC interval while views remain) in favor
|
|
||||||
of `viewsMap.size`. Only `src/` is touched, matching the PR; Metro bundles
|
|
||||||
the app from `src/` via the package's `react-native` field, and the stale
|
|
||||||
`lib/` copy is unreachable (the feature is native-only).
|
|
||||||
+10
-214
@@ -1,155 +1,3 @@
|
|||||||
diff --git a/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp b/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp
|
|
||||||
index 2db064c..2f8c187 100644
|
|
||||||
--- a/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp
|
|
||||||
+++ b/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.cpp
|
|
||||||
@@ -5,8 +5,10 @@
|
|
||||||
|
|
||||||
#include <react/debug/react_native_assert.h>
|
|
||||||
|
|
||||||
+#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
+#include <vector>
|
|
||||||
|
|
||||||
namespace reanimated {
|
|
||||||
|
|
||||||
@@ -36,25 +38,59 @@ void AnimatedPropsRegistry::update(jsi::Runtime &rt, const jsi::Value &operation
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (StaticFeatureFlags::getFlag("FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS")) {
|
|
||||||
- timestampMap_[shadowNode->getTag()] = timestamp;
|
|
||||||
+ const auto tag = shadowNode->getTag();
|
|
||||||
+ timestampMap_[tag] = timestamp;
|
|
||||||
+ // If JS already has a `settledProps` snapshot for this tag, it is now
|
|
||||||
+ // stale — schedule a refresh on the next `collectSettledUpdates`.
|
|
||||||
+ if (syncedTags_.erase(tag) > 0) {
|
|
||||||
+ invalidatedTags_.insert(tag);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-jsi::Value AnimatedPropsRegistry::getUpdatesOlderThanTimestamp(
|
|
||||||
- jsi::Runtime &rt,
|
|
||||||
- const double timestamp,
|
|
||||||
- const double cleanupTimestamp) {
|
|
||||||
+jsi::Value AnimatedPropsRegistry::collectSettledUpdates(jsi::Runtime &rt, const double settledTimestamp) {
|
|
||||||
react_native_assert(UpdatesRegistryManager::isLockedByCurrentThread());
|
|
||||||
- removeUpdatesOlderThanTimestamp(cleanupTimestamp);
|
|
||||||
|
|
||||||
std::vector<std::pair<Tag, std::reference_wrapper<const folly::dynamic>>> updates;
|
|
||||||
|
|
||||||
- for (const auto &[viewTag, pair] : updatesRegistry_) {
|
|
||||||
- auto it = timestampMap_.find(viewTag);
|
|
||||||
- if (it != timestampMap_.end() && it->second < timestamp) {
|
|
||||||
- updates.emplace_back(viewTag, std::cref(pair.second));
|
|
||||||
+ for (auto it = updatesRegistry_.begin(); it != updatesRegistry_.end();) {
|
|
||||||
+ const auto viewTag = it->first;
|
|
||||||
+
|
|
||||||
+ if (syncedTags_.contains(viewTag)) {
|
|
||||||
+ // React already has the latest value for this tag (synced on a previous
|
|
||||||
+ // call, so the `settledProps` state is committed by now) — the registry
|
|
||||||
+ // entry is redundant. `syncedTags_` is intentionally retained to detect
|
|
||||||
+ // re-animation staleness. Note that `syncedTags_` and `invalidatedTags_`
|
|
||||||
+ // are disjoint — `update()` moves tags from the former to the latter.
|
|
||||||
+ timestampMap_.erase(viewTag);
|
|
||||||
+ it = updatesRegistry_.erase(it);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ const auto timestampIt = timestampMap_.find(viewTag);
|
|
||||||
+ if (timestampIt == timestampMap_.end()) {
|
|
||||||
+ ++it;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ const bool isSettled = timestampIt->second < settledTimestamp;
|
|
||||||
+ const auto invalidatedIt = invalidatedTags_.find(viewTag);
|
|
||||||
+ const bool isInvalidated = invalidatedIt != invalidatedTags_.end();
|
|
||||||
+ if (isSettled || isInvalidated) {
|
|
||||||
+ updates.emplace_back(viewTag, std::cref(it->second.second));
|
|
||||||
+ if (isSettled) {
|
|
||||||
+ // Only settled-path tags are tracked as "synced" so that an ongoing
|
|
||||||
+ // animation doesn't re-trigger an invalidation/sync on every GC tick.
|
|
||||||
+ syncedTags_.insert(viewTag);
|
|
||||||
+ }
|
|
||||||
+ if (isInvalidated) {
|
|
||||||
+ // Only erase serviced invalidations; if a tag was invalidated but the
|
|
||||||
+ // matching update batch hasn't been flushed into updatesRegistry_ yet,
|
|
||||||
+ // we leave the entry so the next sync picks it up.
|
|
||||||
+ invalidatedTags_.erase(invalidatedIt);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
+ ++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
const jsi::Array array(rt, updates.size());
|
|
||||||
@@ -69,22 +105,11 @@ jsi::Value AnimatedPropsRegistry::getUpdatesOlderThanTimestamp(
|
|
||||||
return jsi::Value(rt, array);
|
|
||||||
}
|
|
||||||
|
|
||||||
-void AnimatedPropsRegistry::removeUpdatesOlderThanTimestamp(const double timestamp) {
|
|
||||||
- for (auto it = timestampMap_.begin(); it != timestampMap_.end();) {
|
|
||||||
- const auto viewTag = it->first;
|
|
||||||
- const auto viewTimestamp = it->second;
|
|
||||||
- if (viewTimestamp < timestamp) {
|
|
||||||
- it = timestampMap_.erase(it);
|
|
||||||
- updatesRegistry_.erase(viewTag);
|
|
||||||
- } else {
|
|
||||||
- it++;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
void AnimatedPropsRegistry::removeTag(const Tag tag) {
|
|
||||||
updatesRegistry_.erase(tag);
|
|
||||||
timestampMap_.erase(tag);
|
|
||||||
+ syncedTags_.erase(tag);
|
|
||||||
+ invalidatedTags_.erase(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace reanimated
|
|
||||||
diff --git a/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h b/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h
|
|
||||||
index 2197eec..a9cb24c 100644
|
|
||||||
--- a/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h
|
|
||||||
+++ b/Common/cpp/reanimated/Fabric/updates/AnimatedPropsRegistry.h
|
|
||||||
@@ -4,10 +4,8 @@
|
|
||||||
|
|
||||||
#include <react/renderer/uimanager/UIManager.h>
|
|
||||||
|
|
||||||
-#include <memory>
|
|
||||||
-#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
-#include <vector>
|
|
||||||
+#include <unordered_set>
|
|
||||||
|
|
||||||
namespace reanimated {
|
|
||||||
|
|
||||||
@@ -15,13 +13,22 @@ class AnimatedPropsRegistry : public UpdatesRegistry {
|
|
||||||
public:
|
|
||||||
void update(jsi::Runtime &rt, const jsi::Value &operations, double timestamp);
|
|
||||||
|
|
||||||
- /// Also removes updates older than `cleanupTimestamp` from the registry.
|
|
||||||
- jsi::Value getUpdatesOlderThanTimestamp(jsi::Runtime &rt, double timestamp, double cleanupTimestamp);
|
|
||||||
+ /// Returns updates that settled (received no update since `settledTimestamp`)
|
|
||||||
+ /// or whose synced `settledProps` snapshot was invalidated by a fresh update.
|
|
||||||
+ /// Also evicts entries that have already been synced to React — by the time
|
|
||||||
+ /// of the next call, the corresponding `settledProps` state is guaranteed to
|
|
||||||
+ /// be committed, so the registry entries are redundant.
|
|
||||||
+ jsi::Value collectSettledUpdates(jsi::Runtime &rt, double settledTimestamp);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<Tag, double> timestampMap_;
|
|
||||||
+ // Tags whose latest values have already been pushed to React `settledProps`.
|
|
||||||
+ // Intentionally retained after eviction to detect re-animation staleness.
|
|
||||||
+ std::unordered_set<Tag> syncedTags_;
|
|
||||||
+ // Tags that were synced to React but received a fresh worklet update since;
|
|
||||||
+ // their `settledProps` are stale and need to be refreshed on the next sync.
|
|
||||||
+ std::unordered_set<Tag> invalidatedTags_;
|
|
||||||
|
|
||||||
- void removeUpdatesOlderThanTimestamp(double timestamp);
|
|
||||||
void removeTag(Tag tag) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h
|
diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h
|
||||||
index 8603591..20d042b 100644
|
index 8603591..20d042b 100644
|
||||||
--- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h
|
--- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h
|
||||||
@@ -195,10 +43,10 @@ index 8603591..20d042b 100644
|
|||||||
|
|
||||||
void restoreOpacityInCaseOfFlakyEnteringAnimation(SurfaceId surfaceId) const;
|
void restoreOpacityInCaseOfFlakyEnteringAnimation(SurfaceId surfaceId) const;
|
||||||
diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h
|
diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h
|
||||||
index eca44e4..e39c79a 100644
|
index fcc677f..115971a 100644
|
||||||
--- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h
|
--- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h
|
||||||
+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h
|
+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Experimental.h
|
||||||
@@ -66,11 +66,11 @@ struct LayoutAnimationsProxy_Experimental : public LayoutAnimationsProxyCommon,
|
@@ -67,11 +67,11 @@ struct LayoutAnimationsProxy_Experimental : public LayoutAnimationsProxyCommon,
|
||||||
const SharedComponentDescriptorRegistry &componentDescriptorRegistry,
|
const SharedComponentDescriptorRegistry &componentDescriptorRegistry,
|
||||||
const std::shared_ptr<const ContextContainer> &contextContainer,
|
const std::shared_ptr<const ContextContainer> &contextContainer,
|
||||||
jsi::Runtime &uiRuntime,
|
jsi::Runtime &uiRuntime,
|
||||||
@@ -212,7 +60,7 @@ index eca44e4..e39c79a 100644
|
|||||||
const std::shared_ptr<CallInvoker> &jsInvoker
|
const std::shared_ptr<CallInvoker> &jsInvoker
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
@@ -79,11 +79,11 @@ struct LayoutAnimationsProxy_Experimental : public LayoutAnimationsProxyCommon,
|
@@ -80,11 +80,11 @@ struct LayoutAnimationsProxy_Experimental : public LayoutAnimationsProxyCommon,
|
||||||
componentDescriptorRegistry,
|
componentDescriptorRegistry,
|
||||||
contextContainer,
|
contextContainer,
|
||||||
uiRuntime,
|
uiRuntime,
|
||||||
@@ -227,7 +75,7 @@ index eca44e4..e39c79a 100644
|
|||||||
#endif
|
#endif
|
||||||
),
|
),
|
||||||
diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp
|
diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp
|
||||||
index a3927af..13833b7 100644
|
index df53d8d..735f138 100644
|
||||||
--- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp
|
--- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp
|
||||||
+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp
|
+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp
|
||||||
@@ -1,6 +1,7 @@
|
@@ -1,6 +1,7 @@
|
||||||
@@ -238,7 +86,7 @@ index a3927af..13833b7 100644
|
|||||||
#include <react/renderer/mounting/ShadowViewMutation.h>
|
#include <react/renderer/mounting/ShadowViewMutation.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -58,14 +59,37 @@ std::optional<MountingTransaction> LayoutAnimationsProxy_Legacy::pullTransaction
|
@@ -60,14 +61,37 @@ std::optional<MountingTransaction> LayoutAnimationsProxy_Legacy::pullTransaction
|
||||||
|
|
||||||
parseRemoveMutations(movedViews, mutations, roots);
|
parseRemoveMutations(movedViews, mutations, roots);
|
||||||
|
|
||||||
@@ -278,7 +126,7 @@ index a3927af..13833b7 100644
|
|||||||
return MountingTransaction{surfaceId, transactionNumber, std::move(filteredMutations), telemetry};
|
return MountingTransaction{surfaceId, transactionNumber, std::move(filteredMutations), telemetry};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -959,23 +983,22 @@ inline bool MutationNode::isMutationNode() {
|
@@ -998,23 +1022,22 @@ inline bool MutationNode::isMutationNode() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +166,7 @@ index a3927af..13833b7 100644
|
|||||||
|
|
||||||
} // namespace reanimated
|
} // namespace reanimated
|
||||||
diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h
|
diff --git a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h
|
||||||
index e9a5e99..a2c8904 100644
|
index 57cc134..1a2966c 100644
|
||||||
--- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h
|
--- a/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h
|
||||||
+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h
|
+++ b/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.h
|
||||||
@@ -3,8 +3,8 @@
|
@@ -3,8 +3,8 @@
|
||||||
@@ -376,7 +224,7 @@ index e9a5e99..a2c8904 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startEnteringAnimation(const int tag, ShadowViewMutation &mutation) const;
|
void startEnteringAnimation(const int tag, ShadowViewMutation &mutation) const;
|
||||||
@@ -202,19 +207,15 @@ struct LayoutAnimationsProxy_Legacy : public LayoutAnimationsProxyCommon,
|
@@ -206,19 +211,15 @@ struct LayoutAnimationsProxy_Legacy : public LayoutAnimationsProxyCommon,
|
||||||
const TransactionTelemetry &telemetry,
|
const TransactionTelemetry &telemetry,
|
||||||
ShadowViewMutationList mutations) const override;
|
ShadowViewMutationList mutations) const override;
|
||||||
|
|
||||||
@@ -404,30 +252,10 @@ index e9a5e99..a2c8904 100644
|
|||||||
|
|
||||||
} // namespace reanimated
|
} // namespace reanimated
|
||||||
diff --git a/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp b/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
|
diff --git a/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp b/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
|
||||||
index 60c88ec..a23545a 100644
|
index 2b68ff7..d08b1ae 100644
|
||||||
--- a/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
|
--- a/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
|
||||||
+++ b/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
|
+++ b/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp
|
||||||
@@ -641,16 +641,14 @@ jsi::Value ReanimatedModuleProxy::getSettledUpdates(jsi::Runtime &rt) {
|
@@ -1235,22 +1235,19 @@ void ReanimatedModuleProxy::initializeLayoutAnimationsProxy() {
|
||||||
StaticFeatureFlags::getFlag("FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS") &&
|
|
||||||
"getSettledUpdates requires FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS static feature flag to be enabled");
|
|
||||||
|
|
||||||
+ constexpr double SETTLED_ANIMATION_THRESHOLD_MS = 1000;
|
|
||||||
+
|
|
||||||
// TODO(future): use unified timestamp
|
|
||||||
const auto currentTimestamp = getAnimationTimestamp_();
|
|
||||||
|
|
||||||
- // TODO: fix bug when threshold difference is smaller than 1 second
|
|
||||||
// TODO(future): flush updates from CSS animations and CSS transitions registries
|
|
||||||
- // TODO(future): find a better way to obtain timestamp for removing updates
|
|
||||||
- // TODO(future): move removing old updates to separate method
|
|
||||||
auto lock = updatesRegistryManager_->lock();
|
|
||||||
- return animatedPropsRegistry_->getUpdatesOlderThanTimestamp(
|
|
||||||
- rt, currentTimestamp - 1000 /* 1 second */, currentTimestamp - 2000 /* 2 seconds */);
|
|
||||||
+ return animatedPropsRegistry_->collectSettledUpdates(rt, currentTimestamp - SETTLED_ANIMATION_THRESHOLD_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReanimatedModuleProxy::handleEvent(
|
|
||||||
@@ -1227,22 +1225,19 @@ void ReanimatedModuleProxy::initializeLayoutAnimationsProxy() {
|
|
||||||
#endif
|
#endif
|
||||||
layoutAnimationsProxy_ = std::move(layoutAnimationsProxyExperimental);
|
layoutAnimationsProxy_ = std::move(layoutAnimationsProxyExperimental);
|
||||||
} else {
|
} else {
|
||||||
@@ -453,35 +281,3 @@ index 60c88ec..a23545a 100644
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/src/PropsRegistryGarbageCollector.ts b/src/PropsRegistryGarbageCollector.ts
|
|
||||||
index f917ce5..32148fb 100644
|
|
||||||
--- a/src/PropsRegistryGarbageCollector.ts
|
|
||||||
+++ b/src/PropsRegistryGarbageCollector.ts
|
|
||||||
@@ -11,7 +11,6 @@ import { ReanimatedModule } from './ReanimatedModule';
|
|
||||||
const FLUSH_INTERVAL_MS = 500;
|
|
||||||
|
|
||||||
export const PropsRegistryGarbageCollector = {
|
|
||||||
- viewsCount: 0,
|
|
||||||
viewsMap: new Map<number, IAnimatedComponentInternal>(),
|
|
||||||
intervalId: null as NodeJS.Timeout | null,
|
|
||||||
|
|
||||||
@@ -25,16 +24,14 @@ export const PropsRegistryGarbageCollector = {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.viewsMap.set(viewTag, component);
|
|
||||||
- this.viewsCount++;
|
|
||||||
- if (this.viewsCount === 1) {
|
|
||||||
+ if (this.viewsMap.size === 1) {
|
|
||||||
this.registerInterval();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
unregisterView(viewTag: number) {
|
|
||||||
- this.viewsMap.delete(viewTag);
|
|
||||||
- this.viewsCount--;
|
|
||||||
- if (this.viewsCount === 0) {
|
|
||||||
+ const deleted = this.viewsMap.delete(viewTag);
|
|
||||||
+ if (deleted && this.viewsMap.size === 0) {
|
|
||||||
this.unregisterInterval();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# react-native-reanimated@4.5.3.patch
|
||||||
|
|
||||||
|
Backport of https://github.com/software-mansion/react-native-reanimated/pull/9901
|
||||||
|
("refactor(LayoutAnimations): stop taking over UIManagerAnimationDelegate").
|
||||||
|
|
||||||
|
Reanimated's legacy `LayoutAnimationsProxy_Legacy` registered itself as the
|
||||||
|
`UIManagerAnimationDelegate` only to receive `stopSurface`. Occupying that slot
|
||||||
|
overwrites the `LayoutAnimationDriver` that React Native installs there, which
|
||||||
|
silently breaks `LayoutAnimation.configureNext` for the whole app.
|
||||||
|
|
||||||
|
The patch makes the proxy detect surface teardown itself via a
|
||||||
|
`UIManagerCommitHook` (a commit with an empty root marks the surface in
|
||||||
|
`surfacesToRemove_`), frees the animation-delegate slot, and drops final
|
||||||
|
keyframe `Update` mutations for views deleted in the same transaction (a
|
||||||
|
deterministic `configureNext` delete-animation crash found in this app).
|
||||||
|
`uiManager` moves from Android-only to shared constructor args since the hook
|
||||||
|
registration needs it on both platforms.
|
||||||
|
|
||||||
|
Only the `packages/react-native-reanimated` part of the PR is included (the
|
||||||
|
`apps/fabric-example` hunk is not part of the published package), and the hunks
|
||||||
|
were rebased onto the 4.5.3 release sources.
|
||||||
|
|
||||||
|
Note that upstream's own `pullTransaction` rework in 4.5.3 (the new
|
||||||
|
`reconcileContradictedRemovals`) covers a different case - a `Create`/`Insert`
|
||||||
|
contradicting a *withheld* exit removal - and does not subsume the deleted-tag
|
||||||
|
`Update` filter here, which guards against the `LayoutAnimationDriver` final
|
||||||
|
keyframe. That driver only runs at all once this patch frees the delegate slot.
|
||||||
+3
-3
@@ -9,8 +9,8 @@ overrides:
|
|||||||
'@expo/image-utils': '0.8.12'
|
'@expo/image-utils': '0.8.12'
|
||||||
'@types/estree': '1.0.6'
|
'@types/estree': '1.0.6'
|
||||||
'react-native-compressor': '1.13.0'
|
'react-native-compressor': '1.13.0'
|
||||||
'react-native-reanimated': '4.4.2'
|
'react-native-reanimated': '4.5.3'
|
||||||
'react-native-worklets': '0.10.0'
|
'react-native-worklets': '0.11.3'
|
||||||
'psl': '1.9.0'
|
'psl': '1.9.0'
|
||||||
'@types/psl': '1.1.1'
|
'@types/psl': '1.1.1'
|
||||||
'react-native-screens': '4.26.2'
|
'react-native-screens': '4.26.2'
|
||||||
@@ -32,7 +32,7 @@ patchedDependencies:
|
|||||||
'react-native-drawer-layout@4.2.3': patches/react-native-drawer-layout@4.2.3.patch
|
'react-native-drawer-layout@4.2.3': patches/react-native-drawer-layout@4.2.3.patch
|
||||||
'react-native-keyboard-controller@1.21.9': patches/react-native-keyboard-controller@1.21.9.patch
|
'react-native-keyboard-controller@1.21.9': patches/react-native-keyboard-controller@1.21.9.patch
|
||||||
'react-native-pager-view@6.8.0': patches/react-native-pager-view@6.8.0.patch
|
'react-native-pager-view@6.8.0': patches/react-native-pager-view@6.8.0.patch
|
||||||
'react-native-reanimated@4.4.2': patches/react-native-reanimated@4.4.2.patch
|
'react-native-reanimated@4.5.3': patches/react-native-reanimated@4.5.3.patch
|
||||||
'react-native-screens@4.26.2': patches/react-native-screens@4.26.2.patch
|
'react-native-screens@4.26.2': patches/react-native-screens@4.26.2.patch
|
||||||
'react-native-svg@15.15.4': patches/react-native-svg@15.15.4.patch
|
'react-native-svg@15.15.4': patches/react-native-svg@15.15.4.patch
|
||||||
react-native-worklets@0.8.3: patches/react-native-worklets@0.8.3.patch
|
react-native-worklets@0.8.3: patches/react-native-worklets@0.8.3.patch
|
||||||
|
|||||||
Reference in New Issue
Block a user