Files
react-native/ReactCommon/react/renderer/core/ShadowNodeFamily.cpp
T
Kevin Gozali fb39d45ed5 C++ - better => butter
Summary:
Renaming the `better` utilities to `butter`:
- to prevent claims that this library is superior to others - it really depends on use cases
- to indicate ease of use throughout the codebase, easily spread like butter

Changelog: [C++][Changed] Renaming C++ better util to butter, used by Fabric internals

Reviewed By: JoshuaGross

Differential Revision: D33242764

fbshipit-source-id: 26dc95d9597c61ce8e66708e44ed545e0fc5cff5
2021-12-20 22:25:14 -08:00

145 lines
3.8 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "ShadowNodeFamily.h"
#include "ShadowNode.h"
#include <react/debug/react_native_assert.h>
#include <react/renderer/core/ComponentDescriptor.h>
#include <react/renderer/core/State.h>
namespace facebook {
namespace react {
using AncestorList = ShadowNode::AncestorList;
ShadowNodeFamily::ShadowNodeFamily(
ShadowNodeFamilyFragment const &fragment,
EventDispatcher::Weak eventDispatcher,
ComponentDescriptor const &componentDescriptor)
: eventDispatcher_(eventDispatcher),
tag_(fragment.tag),
surfaceId_(fragment.surfaceId),
eventEmitter_(fragment.eventEmitter),
componentDescriptor_(componentDescriptor),
componentHandle_(componentDescriptor.getComponentHandle()),
componentName_(componentDescriptor.getComponentName()) {}
void ShadowNodeFamily::setParent(ShadowNodeFamily::Shared const &parent) const {
react_native_assert(parent_.lock() == nullptr || parent_.lock() == parent);
if (hasParent_) {
return;
}
parent_ = parent;
hasParent_ = true;
}
ComponentHandle ShadowNodeFamily::getComponentHandle() const {
return componentHandle_;
}
SurfaceId ShadowNodeFamily::getSurfaceId() const {
return surfaceId_;
}
ComponentName ShadowNodeFamily::getComponentName() const {
return componentName_;
}
const ComponentDescriptor &ShadowNodeFamily::getComponentDescriptor() const {
return componentDescriptor_;
}
AncestorList ShadowNodeFamily::getAncestors(
ShadowNode const &ancestorShadowNode) const {
auto families = butter::small_vector<ShadowNodeFamily const *, 64>{};
auto ancestorFamily = ancestorShadowNode.family_.get();
auto family = this;
while (family && family != ancestorFamily) {
families.push_back(family);
family = family->parent_.lock().get();
}
if (family != ancestorFamily) {
return {};
}
auto ancestors = AncestorList{};
auto parentNode = &ancestorShadowNode;
for (auto it = families.rbegin(); it != families.rend(); it++) {
auto childFamily = *it;
auto found = false;
auto childIndex = 0;
for (const auto &childNode : *parentNode->children_) {
if (childNode->family_.get() == childFamily) {
ancestors.push_back({*parentNode, childIndex});
parentNode = childNode.get();
found = true;
break;
}
childIndex++;
}
if (!found) {
ancestors.clear();
return ancestors;
}
}
return ancestors;
}
State::Shared ShadowNodeFamily::getMostRecentState() const {
std::unique_lock<butter::shared_mutex> lock(mutex_);
return mostRecentState_;
}
void ShadowNodeFamily::setMostRecentState(State::Shared const &state) const {
std::unique_lock<butter::shared_mutex> lock(mutex_);
/*
* Checking and setting `isObsolete_` prevents old states to be recommitted
* on top of fresher states. It's okay to commit a tree with "older" Shadow
* Nodes (the evolution of nodes is not linear), however, we never back out
* states (they progress linearly).
*/
if (state && state->isObsolete_) {
return;
}
if (mostRecentState_) {
mostRecentState_->isObsolete_ = true;
}
mostRecentState_ = state;
}
std::shared_ptr<State const> ShadowNodeFamily::getMostRecentStateIfObsolete(
State const &state) const {
std::unique_lock<butter::shared_mutex> lock(mutex_);
if (!state.isObsolete_) {
return {};
}
return mostRecentState_;
}
void ShadowNodeFamily::dispatchRawState(
StateUpdate &&stateUpdate,
EventPriority priority) const {
auto eventDispatcher = eventDispatcher_.lock();
if (!eventDispatcher) {
return;
}
eventDispatcher->dispatchStateUpdate(std::move(stateUpdate), priority);
}
} // namespace react
} // namespace facebook