Skip to content

Commit

Permalink
feat: Support for multiple surfaces on Fabric (#6647)
Browse files Browse the repository at this point in the history
## Summary

This PR introduces handling multiple surfaces on Fabric.

## Test plan

🚀
  • Loading branch information
patrycjakalinska authored Nov 18, 2024
1 parent 61e984e commit b2b58a6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <reanimated/RuntimeDecorators/UIRuntimeDecorator.h>
#include <reanimated/Tools/CollectionUtils.h>
#include <reanimated/Tools/FeaturesConfig.h>
#include <unordered_map>

#ifdef RCT_NEW_ARCH_ENABLED
#include <reanimated/Fabric/ReanimatedCommitShadowNode.h>
Expand Down Expand Up @@ -636,9 +637,6 @@ void NativeReanimatedModule::updateProps(
const jsi::Value &updates = item.getProperty(rt, "updates");
operationsInBatch_.emplace_back(
shadowNode, std::make_unique<jsi::Value>(rt, updates));

// TODO: support multiple surfaces
surfaceId_ = shadowNode->getSurfaceId();
}
}

Expand Down Expand Up @@ -696,6 +694,7 @@ void NativeReanimatedModule::performOperations() {
}

bool hasLayoutUpdates = false;

for (const auto &[shadowNode, props] : copiedOperationsQueue) {
if (isThereAnyLayoutProp(rt, props->asObject(rt))) {
hasLayoutUpdates = true;
Expand Down Expand Up @@ -725,41 +724,45 @@ void NativeReanimatedModule::performOperations() {
react_native_assert(uiManager_ != nullptr);
const auto &shadowTreeRegistry = uiManager_->getShadowTreeRegistry();

shadowTreeRegistry.visit(surfaceId_, [&](ShadowTree const &shadowTree) {
shadowTree.commit(
[&](RootShadowNode const &oldRootShadowNode)
-> RootShadowNode::Unshared {
PropsMap propsMap;
for (auto &[shadowNode, props] : copiedOperationsQueue) {
auto family = &shadowNode->getFamily();
react_native_assert(family->getSurfaceId() == surfaceId_);
propsMap[family].emplace_back(rt, std::move(*props));
std::unordered_map<SurfaceId, PropsMap> propsMapBySurface;

for (auto const &[shadowNode, props] : copiedOperationsQueue) {
SurfaceId surfaceId = shadowNode->getSurfaceId();
auto family = &shadowNode->getFamily();
react_native_assert(family->getSurfaceId() == surfaceId);
propsMapBySurface[surfaceId][family].emplace_back(rt, std::move(*props));
}

for (auto const &[surfaceId, propsMap] : propsMapBySurface) {
shadowTreeRegistry.visit(surfaceId, [&](ShadowTree const &shadowTree) {
shadowTree.commit(
[&](RootShadowNode const &oldRootShadowNode)
-> RootShadowNode::Unshared {
if (propsRegistry_->shouldReanimatedSkipCommit()) {
return nullptr;
}
}

auto rootNode =
cloneShadowTreeWithNewProps(oldRootShadowNode, propsMap);

// Mark the commit as Reanimated commit so that we can distinguish it
// in ReanimatedCommitHook.

auto reaShadowNode =
std::reinterpret_pointer_cast<ReanimatedCommitShadowNode>(
rootNode);
reaShadowNode->setReanimatedCommitTrait();

return rootNode;
},
{/* .enableStateReconciliation = */
false,
/* .mountSynchronously = */ true,
/* .shouldYield = */ [this]() {
return propsRegistry_->shouldReanimatedSkipCommit();
}});
});

auto rootNode =
cloneShadowTreeWithNewProps(oldRootShadowNode, propsMap);

// Mark the commit as Reanimated commit so that we can distinguish
// it in ReanimatedCommitHook.

auto reaShadowNode =
std::reinterpret_pointer_cast<ReanimatedCommitShadowNode>(
rootNode);
reaShadowNode->setReanimatedCommitTrait();

return rootNode;
},
{/* .enableStateReconciliation = */
false,
/* .mountSynchronously = */ true,
/* .shouldYield = */ [this]() {
return propsRegistry_->shouldReanimatedSkipCommit();
}});
});
}
}

void NativeReanimatedModule::removeFromPropsRegistry(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,6 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec {
std::shared_ptr<UIManager> uiManager_;
std::shared_ptr<LayoutAnimationsProxy> layoutAnimationsProxy_;

// After app reload, surfaceId on iOS is still 1 but on Android it's 11.
// We can store surfaceId of the most recent ShadowNode as a workaround.
SurfaceId surfaceId_ = -1;

std::vector<std::pair<ShadowNode::Shared, std::unique_ptr<jsi::Value>>>
operationsInBatch_; // TODO: refactor std::pair to custom struct

Expand Down

0 comments on commit b2b58a6

Please sign in to comment.