react-native-reanimated 4.7.0 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.cpp +34 -2
  2. package/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.h +15 -1
  3. package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.cpp +9 -0
  4. package/Common/cpp/reanimated/Fabric/ReanimatedMountHook.h +3 -0
  5. package/Common/cpp/reanimated/Fabric/updates/SynchronousWritesTracker.cpp +103 -0
  6. package/Common/cpp/reanimated/Fabric/updates/SynchronousWritesTracker.h +74 -0
  7. package/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.cpp +15 -0
  8. package/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.h +5 -0
  9. package/Common/cpp/reanimated/Fabric/updates/UpdatesRegistryManager.cpp +10 -0
  10. package/Common/cpp/reanimated/Fabric/updates/UpdatesRegistryManager.h +3 -0
  11. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.cpp +97 -54
  12. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.h +5 -1
  13. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.cpp +23 -5
  14. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxyCommon.h +17 -1
  15. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy_Legacy.cpp +9 -9
  16. package/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.h +35 -8
  17. package/Common/cpp/reanimated/LayoutAnimations/PropsDiffer.h +2 -2
  18. package/Common/cpp/reanimated/LayoutAnimations/SharedTransitions.cpp +11 -11
  19. package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +75 -2
  20. package/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h +11 -1
  21. package/Common/cpp/reanimated/Tools/PlatformDepMethodsHolder.h +4 -1
  22. package/android/src/main/cpp/reanimated/android/NativeProxy.cpp +13 -3
  23. package/android/src/main/cpp/reanimated/android/NativeProxy.h +2 -0
  24. package/android/src/main/java/com/swmansion/reanimated/NativeProxy.kt +84 -9
  25. package/android/src/main/java/com/swmansion/reanimated/NodesManager.kt +2 -4
  26. package/android/src/main/java/com/swmansion/reanimated/nativeProxy/EventHandler.kt +4 -3
  27. package/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensor.kt +1 -1
  28. package/android/src/main/java/com/swmansion/reanimated/sensor/ReanimatedSensorListener.kt +44 -33
  29. package/apple/reanimated/apple/REASynchronousPropsRewriter.h +18 -0
  30. package/apple/reanimated/apple/REASynchronousPropsRewriter.mm +37 -0
  31. package/apple/reanimated/apple/ReanimatedModule.mm +7 -0
  32. package/apple/reanimated/apple/keyboardObserver/REAKeyboardEventObserver.mm +20 -3
  33. package/apple/reanimated/apple/native/PlatformDepMethodsHolderImpl.mm +24 -1
  34. package/lib/module/animation/timing.js +15 -2
  35. package/lib/module/animation/timing.js.map +1 -1
  36. package/lib/module/platform-specific/jsVersion.js +1 -1
  37. package/lib/typescript/animation/timing.d.ts.map +1 -1
  38. package/lib/typescript/platform-specific/jsVersion.d.ts +1 -1
  39. package/package.json +3 -1
  40. package/src/animation/timing.ts +20 -2
  41. package/src/platform-specific/jsVersion.ts +1 -1
@@ -16,11 +16,13 @@ ReanimatedCommitHook::ReanimatedCommitHook(
16
16
  const std::shared_ptr<UIManager> &uiManager,
17
17
  const std::shared_ptr<UpdatesRegistryManager> &updatesRegistryManager,
18
18
  const std::shared_ptr<css::ViewStylesRepository> &viewStylesRepository,
19
- const std::shared_ptr<LayoutAnimationsProxyRegistry> &layoutAnimationsProxyRegistry)
19
+ const std::shared_ptr<LayoutAnimationsProxyRegistry> &layoutAnimationsProxyRegistry,
20
+ const std::shared_ptr<SynchronousWritesTracker> &synchronousWritesTracker)
20
21
  : uiManager_(uiManager),
21
22
  updatesRegistryManager_(updatesRegistryManager),
22
23
  viewStylesRepository_(viewStylesRepository),
23
- layoutAnimationsProxyRegistry_(layoutAnimationsProxyRegistry) {
24
+ layoutAnimationsProxyRegistry_(layoutAnimationsProxyRegistry),
25
+ synchronousWritesTracker_(synchronousWritesTracker) {
24
26
  uiManager_->registerCommitHook(*this);
25
27
  uiManager_->getShadowTreeRegistry().enumerate(
26
28
  [this](const ShadowTree &shadowTree, bool & /*stop*/) { registerLayoutAnimations(shadowTree); });
@@ -57,6 +59,9 @@ RootShadowNode::Unshared ReanimatedCommitHook::shadowTreeWillCommit(
57
59
  // A stopping surface commits an empty root; its mount is not reported on a paused Android host.
58
60
  auto lock = updatesRegistryManager_->lock();
59
61
  viewStylesRepository_->removeSurface(shadowTree.getSurfaceId());
62
+ if (synchronousWritesTracker_) {
63
+ synchronousWritesTracker_->onSurfaceStop(shadowTree.getSurfaceId());
64
+ }
60
65
  }
61
66
 
62
67
  auto reaShadowNode = std::reinterpret_pointer_cast<ReanimatedCommitShadowNode>(newRootShadowNode);
@@ -66,6 +71,7 @@ RootShadowNode::Unshared ReanimatedCommitHook::shadowTreeWillCommit(
66
71
  // the updates registry manager
67
72
  reaShadowNode->unsetReanimatedCommitTrait();
68
73
  reaShadowNode->setReanimatedMountTrait();
74
+ trackCommit(newRootShadowNode, false);
69
75
  return newRootShadowNode;
70
76
  }
71
77
 
@@ -74,6 +80,7 @@ RootShadowNode::Unshared ReanimatedCommitHook::shadowTreeWillCommit(
74
80
  // which means that all animation changes are already included.
75
81
  // Therefore, there's no need to reapply styles from the props map.
76
82
  if (commitOptions.source != ShadowTreeCommitSource::React) {
83
+ trackCommit(newRootShadowNode, false);
77
84
  return newRootShadowNode;
78
85
  }
79
86
  }
@@ -90,6 +97,8 @@ RootShadowNode::Unshared ReanimatedCommitHook::shadowTreeWillCommit(
90
97
  updatesRegistryManager_->cancelCommitAfterPause();
91
98
 
92
99
  rootNode = cloneShadowTreeWithNewProps(*rootNode, propsMap);
100
+ // Must share the registry lock with `collectProps`, or a write can get the epoch of a snapshot that lacks it.
101
+ trackCommit(rootNode, true);
93
102
  // If the commit comes from React Native then pause commits from
94
103
  // Reanimated since the ShadowTree to be committed by Reanimated may not
95
104
  // include the new changes from React Native yet and all changes of animated
@@ -104,4 +113,27 @@ RootShadowNode::Unshared ReanimatedCommitHook::shadowTreeWillCommit(
104
113
  return rootNode;
105
114
  }
106
115
 
116
+ #if REACT_NATIVE_VERSION_MINOR >= 88
117
+ void ReanimatedCommitHook::shadowTreeDidCommit(
118
+ const ShadowTree &,
119
+ const RootShadowNode::Shared &rootShadowNode,
120
+ const std::vector<const LayoutableShadowNode *> &) noexcept {
121
+ if (synchronousWritesTracker_) {
122
+ synchronousWritesTracker_->onDidCommit(rootShadowNode);
123
+ }
124
+ }
125
+ #endif
126
+
127
+ void ReanimatedCommitHook::trackCommit(const RootShadowNode::Shared &rootShadowNode, const bool carriesRegistryValues)
128
+ const {
129
+ if (!synchronousWritesTracker_) {
130
+ return;
131
+ }
132
+ synchronousWritesTracker_->onWillCommit(rootShadowNode, carriesRegistryValues);
133
+ #if REACT_NATIVE_VERSION_MINOR < 88
134
+ // Before 0.88 there is no `shadowTreeDidCommit`. The root that this hook returns is the only one available.
135
+ synchronousWritesTracker_->onDidCommit(rootShadowNode);
136
+ #endif
137
+ }
138
+
107
139
  } // namespace reanimated
@@ -1,12 +1,15 @@
1
1
  #pragma once
2
2
 
3
3
  #include <reanimated/CSS/misc/ViewStylesRepository.h>
4
+ #include <reanimated/Compat/ReactNativeVersionCompat.h>
5
+ #include <reanimated/Fabric/updates/SynchronousWritesTracker.h>
4
6
  #include <reanimated/Fabric/updates/UpdatesRegistryManager.h>
5
7
  #include <reanimated/LayoutAnimations/LayoutAnimationsProxyRegistry.h>
6
8
 
7
9
  #include <react/renderer/uimanager/UIManagerCommitHook.h>
8
10
 
9
11
  #include <memory>
12
+ #include <vector>
10
13
 
11
14
  using namespace facebook::react;
12
15
 
@@ -18,7 +21,8 @@ class ReanimatedCommitHook : public UIManagerCommitHook {
18
21
  const std::shared_ptr<UIManager> &uiManager,
19
22
  const std::shared_ptr<UpdatesRegistryManager> &updatesRegistryManager,
20
23
  const std::shared_ptr<css::ViewStylesRepository> &viewStylesRepository,
21
- const std::shared_ptr<LayoutAnimationsProxyRegistry> &layoutAnimationsProxyRegistry);
24
+ const std::shared_ptr<LayoutAnimationsProxyRegistry> &layoutAnimationsProxyRegistry,
25
+ const std::shared_ptr<SynchronousWritesTracker> &synchronousWritesTracker);
22
26
 
23
27
  ~ReanimatedCommitHook() noexcept override;
24
28
 
@@ -34,11 +38,21 @@ class ReanimatedCommitHook : public UIManagerCommitHook {
34
38
  RootShadowNode::Unshared const &newRootShadowNode,
35
39
  const ShadowTreeCommitOptions &commitOptions) noexcept override;
36
40
 
41
+ #if REACT_NATIVE_VERSION_MINOR >= 88
42
+ void shadowTreeDidCommit(
43
+ const ShadowTree &shadowTree,
44
+ const RootShadowNode::Shared &rootShadowNode,
45
+ const std::vector<const LayoutableShadowNode *> &affectedLayoutableNodes) noexcept override;
46
+ #endif
47
+
37
48
  private:
49
+ void trackCommit(const RootShadowNode::Shared &rootShadowNode, bool carriesRegistryValues) const;
50
+
38
51
  std::shared_ptr<UIManager> uiManager_;
39
52
  std::shared_ptr<UpdatesRegistryManager> updatesRegistryManager_;
40
53
  std::shared_ptr<css::ViewStylesRepository> viewStylesRepository_;
41
54
  std::shared_ptr<LayoutAnimationsProxyRegistry> layoutAnimationsProxyRegistry_;
55
+ std::shared_ptr<SynchronousWritesTracker> synchronousWritesTracker_;
42
56
  };
43
57
 
44
58
  } // namespace reanimated
@@ -12,11 +12,13 @@ ReanimatedMountHook::ReanimatedMountHook(
12
12
  const std::shared_ptr<UpdatesRegistryManager> &updatesRegistryManager,
13
13
  const std::shared_ptr<css::ViewStylesRepository> &viewStylesRepository,
14
14
  const std::shared_ptr<LayoutAnimationsProxyRegistry> &layoutAnimationsProxyRegistry,
15
+ const std::shared_ptr<SynchronousWritesTracker> &synchronousWritesTracker,
15
16
  const std::function<void()> &requestFlush)
16
17
  : uiManager_(uiManager),
17
18
  updatesRegistryManager_(updatesRegistryManager),
18
19
  viewStylesRepository_(viewStylesRepository),
19
20
  layoutAnimationsProxyRegistry_(layoutAnimationsProxyRegistry),
21
+ synchronousWritesTracker_(synchronousWritesTracker),
20
22
  requestFlush_(requestFlush) {
21
23
  uiManager_->registerMountHook(*this);
22
24
  }
@@ -35,6 +37,10 @@ void ReanimatedMountHook::shadowTreeDidMount(
35
37
  return;
36
38
  }
37
39
 
40
+ if (synchronousWritesTracker_) {
41
+ synchronousWritesTracker_->onMountReport(rootShadowNode);
42
+ }
43
+
38
44
  auto reaShadowNode = std::reinterpret_pointer_cast<ReanimatedCommitShadowNode>(
39
45
  std::const_pointer_cast<RootShadowNode>(rootShadowNode));
40
46
 
@@ -73,6 +79,9 @@ void ReanimatedMountHook::shadowTreeDidUnmount(SurfaceId surfaceId, HighResTimeS
73
79
  if (layoutAnimationsProxyRegistry_) {
74
80
  layoutAnimationsProxyRegistry_->remove(surfaceId);
75
81
  }
82
+ if (synchronousWritesTracker_) {
83
+ synchronousWritesTracker_->onSurfaceStop(surfaceId);
84
+ }
76
85
 
77
86
  auto lock = updatesRegistryManager_->lock();
78
87
  viewStylesRepository_->removeSurface(surfaceId);
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include <reanimated/CSS/misc/ViewStylesRepository.h>
4
4
  #include <reanimated/Fabric/ShadowTreeCloner.h>
5
+ #include <reanimated/Fabric/updates/SynchronousWritesTracker.h>
5
6
  #include <reanimated/Fabric/updates/UpdatesRegistryManager.h>
6
7
  #include <reanimated/LayoutAnimations/LayoutAnimationsProxyRegistry.h>
7
8
 
@@ -20,6 +21,7 @@ class ReanimatedMountHook : public UIManagerMountHook {
20
21
  const std::shared_ptr<UpdatesRegistryManager> &updatesRegistryManager,
21
22
  const std::shared_ptr<css::ViewStylesRepository> &viewStylesRepository,
22
23
  const std::shared_ptr<LayoutAnimationsProxyRegistry> &layoutAnimationsProxyRegistry,
24
+ const std::shared_ptr<SynchronousWritesTracker> &synchronousWritesTracker,
23
25
  const std::function<void()> &requestFlush);
24
26
  ~ReanimatedMountHook() noexcept override;
25
27
 
@@ -32,6 +34,7 @@ class ReanimatedMountHook : public UIManagerMountHook {
32
34
  const std::shared_ptr<UpdatesRegistryManager> updatesRegistryManager_;
33
35
  const std::shared_ptr<css::ViewStylesRepository> viewStylesRepository_;
34
36
  const std::shared_ptr<LayoutAnimationsProxyRegistry> layoutAnimationsProxyRegistry_;
37
+ const std::shared_ptr<SynchronousWritesTracker> synchronousWritesTracker_;
35
38
  const std::function<void()> requestFlush_;
36
39
  };
37
40
 
@@ -0,0 +1,103 @@
1
+ #include <reanimated/Fabric/updates/SynchronousWritesTracker.h>
2
+
3
+ #include <algorithm>
4
+
5
+ namespace reanimated {
6
+
7
+ void SynchronousWritesTracker::onWillCommit(
8
+ const RootShadowNode::Shared &rootShadowNode,
9
+ const bool carriesRegistryValues) {
10
+ auto lock = std::scoped_lock{mutex_};
11
+ const auto threadId = std::this_thread::get_id();
12
+ pendingCommits_.erase(threadId);
13
+ if (rootShadowNode->getChildren().empty()) {
14
+ return;
15
+ }
16
+ const auto surfaceId = rootShadowNode->getSurfaceId();
17
+ auto &surface = surfaces_[surfaceId];
18
+ if (carriesRegistryValues) {
19
+ surface.epoch++;
20
+ }
21
+ pendingCommits_.emplace(threadId, PendingCommit{surfaceId, surface.epoch});
22
+ }
23
+
24
+ void SynchronousWritesTracker::onDidCommit(const RootShadowNode::Shared &rootShadowNode) {
25
+ auto lock = std::scoped_lock{mutex_};
26
+ const auto pendingCommit = pendingCommits_.extract(std::this_thread::get_id());
27
+ if (pendingCommit.empty() || pendingCommit.mapped().surfaceId != rootShadowNode->getSurfaceId()) {
28
+ return;
29
+ }
30
+ const auto surfaceIt = surfaces_.find(pendingCommit.mapped().surfaceId);
31
+ if (surfaceIt == surfaces_.end()) {
32
+ return;
33
+ }
34
+ rememberRoot(surfaceIt->second, rootShadowNode, pendingCommit.mapped().epoch);
35
+ }
36
+
37
+ void SynchronousWritesTracker::rememberRoot(
38
+ SurfaceState &surface,
39
+ const RootShadowNode::Shared &rootShadowNode,
40
+ const Epoch epoch) {
41
+ auto &committedRoots = surface.committedRoots;
42
+ while (!committedRoots.empty() && committedRoots.front().rootShadowNode.expired()) {
43
+ committedRoots.pop_front();
44
+ }
45
+ committedRoots.push_back({rootShadowNode, epoch});
46
+ }
47
+
48
+ void SynchronousWritesTracker::onSynchronousWrite(const UpdatesBatch &synchronousUpdatesBatch) {
49
+ auto lock = std::scoped_lock{mutex_};
50
+ for (const auto &[shadowNodeFamily, props] : synchronousUpdatesBatch) {
51
+ const auto surfaceIt = surfaces_.find(shadowNodeFamily->getSurfaceId());
52
+ if (surfaceIt == surfaces_.end() || surfaceIt->second.epoch == surfaceIt->second.mountedEpoch) {
53
+ continue;
54
+ }
55
+ auto &surface = surfaceIt->second;
56
+ surface.writes.insert_or_assign(shadowNodeFamily->getTag(), Write{shadowNodeFamily, surface.epoch});
57
+ }
58
+ }
59
+
60
+ void SynchronousWritesTracker::onMountReport(const RootShadowNode::Shared &mountedRootShadowNode) {
61
+ auto lock = std::scoped_lock{mutex_};
62
+ const auto surfaceIt = surfaces_.find(mountedRootShadowNode->getSurfaceId());
63
+ if (surfaceIt == surfaces_.end()) {
64
+ return;
65
+ }
66
+ auto &surface = surfaceIt->second;
67
+ auto &committedRoots = surface.committedRoots;
68
+ const auto it = std::find_if(committedRoots.begin(), committedRoots.end(), [&](const CommittedRoot &root) {
69
+ return root.rootShadowNode.lock() == mountedRootShadowNode;
70
+ });
71
+ if (it == committedRoots.end()) {
72
+ return;
73
+ }
74
+ surface.reportedEpoch = it->epoch;
75
+ committedRoots.erase(committedRoots.begin(), it + 1);
76
+ }
77
+
78
+ void SynchronousWritesTracker::onSurfaceStop(const SurfaceId surfaceId) {
79
+ auto lock = std::scoped_lock{mutex_};
80
+ surfaces_.erase(surfaceId);
81
+ }
82
+
83
+ std::vector<ShadowNodeFamily::Shared> SynchronousWritesTracker::getFamiliesToRewrite() const {
84
+ auto lock = std::scoped_lock{mutex_};
85
+ std::vector<ShadowNodeFamily::Shared> families;
86
+ for (const auto &[_, surface] : surfaces_) {
87
+ for (const auto &[tag, write] : surface.writes) {
88
+ families.push_back(write.shadowNodeFamily);
89
+ }
90
+ }
91
+ return families;
92
+ }
93
+
94
+ void SynchronousWritesTracker::onRewrite() {
95
+ auto lock = std::scoped_lock{mutex_};
96
+ for (auto &[_, surface] : surfaces_) {
97
+ const auto mountedEpoch = surface.reportedEpoch;
98
+ surface.mountedEpoch = mountedEpoch;
99
+ std::erase_if(surface.writes, [mountedEpoch](const auto &entry) { return entry.second.epoch <= mountedEpoch; });
100
+ }
101
+ }
102
+
103
+ } // namespace reanimated
@@ -0,0 +1,74 @@
1
+ #pragma once
2
+
3
+ #include <reanimated/Fabric/updates/UpdatesRegistry.h>
4
+
5
+ #include <react/renderer/components/root/RootShadowNode.h>
6
+ #include <react/renderer/core/ShadowNodeFamily.h>
7
+
8
+ #include <cstdint>
9
+ #include <deque>
10
+ #include <memory>
11
+ #include <mutex>
12
+ #include <thread>
13
+ #include <unordered_map>
14
+ #include <vector>
15
+
16
+ using namespace facebook::react;
17
+
18
+ namespace reanimated {
19
+
20
+ // A React commit takes its animated values from the registries in the commit hook, but the platform can mount it
21
+ // after newer synchronous writes. This class keeps the views with such writes until every such commit is mounted, so
22
+ // that the platform can write their current values again after a mount.
23
+ class SynchronousWritesTracker {
24
+ public:
25
+ void onWillCommit(const RootShadowNode::Shared &rootShadowNode, bool carriesRegistryValues);
26
+ void onDidCommit(const RootShadowNode::Shared &rootShadowNode);
27
+ void onSynchronousWrite(const UpdatesBatch &synchronousUpdatesBatch);
28
+ void onMountReport(const RootShadowNode::Shared &mountedRootShadowNode);
29
+ void onSurfaceStop(SurfaceId surfaceId);
30
+ std::vector<ShadowNodeFamily::Shared> getFamiliesToRewrite() const;
31
+ void onRewrite();
32
+
33
+ private:
34
+ using Epoch = uint64_t;
35
+
36
+ struct CommittedRoot {
37
+ std::weak_ptr<const RootShadowNode> rootShadowNode;
38
+ Epoch epoch;
39
+ };
40
+
41
+ struct Write {
42
+ ShadowNodeFamily::Shared shadowNodeFamily;
43
+ Epoch epoch;
44
+ };
45
+
46
+ struct PendingCommit {
47
+ SurfaceId surfaceId;
48
+ Epoch epoch;
49
+ };
50
+
51
+ struct SurfaceState {
52
+ // Number of commits that carried registry values. A write with epoch N is newer than the values in commits 1..N.
53
+ Epoch epoch{0};
54
+ // Android reports a mount at the pull, before the mount items run. The next mount callback writes the props
55
+ // again. That callback also runs for a dispatch that has only view commands. If such a dispatch runs before the
56
+ // mount items, the tracker removes the writes too early. The old value then stays on screen until the next
57
+ // synchronous write.
58
+ Epoch reportedEpoch{0};
59
+ Epoch mountedEpoch{0};
60
+ std::deque<CommittedRoot> committedRoots;
61
+ std::unordered_map<Tag, Write> writes;
62
+ };
63
+
64
+ static void rememberRoot(SurfaceState &surface, const RootShadowNode::Shared &rootShadowNode, Epoch epoch);
65
+
66
+ mutable std::mutex mutex_;
67
+ // Carries the epoch from `onWillCommit` (known at the registry read) to `onDidCommit` (final root, after all
68
+ // hooks). Both run on the committing thread, but commits on different threads can overlap on one surface, so
69
+ // the key is the thread. A failed or cancelled commit gets no `onDidCommit`; `onWillCommit` drops its entry.
70
+ std::unordered_map<std::thread::id, PendingCommit> pendingCommits_;
71
+ std::unordered_map<SurfaceId, SurfaceState> surfaces_;
72
+ };
73
+
74
+ } // namespace reanimated
@@ -37,6 +37,21 @@ void UpdatesRegistry::mergeInto(const Tag tag, folly::dynamic &target) const {
37
37
  target.update(it->second.second);
38
38
  }
39
39
 
40
+ #ifdef ANDROID
41
+ void UpdatesRegistry::mergeInto(const Tag tag, folly::dynamic &target, const PropNamePredicate isIncluded) const {
42
+ react_native_assert(UpdatesRegistryManager::isLockedByCurrentThread());
43
+ auto it = updatesRegistry_.find(tag);
44
+ if (it == updatesRegistry_.cend()) {
45
+ return;
46
+ }
47
+ for (const auto &[name, value] : it->second.second.items()) {
48
+ if (isIncluded(name.getString())) {
49
+ target[name] = value;
50
+ }
51
+ }
52
+ }
53
+ #endif // ANDROID
54
+
40
55
  void UpdatesRegistry::remove(const Tag tag) {
41
56
  react_native_assert(UpdatesRegistryManager::isLockedByCurrentThread());
42
57
  removeTag(tag);
@@ -29,6 +29,8 @@ struct AnimatedPropsEntry {
29
29
  };
30
30
  using UpdatesBatchAnimatedProps = std::vector<AnimatedPropsEntry>;
31
31
 
32
+ using PropNamePredicate = bool (*)(const std::string &);
33
+
32
34
  using RegistryMap = std::unordered_map<Tag, std::pair<ShadowNodeFamily::Shared, folly::dynamic>>;
33
35
 
34
36
  #ifdef ANDROID
@@ -48,6 +50,9 @@ class UpdatesRegistry {
48
50
  virtual bool isEmpty() const;
49
51
  folly::dynamic get(Tag tag) const;
50
52
  void mergeInto(Tag tag, folly::dynamic &target) const;
53
+ #ifdef ANDROID
54
+ void mergeInto(Tag tag, folly::dynamic &target, PropNamePredicate isIncluded) const;
55
+ #endif
51
56
  void remove(Tag tag);
52
57
 
53
58
  #ifdef ANDROID
@@ -115,6 +115,16 @@ void UpdatesRegistryManager::mergeRegistryProps(const Tag viewTag, folly::dynami
115
115
 
116
116
  #ifdef ANDROID
117
117
 
118
+ void UpdatesRegistryManager::mergeRegistryProps(
119
+ const Tag viewTag,
120
+ folly::dynamic &target,
121
+ const PropNamePredicate isIncluded) {
122
+ react_native_assert(isLockedByCurrentThread());
123
+ for (const auto &registry : registries_) {
124
+ registry->mergeInto(viewTag, target, isIncluded);
125
+ }
126
+ }
127
+
118
128
  bool UpdatesRegistryManager::hasPropsToRevert() {
119
129
  react_native_assert(isLockedByCurrentThread());
120
130
  for (auto &registry : registries_) {
@@ -49,6 +49,9 @@ class UpdatesRegistryManager {
49
49
  void handleNodeRemovals(const RootShadowNode &rootShadowNode);
50
50
  PropsMap collectProps();
51
51
  void mergeRegistryProps(Tag viewTag, folly::dynamic &target);
52
+ #ifdef ANDROID
53
+ void mergeRegistryProps(Tag viewTag, folly::dynamic &target, PropNamePredicate isIncluded);
54
+ #endif
52
55
 
53
56
  #ifdef ANDROID
54
57
  bool hasPropsToRevert();