Skip to content

Fabric: Export shadow node family to javascript #51146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
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
466 changes: 233 additions & 233 deletions packages/react-native/Libraries/Core/setUpReactDevTools.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import defineLazyObjectProperty from '../Utilities/defineLazyObjectProperty';

export type NodeSet = Array<Node>;
export type NodeProps = {...};
export opaque type ShadowNodeFamilyReference = mixed;
export interface Spec {
+createNode: (
reactTag: number,
Expand All @@ -40,6 +41,7 @@ export interface Spec {
+cloneNodeWithNewProps: (node: Node, newProps: NodeProps) => Node;
+cloneNodeWithNewChildrenAndProps: (node: Node, newProps: NodeProps) => Node;
+createChildSet: (rootTag: RootTag) => NodeSet;
+createShadowNodeFamilyReference: (node: Node) => ShadowNodeFamilyReference;
+appendChild: (parentNode: Node, child: Node) => Node;
+appendChildToSet: (childSet: NodeSet, child: Node) => void;
+completeRoot: (rootTag: RootTag, childSet: NodeSet) => void;
Expand Down Expand Up @@ -111,6 +113,7 @@ const CACHED_PROPERTIES = [
'cloneNodeWithNewProps',
'cloneNodeWithNewChildrenAndProps',
'createChildSet',
'createShadowNodeFamilyReference',
'appendChild',
'appendChildToSet',
'completeRoot',
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/React/Base/RCTBundleURLProvider.mm
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ - (void)updateValue:(id)object forKey:(NSString *)key

- (BOOL)enableDev
{
return [[NSUserDefaults standardUserDefaults] boolForKey:kRCTEnableDevKey];
return NO;
}

- (BOOL)enableMinification
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
Expand Down Expand Up @@ -128,6 +129,26 @@ void TurboModuleBinding::install(
return;
}

defineReadOnlyGlobal(
runtime,
"RN$clearLongLivedObjectCollection",
jsi::Function::createFromHostFunction(
runtime,
jsi::PropNameID::forAscii(
runtime, "RN$clearLongLivedObjectCollection"),
0,
[longLivedObjectCollection](
jsi::Runtime& rt,
const jsi::Value& /*thisVal*/,
const jsi::Value* /*args*/,
size_t /*count*/) {
LongLivedObjectCollection::get(rt).clear();
if (longLivedObjectCollection) {
longLivedObjectCollection->clear();
}
return jsi::Value::undefined();
}));

defineReadOnlyGlobal(runtime, "RN$UnifiedNativeModuleProxy", true);
defineReadOnlyGlobal(
runtime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void NativeIntersectionObserver::observe(

intersectionObserverManager_.observe(
intersectionObserverId,
shadowNode,
shadowNode->getFamilyShared(),
thresholds,
rootThresholds,
uiManager);
Expand All @@ -48,7 +48,8 @@ void NativeIntersectionObserver::unobserve(
IntersectionObserverObserverId intersectionObserverId,
jsi::Object targetShadowNode) {
auto shadowNode = shadowNodeFromValue(runtime, std::move(targetShadowNode));
intersectionObserverManager_.unobserve(intersectionObserverId, *shadowNode);
intersectionObserverManager_.unobserve(
intersectionObserverId, shadowNode->getFamilyShared());
}

void NativeIntersectionObserver::connect(
Expand Down Expand Up @@ -101,7 +102,7 @@ NativeIntersectionObserver::convertToNativeModuleEntry(

NativeIntersectionObserverEntry nativeModuleEntry = {
entry.intersectionObserverId,
(*entry.shadowNode).getInstanceHandle(runtime),
(*entry.shadowNodeFamily).getInstanceHandle(runtime),
targetRect,
rootRect,
intersectionRect,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,7 @@ const SharedEventEmitter& ShadowNode::getEventEmitter() const {
}

jsi::Value ShadowNode::getInstanceHandle(jsi::Runtime& runtime) const {
auto instanceHandle = family_->instanceHandle_;
if (instanceHandle == nullptr) {
return jsi::Value::null();
}

return instanceHandle->getInstanceHandle(runtime);
return family_->getInstanceHandle(runtime);
}

Tag ShadowNode::getTag() const {
Expand Down Expand Up @@ -341,6 +336,10 @@ const ShadowNodeFamily& ShadowNode::getFamily() const {
return *family_;
}

ShadowNodeFamily::Shared ShadowNode::getFamilyShared() const {
return family_;
}

ShadowNode::Unshared ShadowNode::cloneTree(
const ShadowNodeFamily& shadowNodeFamily,
const std::function<ShadowNode::Unshared(const ShadowNode& oldShadowNode)>&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ class ShadowNode : public Sealable,

const ShadowNodeFamily& getFamily() const;

ShadowNodeFamily::Shared getFamilyShared() const;

#pragma mark - Mutating Methods

virtual void appendChild(const Shared& child);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ Tag ShadowNodeFamily::getTag() const {
return tag_;
}

jsi::Value ShadowNodeFamily::getInstanceHandle(jsi::Runtime& runtime) const {
if (instanceHandle_ == nullptr) {
return jsi::Value::null();
}

return instanceHandle_->getInstanceHandle(runtime);
}

InstanceHandle::Shared ShadowNodeFamily::getInstanceHandle() const {
return instanceHandle_;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct ShadowNodeFamilyFragment {
* Represents all things that shadow nodes from the same family have in common.
* To be used inside `ShadowNode` class *only*.
*/
class ShadowNodeFamily final {
class ShadowNodeFamily final : public jsi::NativeState {
public:
using Shared = std::shared_ptr<const ShadowNodeFamily>;
using Weak = std::weak_ptr<const ShadowNodeFamily>;
Expand Down Expand Up @@ -122,6 +122,7 @@ class ShadowNodeFamily final {
*/
Tag getTag() const;

jsi::Value getInstanceHandle(jsi::Runtime& runtime) const;
InstanceHandle::Shared getInstanceHandle() const;
void setInstanceHandle(InstanceHandle::Shared& instanceHandle) const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ namespace facebook::react {

IntersectionObserver::IntersectionObserver(
IntersectionObserverObserverId intersectionObserverId,
ShadowNode::Shared targetShadowNode,
ShadowNodeFamily::Shared targetShadowNodeFamily,
std::vector<Float> thresholds,
std::optional<std::vector<Float>> rootThresholds)
: intersectionObserverId_(intersectionObserverId),
targetShadowNode_(std::move(targetShadowNode)),
targetShadowNodeFamily_(std::move(targetShadowNodeFamily)),
thresholds_(std::move(thresholds)),
rootThresholds_(std::move(rootThresholds)) {}

Expand Down Expand Up @@ -112,8 +112,7 @@ IntersectionObserver::updateIntersectionObservation(
layoutableRootShadowNode != nullptr &&
"RootShadowNode instances must always inherit from LayoutableShadowNode.");

auto targetAncestors =
targetShadowNode_->getFamily().getAncestors(rootShadowNode);
auto targetAncestors = targetShadowNodeFamily_->getAncestors(rootShadowNode);

// Absolute coordinates of the root
auto rootBoundingRect = getRootBoundingRect(*layoutableRootShadowNode);
Expand Down Expand Up @@ -189,7 +188,7 @@ IntersectionObserver::setIntersectingState(
state_ = newState;
IntersectionObserverEntry entry{
intersectionObserverId_,
targetShadowNode_,
targetShadowNodeFamily_,
targetBoundingRect,
rootBoundingRect,
intersectionRect,
Expand All @@ -212,7 +211,7 @@ IntersectionObserver::setNotIntersectingState(
state_ = IntersectionObserverState::NotIntersecting();
IntersectionObserverEntry entry{
intersectionObserverId_,
targetShadowNode_,
targetShadowNodeFamily_,
targetBoundingRect,
rootBoundingRect,
intersectionRect,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#pragma once

#include <react/renderer/components/root/RootShadowNode.h>
#include <react/renderer/core/ShadowNode.h>
#include <react/renderer/core/ShadowNodeFamily.h>
#include <react/renderer/graphics/Float.h>
#include <react/renderer/graphics/Rect.h>
#include <memory>
Expand All @@ -20,21 +20,27 @@ using IntersectionObserverObserverId = int32_t;

struct IntersectionObserverEntry {
IntersectionObserverObserverId intersectionObserverId;
ShadowNode::Shared shadowNode;
ShadowNodeFamily::Shared shadowNodeFamily;
Rect targetRect;
Rect rootRect;
Rect intersectionRect;
bool isIntersectingAboveThresholds;
// TODO(T156529385) Define `DOMHighResTimeStamp` as an alias for `double` and
// use it here.
double time;

bool sameShadowNodeFamily(
const ShadowNodeFamily& otherShadowNodeFamily) const {
return std::addressof(*shadowNodeFamily) ==
std::addressof(otherShadowNodeFamily);
}
};

class IntersectionObserver {
public:
IntersectionObserver(
IntersectionObserverObserverId intersectionObserverId,
ShadowNode::Shared targetShadowNode,
ShadowNodeFamily::Shared targetShadowNodeFamily,
std::vector<Float> thresholds,
std::optional<std::vector<Float>> rootThresholds = std::nullopt);

Expand All @@ -51,8 +57,10 @@ class IntersectionObserver {
return intersectionObserverId_;
}

const ShadowNode& getTargetShadowNode() const {
return *targetShadowNode_;
bool isTargetShadowNodeFamily(
const ShadowNodeFamily& shadowNodeFamily) const {
return std::addressof(*targetShadowNodeFamily_) ==
std::addressof(shadowNodeFamily);
}

std::vector<Float> getThresholds() const {
Expand All @@ -75,7 +83,7 @@ class IntersectionObserver {
double time);

IntersectionObserverObserverId intersectionObserverId_;
ShadowNode::Shared targetShadowNode_;
ShadowNodeFamily::Shared targetShadowNodeFamily_;
std::vector<Float> thresholds_;
std::optional<std::vector<Float>> rootThresholds_;
mutable IntersectionObserverState state_ =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ IntersectionObserverManager::IntersectionObserverManager() = default;

void IntersectionObserverManager::observe(
IntersectionObserverObserverId intersectionObserverId,
const ShadowNode::Shared& shadowNode,
const ShadowNodeFamily::Shared& shadowNodeFamily,
std::vector<Float> thresholds,
std::optional<std::vector<Float>> rootThresholds,
const UIManager& uiManager) {
TraceSection s("IntersectionObserverManager::observe");

auto surfaceId = shadowNode->getSurfaceId();
auto surfaceId = shadowNodeFamily->getSurfaceId();

// The actual observer lives in the array, so we need to create it there and
// then get a reference. Otherwise we only update its state in a copy.
Expand All @@ -36,7 +36,7 @@ void IntersectionObserverManager::observe(
auto& observers = observersBySurfaceId_[surfaceId];
observers.emplace_back(IntersectionObserver{
intersectionObserverId,
shadowNode,
shadowNodeFamily,
std::move(thresholds),
std::move(rootThresholds)});
observer = &observers.back();
Expand Down Expand Up @@ -77,13 +77,13 @@ void IntersectionObserverManager::observe(

void IntersectionObserverManager::unobserve(
IntersectionObserverObserverId intersectionObserverId,
const ShadowNode& shadowNode) {
const ShadowNodeFamily::Shared& shadowNodeFamily) {
TraceSection s("IntersectionObserverManager::unobserve");

{
std::unique_lock lock(observersMutex_);

auto surfaceId = shadowNode.getSurfaceId();
auto surfaceId = shadowNodeFamily->getSurfaceId();

auto observersIt = observersBySurfaceId_.find(surfaceId);
if (observersIt == observersBySurfaceId_.end()) {
Expand All @@ -96,11 +96,10 @@ void IntersectionObserverManager::unobserve(
std::remove_if(
observers.begin(),
observers.end(),
[intersectionObserverId, &shadowNode](const auto& observer) {
[intersectionObserverId, &shadowNodeFamily](const auto& observer) {
return observer.getIntersectionObserverId() ==
intersectionObserverId &&
ShadowNode::sameFamily(
observer.getTargetShadowNode(), shadowNode);
observer.isTargetShadowNodeFamily(*shadowNodeFamily);
}),
observers.end());

Expand All @@ -116,9 +115,9 @@ void IntersectionObserverManager::unobserve(
std::remove_if(
pendingEntries_.begin(),
pendingEntries_.end(),
[intersectionObserverId, &shadowNode](const auto& entry) {
[intersectionObserverId, &shadowNodeFamily](const auto& entry) {
return entry.intersectionObserverId == intersectionObserverId &&
ShadowNode::sameFamily(*entry.shadowNode, shadowNode);
entry.sameShadowNodeFamily(*shadowNodeFamily);
}),
pendingEntries_.end());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ class IntersectionObserverManager final : public UIManagerMountHook {

void observe(
IntersectionObserverObserverId intersectionObserverId,
const ShadowNode::Shared& shadowNode,
const ShadowNodeFamily::Shared& shadowNode,
std::vector<Float> thresholds,
std::optional<std::vector<Float>> rootThresholds,
const UIManager& uiManager);

void unobserve(
IntersectionObserverObserverId intersectionObserverId,
const ShadowNode& shadowNode);
const ShadowNodeFamily::Shared& shadowNode);

void connect(
UIManager& uiManager,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,24 @@ jsi::Value UIManagerBinding::get(
});
}

if (methodName == "createShadowNodeFamilyReference") {
auto paramCount = 1;
return jsi::Function::createFromHostFunction(
runtime,
name,
paramCount,
[methodName, paramCount](
jsi::Runtime& runtime,
const jsi::Value& /*thisValue*/,
const jsi::Value* arguments,
size_t count) {
validateArgumentCount(runtime, methodName, paramCount, count);

auto node = shadowNodeFromValue(runtime, arguments[0]);
return valueFromShadowNodeFamily(runtime, node->getFamilyShared());
});
}

if (methodName == "setIsJSResponder") {
auto paramCount = 3;
return jsi::Function::createFromHostFunction(
Expand Down
Loading
Loading