Fabric: ShadowNodeFamily, maintaining a pointer to a parent family
Summary: One of the core feature of ShadowNodeFamily is having a pointer to a parent family. This diff implements it. I don't think there is a hard retain cycle there, but for more lean memory usage we use weak_ptr here. Reviewed By: JoshuaGross Differential Revision: D14416948 fbshipit-source-id: 05fd2c4833146f007228363b1d958776b4a2a9cf
This commit is contained in:
Родитель
28e89e5081
Коммит
978e59aa92
|
@ -46,6 +46,10 @@ ShadowNode::ShadowNode(
|
|||
revision_(1) {
|
||||
assert(props_);
|
||||
assert(children_);
|
||||
|
||||
for (const auto &child : *children_) {
|
||||
child->family_->setParent(family_);
|
||||
}
|
||||
}
|
||||
|
||||
ShadowNode::ShadowNode(
|
||||
|
@ -71,6 +75,12 @@ ShadowNode::ShadowNode(
|
|||
|
||||
assert(props_);
|
||||
assert(children_);
|
||||
|
||||
if (fragment.children) {
|
||||
for (const auto &child : *children_) {
|
||||
child->family_->setParent(family_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UnsharedShadowNode ShadowNode::clone(const ShadowNodeFragment &fragment) const {
|
||||
|
@ -139,6 +149,8 @@ void ShadowNode::appendChild(const SharedShadowNode &child) {
|
|||
auto nonConstChildren =
|
||||
std::const_pointer_cast<SharedShadowNodeList>(children_);
|
||||
nonConstChildren->push_back(child);
|
||||
|
||||
child->family_->setParent(family_);
|
||||
}
|
||||
|
||||
void ShadowNode::replaceChild(
|
||||
|
@ -161,6 +173,8 @@ void ShadowNode::replaceChild(
|
|||
|
||||
std::replace(
|
||||
nonConstChildren->begin(), nonConstChildren->end(), oldChild, newChild);
|
||||
|
||||
newChild->family_->setParent(family_);
|
||||
}
|
||||
|
||||
void ShadowNode::setLocalData(const SharedLocalData &localData) {
|
||||
|
|
|
@ -20,5 +20,15 @@ ShadowNodeFamily::ShadowNodeFamily(
|
|||
eventEmitter_(eventEmitter),
|
||||
componentDescriptor_(componentDescriptor) {}
|
||||
|
||||
void ShadowNodeFamily::setParent(ShadowNodeFamily::Shared const &parent) const {
|
||||
assert(parent_.lock() == nullptr || parent_.lock() == parent);
|
||||
if (hasParent_) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent_ = parent;
|
||||
hasParent_ = true;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
|
|
@ -32,6 +32,13 @@ class ShadowNodeFamily {
|
|||
SharedEventEmitter const &eventEmitter,
|
||||
ComponentDescriptor const &componentDescriptor);
|
||||
|
||||
/*
|
||||
* Sets the parent.
|
||||
* This is not techically thread-safe, but practically it mutates the object
|
||||
* only once (and the model enforces that this first call is not concurent).
|
||||
*/
|
||||
void setParent(ShadowNodeFamily::Shared const &parent) const;
|
||||
|
||||
private:
|
||||
friend ShadowNode;
|
||||
|
||||
|
@ -55,6 +62,17 @@ class ShadowNodeFamily {
|
|||
* type.
|
||||
*/
|
||||
ComponentDescriptor const &componentDescriptor_;
|
||||
|
||||
/*
|
||||
* Points to a family of all parent nodes of all nodes of the family.
|
||||
*/
|
||||
mutable ShadowNodeFamily::Weak parent_{};
|
||||
|
||||
/*
|
||||
* Represents a case where `parent_` is `nullptr`.
|
||||
* For optimization purposes only.
|
||||
*/
|
||||
mutable bool hasParent_{false};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
Загрузка…
Ссылка в новой задаче