Skip to content

Commit

Permalink
Support passing in children directly when cloning nodes (facebook#39817)
Browse files Browse the repository at this point in the history
Summary:
Update the UIManagerBinding interface to support the upcoming API changes in facebook/react#27458

Changelog: [Internal]


Reviewed By: rubennorte, sammy-SC

Differential Revision: D49912532
  • Loading branch information
javache authored and facebook-github-bot committed Oct 6, 2023
1 parent 9252099 commit c13e0c8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -327,25 +327,28 @@ jsi::Value UIManagerBinding::get(
});
}

// Semantic: Clones the node with *same* props and *empty* children.
// Semantic: Clones the node with *same* props and *given* children.
if (methodName == "cloneNodeWithNewChildren") {
auto paramCount = 1;
auto paramCount = 2;
return jsi::Function::createFromHostFunction(
runtime,
name,
paramCount,
[uiManager, methodName, paramCount](
[uiManager, methodName](
jsi::Runtime& runtime,
const jsi::Value& /*thisValue*/,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
validateArgumentCount(runtime, methodName, paramCount, count);
// TODO: re-enable when passChildrenWhenCloningPersistedNodes is
// rolled out
// validateArgumentCount(runtime, methodName, paramCount, count);

return valueFromShadowNode(
runtime,
uiManager->cloneNode(
*shadowNodeFromValue(runtime, arguments[0]),
ShadowNode::emptySharedShadowNodeSharedList()));
count > 1 ? shadowNodeListFromValue(runtime, arguments[1])
: ShadowNode::emptySharedShadowNodeSharedList()));
});
}

Expand All @@ -363,7 +366,7 @@ jsi::Value UIManagerBinding::get(
size_t count) -> jsi::Value {
validateArgumentCount(runtime, methodName, paramCount, count);

const auto& rawProps = RawProps(runtime, arguments[1]);
RawProps rawProps(runtime, arguments[1]);
return valueFromShadowNode(
runtime,
uiManager->cloneNode(
Expand All @@ -373,26 +376,31 @@ jsi::Value UIManagerBinding::get(
});
}

// Semantic: Clones the node with *given* props and *empty* children.
// Semantic: Clones the node with *given* props and *given* children.
if (methodName == "cloneNodeWithNewChildrenAndProps") {
auto paramCount = 2;
auto paramCount = 3;
return jsi::Function::createFromHostFunction(
runtime,
name,
paramCount,
[uiManager, methodName, paramCount](
[uiManager, methodName](
jsi::Runtime& runtime,
const jsi::Value& /*thisValue*/,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
validateArgumentCount(runtime, methodName, paramCount, count);
// TODO: re-enable when passChildrenWhenCloningPersistedNodes is
// rolled out
// validateArgumentCount(runtime, methodName, paramCount, count);

const auto& rawProps = RawProps(runtime, arguments[1]);
bool hasChildrenArg = count == 3;
RawProps rawProps(runtime, arguments[hasChildrenArg ? 2 : 1]);
return valueFromShadowNode(
runtime,
uiManager->cloneNode(
*shadowNodeFromValue(runtime, arguments[0]),
ShadowNode::emptySharedShadowNodeSharedList(),
hasChildrenArg
? shadowNodeListFromValue(runtime, arguments[1])
: ShadowNode::emptySharedShadowNodeSharedList(),
&rawProps));
});
}
Expand All @@ -417,6 +425,7 @@ jsi::Value UIManagerBinding::get(
});
}

// TODO: remove when passChildrenWhenCloningPersistedNodes is rolled out
if (methodName == "createChildSet") {
return jsi::Function::createFromHostFunction(
runtime,
Expand All @@ -432,6 +441,7 @@ jsi::Value UIManagerBinding::get(
});
}

// TODO: remove when passChildrenWhenCloningPersistedNodes is rolled out
if (methodName == "appendChildToSet") {
auto paramCount = 2;
return jsi::Function::createFromHostFunction(
Expand Down Expand Up @@ -475,17 +485,13 @@ jsi::Value UIManagerBinding::get(
if (!uiManager->backgroundExecutor_ ||
(runtimeSchedulerBinding &&
runtimeSchedulerBinding->getIsSynchronous())) {
auto weakShadowNodeList =
weakShadowNodeListFromValue(runtime, arguments[1]);
auto shadowNodeList =
shadowNodeListFromWeakList(weakShadowNodeList);
if (shadowNodeList) {
uiManager->completeSurface(
surfaceId,
shadowNodeList,
{/* .enableStateReconciliation = */ true,
/* .mountSynchronously = */ false});
}
shadowNodeListFromValue(runtime, arguments[1]);
uiManager->completeSurface(
surfaceId,
shadowNodeList,
{/* .enableStateReconciliation = */ true,
/* .mountSynchronously = */ false});
} else {
auto weakShadowNodeList =
weakShadowNodeListFromValue(runtime, arguments[1]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,39 @@ inline static jsi::Value valueFromShadowNode(
}
}

// TODO: once we no longer need to mutate the return value (appendChildToSet)
// make this a SharedListOfShared
inline static ShadowNode::UnsharedListOfShared shadowNodeListFromValue(
jsi::Runtime& runtime,
const jsi::Value& value) {
if (CoreFeatures::useNativeState) {
return value.getObject(runtime)
.getNativeState<ShadowNodeListWrapper>(runtime)
->shadowNodeList;
// TODO: cleanup when passChildrenWhenCloningPersistedNodes is rolled out
jsi::Object object = value.asObject(runtime);
if (object.isArray(runtime)) {
auto jsArray = std::move(object).asArray(runtime);
size_t jsArrayLen = jsArray.length(runtime);
if (jsArrayLen > 0) {
auto shadowNodeArray = std::make_shared<ShadowNode::ListOfShared>();
shadowNodeArray->reserve(jsArrayLen);

for (size_t i = 0; i < jsArrayLen; i++) {
shadowNodeArray->push_back(
shadowNodeFromValue(runtime, jsArray.getValueAtIndex(runtime, i)));
}
return shadowNodeArray;
} else {
// TODO: return ShadowNode::emptySharedShadowNodeSharedList()
return std::make_shared<ShadowNode::ListOfShared>(
ShadowNode::ListOfShared({}));
;
}
} else {
return value.getObject(runtime)
.getHostObject<ShadowNodeListWrapper>(runtime)
->shadowNodeList;
if (CoreFeatures::useNativeState) {
return object.getNativeState<ShadowNodeListWrapper>(runtime)
->shadowNodeList;
} else {
return object.getHostObject<ShadowNodeListWrapper>(runtime)
->shadowNodeList;
}
}
}

Expand Down

0 comments on commit c13e0c8

Please sign in to comment.