diff --git a/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h b/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h index e8b0700e5e0..6dcd04bfa32 100644 --- a/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h +++ b/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h @@ -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; /* diff --git a/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h b/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h index 6d3e392dd8f..7f7b82d9adb 100644 --- a/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h +++ b/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h @@ -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::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(previousState.get()) && - "Provided `previousState` has an incompatible type."); return std::make_shared( - std::move(*std::static_pointer_cast(data)), - *std::static_pointer_cast(previousState)); + std::move(*std::static_pointer_cast(data)), family); } virtual ShadowNodeFamily::Shared createFamily( diff --git a/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.cpp b/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.cpp index 485ebd4a4b1..2c1f37c3837 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.cpp +++ b/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.cpp @@ -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{}; @@ -120,19 +124,14 @@ void ShadowNodeFamily::setTarget(StateTarget &&target) const { } void ShadowNodeFamily::dispatchRawState( - std::function &&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 { - auto target = getTarget(); - return {std::move(target), stateData()}; - }}, - priority); + eventDispatcher->dispatchStateUpdate(std::move(stateUpdate), priority); } } // namespace react diff --git a/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.h b/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.h index c18c2f4b1f9..063aa8e8ff0 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.h +++ b/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.h @@ -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, - EventPriority priority) const; + void dispatchRawState(StateUpdate &&stateUpdate, EventPriority priority) + const; private: friend ShadowNode; diff --git a/ReactCommon/fabric/core/state/ConcreteState.h b/ReactCommon/fabric/core/state/ConcreteState.h index e5ef7678ca5..60806235682 100644 --- a/ReactCommon/fabric/core/state/ConcreteState.h +++ b/ReactCommon/fabric/core/state/ConcreteState.h @@ -70,14 +70,14 @@ class ConcreteState : public State { std::function callback, EventPriority priority = EventPriority::AsynchronousBatched) const { family_->dispatchRawState( - {[family = family_, - callback = std::move(callback)]() -> StateData::Shared { + {[family = family_, callback = std::move(callback)]() + -> std::pair { auto target = family->getTarget(); auto oldState = target.getShadowNode().getState(); auto oldData = std::static_pointer_cast(oldState) ->getData(); auto newData = std::make_shared(callback(oldData)); - return newData; + return {family, newData}; }}, priority); } diff --git a/ReactCommon/fabric/core/state/StatePipe.h b/ReactCommon/fabric/core/state/StatePipe.h index 1eb6100a690..c1616482df9 100644 --- a/ReactCommon/fabric/core/state/StatePipe.h +++ b/ReactCommon/fabric/core/state/StatePipe.h @@ -15,8 +15,11 @@ namespace facebook { namespace react { +class ShadowNodeFamily; +using SharedShadowNodeFamily = std::shared_ptr; + using StatePipe = std::function< - void(const StateData::Shared &data, const StateTarget &target)>; + void(const StateData::Shared &data, SharedShadowNodeFamily const &family)>; } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/core/state/StateUpdate.cpp b/ReactCommon/fabric/core/state/StateUpdate.cpp index f73401f0dd0..aaabfcb394b 100644 --- a/ReactCommon/fabric/core/state/StateUpdate.cpp +++ b/ReactCommon/fabric/core/state/StateUpdate.cpp @@ -10,7 +10,8 @@ namespace facebook { namespace react { -std::pair StateUpdate::operator()() const { +std::pair StateUpdate:: +operator()() const { return callback_(); } diff --git a/ReactCommon/fabric/core/state/StateUpdate.h b/ReactCommon/fabric/core/state/StateUpdate.h index 6260baa7d3a..405684704c3 100644 --- a/ReactCommon/fabric/core/state/StateUpdate.h +++ b/ReactCommon/fabric/core/state/StateUpdate.h @@ -10,7 +10,6 @@ #include #include -#include 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; class StateUpdate { public: - std::pair operator()() const; + std::pair 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()> callback_; + std::function()> + callback_; }; } // namespace react diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index 29ce6dc7bc8..a4be7904234 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -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( diff --git a/ReactCommon/fabric/uimanager/UIManager.cpp b/ReactCommon/fabric/uimanager/UIManager.cpp index 37687c721b7..990cb0294b7 100644 --- a/ReactCommon/fabric/uimanager/UIManager.cpp +++ b/ReactCommon/fabric/uimanager/UIManager.cpp @@ -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(), diff --git a/ReactCommon/fabric/uimanager/UIManager.h b/ReactCommon/fabric/uimanager/UIManager.h index 1d250b85de0..4f47d7702d7 100644 --- a/ReactCommon/fabric/uimanager/UIManager.h +++ b/ReactCommon/fabric/uimanager/UIManager.h @@ -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(