mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Use ShadowNodeFamily in state updates
Summary: Changelog: [internal] `ShadowNodeFamily` can be used as target in state updates instead of `ShadowNode`. Reviewed By: shergin Differential Revision: D19517428 fbshipit-source-id: 6831357e749239d5afec1dfd2d44a26ca6553e51
This commit is contained in:
committed by
Facebook Github Bot
parent
1041ad5651
commit
595e954b13
@@ -116,7 +116,7 @@ class ComponentDescriptor {
|
||||
* State's data.
|
||||
*/
|
||||
virtual State::Shared createState(
|
||||
const State::Shared &previousState,
|
||||
ShadowNodeFamily::Shared const &family,
|
||||
const StateData::Shared &data) const = 0;
|
||||
|
||||
/*
|
||||
|
||||
@@ -132,22 +132,17 @@ class ConcreteComponentDescriptor : public ComponentDescriptor {
|
||||
}
|
||||
|
||||
virtual State::Shared createState(
|
||||
const State::Shared &previousState,
|
||||
ShadowNodeFamily::Shared const &family,
|
||||
const StateData::Shared &data) const override {
|
||||
if (std::is_same<ConcreteStateData, StateData>::value) {
|
||||
// Default case: Returning `null` for nodes that don't use `State`.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
assert(previousState && "Provided `previousState` is nullptr.");
|
||||
assert(data && "Provided `data` is nullptr.");
|
||||
assert(
|
||||
dynamic_cast<ConcreteState const *>(previousState.get()) &&
|
||||
"Provided `previousState` has an incompatible type.");
|
||||
|
||||
return std::make_shared<const ConcreteState>(
|
||||
std::move(*std::static_pointer_cast<ConcreteStateData>(data)),
|
||||
*std::static_pointer_cast<const ConcreteState>(previousState));
|
||||
std::move(*std::static_pointer_cast<ConcreteStateData>(data)), family);
|
||||
}
|
||||
|
||||
virtual ShadowNodeFamily::Shared createFamily(
|
||||
|
||||
@@ -49,6 +49,10 @@ ComponentName ShadowNodeFamily::getComponentName() const {
|
||||
return componentName_;
|
||||
}
|
||||
|
||||
const ComponentDescriptor &ShadowNodeFamily::getComponentDescriptor() const {
|
||||
return componentDescriptor_;
|
||||
}
|
||||
|
||||
AncestorList ShadowNodeFamily::getAncestors(
|
||||
ShadowNode const &ancestorShadowNode) const {
|
||||
auto families = better::small_vector<ShadowNodeFamily const *, 64>{};
|
||||
@@ -120,19 +124,14 @@ void ShadowNodeFamily::setTarget(StateTarget &&target) const {
|
||||
}
|
||||
|
||||
void ShadowNodeFamily::dispatchRawState(
|
||||
std::function<StateData::Shared()> &&stateData,
|
||||
StateUpdate &&stateUpdate,
|
||||
EventPriority priority) const {
|
||||
auto eventDispatcher = eventDispatcher_.lock();
|
||||
if (!eventDispatcher || !target_) { // why do we check !target_ here?
|
||||
if (!eventDispatcher) {
|
||||
return;
|
||||
}
|
||||
|
||||
eventDispatcher->dispatchStateUpdate(
|
||||
{[=]() -> std::pair<StateTarget, StateData::Shared> {
|
||||
auto target = getTarget();
|
||||
return {std::move(target), stateData()};
|
||||
}},
|
||||
priority);
|
||||
eventDispatcher->dispatchStateUpdate(std::move(stateUpdate), priority);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -54,6 +54,11 @@ class ShadowNodeFamily {
|
||||
ComponentHandle getComponentHandle() const;
|
||||
ComponentName getComponentName() const;
|
||||
|
||||
/*
|
||||
* Returns a concrete `ComponentDescriptor` that manages nodes of this type.
|
||||
*/
|
||||
const ComponentDescriptor &getComponentDescriptor() const;
|
||||
|
||||
/*
|
||||
* Returns a list of all ancestors of the node relative to the given ancestor.
|
||||
* The list starts from the given ancestor node and ends with the parent node
|
||||
@@ -76,9 +81,8 @@ class ShadowNodeFamily {
|
||||
/*
|
||||
* Dispatches a state update with given priority.
|
||||
*/
|
||||
void dispatchRawState(
|
||||
std::function<StateData::Shared()> &&stateData,
|
||||
EventPriority priority) const;
|
||||
void dispatchRawState(StateUpdate &&stateUpdate, EventPriority priority)
|
||||
const;
|
||||
|
||||
private:
|
||||
friend ShadowNode;
|
||||
|
||||
@@ -70,14 +70,14 @@ class ConcreteState : public State {
|
||||
std::function<Data(const Data &oldData)> callback,
|
||||
EventPriority priority = EventPriority::AsynchronousBatched) const {
|
||||
family_->dispatchRawState(
|
||||
{[family = family_,
|
||||
callback = std::move(callback)]() -> StateData::Shared {
|
||||
{[family = family_, callback = std::move(callback)]()
|
||||
-> std::pair<SharedShadowNodeFamily const &, StateData::Shared> {
|
||||
auto target = family->getTarget();
|
||||
auto oldState = target.getShadowNode().getState();
|
||||
auto oldData = std::static_pointer_cast<const ConcreteState>(oldState)
|
||||
->getData();
|
||||
auto newData = std::make_shared<Data>(callback(oldData));
|
||||
return newData;
|
||||
return {family, newData};
|
||||
}},
|
||||
priority);
|
||||
}
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class ShadowNodeFamily;
|
||||
using SharedShadowNodeFamily = std::shared_ptr<ShadowNodeFamily const>;
|
||||
|
||||
using StatePipe = std::function<
|
||||
void(const StateData::Shared &data, const StateTarget &target)>;
|
||||
void(const StateData::Shared &data, SharedShadowNodeFamily const &family)>;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::pair<StateTarget, StateData::Shared> StateUpdate::operator()() const {
|
||||
std::pair<SharedShadowNodeFamily const &, StateData::Shared> StateUpdate::
|
||||
operator()() const {
|
||||
return callback_();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <functional>
|
||||
|
||||
#include <react/core/StateData.h>
|
||||
#include <react/core/StateTarget.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
@@ -18,16 +17,20 @@ namespace react {
|
||||
/*
|
||||
* Carries some logic and additional information about state update transaction.
|
||||
*/
|
||||
class ShadowNodeFamily;
|
||||
using SharedShadowNodeFamily = std::shared_ptr<ShadowNodeFamily const>;
|
||||
class StateUpdate {
|
||||
public:
|
||||
std::pair<StateTarget, StateData::Shared> operator()() const;
|
||||
std::pair<SharedShadowNodeFamily const &, StateData::Shared> operator()()
|
||||
const;
|
||||
|
||||
/*
|
||||
* The current implementation simply uses `std::function` inside that captures
|
||||
* everything which is needed to perform state update. That will be probably
|
||||
* changed in the future.
|
||||
*/
|
||||
std::function<std::pair<StateTarget, StateData::Shared>()> callback_;
|
||||
std::function<std::pair<SharedShadowNodeFamily const &, StateData::Shared>()>
|
||||
callback_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -45,8 +45,8 @@ Scheduler::Scheduler(
|
||||
|
||||
auto statePipe = [uiManager](
|
||||
const StateData::Shared &data,
|
||||
const StateTarget &stateTarget) {
|
||||
uiManager->updateState(stateTarget.getShadowNode(), data);
|
||||
SharedShadowNodeFamily const &family) {
|
||||
uiManager->updateState(family, data);
|
||||
};
|
||||
|
||||
eventDispatcher_ = std::make_shared<EventDispatcher>(
|
||||
|
||||
@@ -194,18 +194,17 @@ LayoutMetrics UIManager::getRelativeLayoutMetrics(
|
||||
}
|
||||
|
||||
void UIManager::updateState(
|
||||
ShadowNode const &shadowNode,
|
||||
ShadowNodeFamily::Shared const &family,
|
||||
StateData::Shared const &rawStateData) const {
|
||||
auto &componentDescriptor = family->getComponentDescriptor();
|
||||
auto state = componentDescriptor.createState(family, rawStateData);
|
||||
|
||||
shadowTreeRegistry_.visit(
|
||||
shadowNode.getSurfaceId(), [&](ShadowTree const &shadowTree) {
|
||||
family->getSurfaceId(), [&](ShadowTree const &shadowTree) {
|
||||
shadowTree.tryCommit([&](RootShadowNode::Shared const
|
||||
&oldRootShadowNode) {
|
||||
return oldRootShadowNode->clone(
|
||||
shadowNode.getFamily(), [&](ShadowNode const &oldShadowNode) {
|
||||
auto &componentDescriptor =
|
||||
oldShadowNode.getComponentDescriptor();
|
||||
auto state = componentDescriptor.createState(
|
||||
oldShadowNode.getState(), rawStateData);
|
||||
*family, [&](ShadowNode const &oldShadowNode) {
|
||||
return oldShadowNode.clone({
|
||||
/* .props = */ ShadowNodeFragment::propsPlaceholder(),
|
||||
/* .children = */ ShadowNodeFragment::childrenPlaceholder(),
|
||||
|
||||
@@ -107,7 +107,7 @@ class UIManager final : public ShadowTreeDelegate {
|
||||
* and performs a commit.
|
||||
*/
|
||||
void updateState(
|
||||
ShadowNode const &shadowNode,
|
||||
ShadowNodeFamily::Shared const &family,
|
||||
StateData::Shared const &rawStateData) const;
|
||||
|
||||
void dispatchCommand(
|
||||
|
||||
Reference in New Issue
Block a user