Fabric: Introducing Scheduler
Summary: Scheduler coordinates Shadow Tree updates and event flows (not yet). Reviewed By: mdvacca Differential Revision: D7503387 fbshipit-source-id: 4cb8bc574c25a0fd2ace6319c26c644a1e4757a9
This commit is contained in:
parent
f6f7d0484c
commit
ba45895a3f
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "Scheduler.h"
|
||||
|
||||
#include <fabric/core/LayoutContext.h>
|
||||
#include <fabric/uimanager/ComponentDescriptorRegistry.h>
|
||||
#include <fabric/uimanager/FabricUIManager.h>
|
||||
#include <fabric/view/ViewComponentDescriptor.h>
|
||||
#include <fabric/view/ViewProps.h>
|
||||
#include <fabric/view/ViewShadowNode.h>
|
||||
|
||||
#include "Differentiator.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
Scheduler::Scheduler() {
|
||||
auto componentDescriptorRegistry = std::make_shared<ComponentDescriptorRegistry>();
|
||||
SharedComponentDescriptor viewComponentDescriptor = std::make_shared<ViewComponentDescriptor>();
|
||||
componentDescriptorRegistry->registerComponentDescriptor(viewComponentDescriptor);
|
||||
|
||||
uiManager_ = std::make_shared<FabricUIManager>(componentDescriptorRegistry);
|
||||
uiManager_->setDelegate(this);
|
||||
}
|
||||
|
||||
Scheduler::~Scheduler() {
|
||||
uiManager_->setDelegate(nullptr);
|
||||
}
|
||||
|
||||
void Scheduler::registerRootTag(Tag rootTag) {
|
||||
auto rootShadowNode = std::make_shared<RootShadowNode>(rootTag, rootTag, nullptr);
|
||||
rootNodeRegistry_.insert({rootTag, rootShadowNode});
|
||||
}
|
||||
|
||||
void Scheduler::unregisterRootTag(Tag rootTag) {
|
||||
rootNodeRegistry_.erase(rootTag);
|
||||
}
|
||||
|
||||
#pragma mark - Delegate
|
||||
|
||||
void Scheduler::setDelegate(SchedulerDelegate *delegate) {
|
||||
delegate_ = delegate;
|
||||
}
|
||||
|
||||
SchedulerDelegate *Scheduler::getDelegate() {
|
||||
return delegate_;
|
||||
}
|
||||
|
||||
#pragma mark - UIManagerDelegate
|
||||
|
||||
void Scheduler::uiManagerDidFinishTransaction(Tag rootTag, const SharedShadowNodeUnsharedList &rootChildNodes) {
|
||||
SharedRootShadowNode oldRootShadowNode = rootNodeRegistry_[rootTag];
|
||||
assert(oldRootShadowNode);
|
||||
|
||||
SharedRootShadowNode newRootShadowNode =
|
||||
std::make_shared<RootShadowNode>(oldRootShadowNode, nullptr, SharedShadowNodeSharedList(rootChildNodes));
|
||||
|
||||
auto nonConstOldRootShadowNode = std::const_pointer_cast<RootShadowNode>(oldRootShadowNode);
|
||||
auto nonConstNewRootShadowNode = std::const_pointer_cast<RootShadowNode>(newRootShadowNode);
|
||||
|
||||
LayoutContext layoutContext = LayoutContext();
|
||||
layoutContext.affectedShadowNodes = std::make_shared<std::unordered_set<SharedLayoutableShadowNode>>();
|
||||
|
||||
LOG(INFO) << "Old Shadow Tree: \n" << oldRootShadowNode->getDebugDescription();
|
||||
LOG(INFO) << "New Shadow Tree *before* layout: \n" << newRootShadowNode->getDebugDescription();
|
||||
|
||||
nonConstNewRootShadowNode->layout(layoutContext);
|
||||
|
||||
nonConstNewRootShadowNode->sealRecursive();
|
||||
|
||||
LOG(INFO) << "New Shadow Tree *after* layout: \n" << nonConstNewRootShadowNode->getDebugDescription();
|
||||
|
||||
TreeMutationInstructionList instructions = TreeMutationInstructionList();
|
||||
|
||||
calculateMutationInstructions(
|
||||
instructions,
|
||||
oldRootShadowNode,
|
||||
oldRootShadowNode->ShadowNode::getChildren(),
|
||||
newRootShadowNode->ShadowNode::getChildren()
|
||||
);
|
||||
|
||||
LOG(INFO) << "TreeMutationInstructionList:";
|
||||
|
||||
for (auto instruction : instructions) {
|
||||
LOG(INFO) << "Instruction: " << instruction.getDebugDescription();
|
||||
}
|
||||
|
||||
rootNodeRegistry_[rootTag] = newRootShadowNode;
|
||||
|
||||
if (delegate_) {
|
||||
delegate_->schedulerDidComputeMutationInstructions(rootTag, instructions);
|
||||
}
|
||||
}
|
||||
|
||||
void Scheduler::uiManagerDidCreateShadowNode(const SharedShadowNode &shadowNode) {
|
||||
if (delegate_) {
|
||||
delegate_->schedulerDidRequestPreliminaryViewAllocation(shadowNode->getComponentName());
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Deprecated
|
||||
|
||||
std::shared_ptr<FabricUIManager> Scheduler::getUIManager_DO_NOT_USE() {
|
||||
return uiManager_;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <fabric/core/ComponentDescriptor.h>
|
||||
#include <fabric/core/LayoutConstraints.h>
|
||||
#include <fabric/uimanager/SchedulerDelegate.h>
|
||||
#include <fabric/uimanager/UIManagerDelegate.h>
|
||||
#include <fabric/view/ViewShadowNode.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* We expect having a dedicated subclass for root shadow node.
|
||||
*/
|
||||
using SharedRootShadowNode = SharedViewShadowNode;
|
||||
using RootShadowNode = ViewShadowNode;
|
||||
|
||||
class FabricUIManager;
|
||||
|
||||
/*
|
||||
* Scheduler coordinates Shadow Tree updates and event flows.
|
||||
*/
|
||||
class Scheduler:
|
||||
public UIManagerDelegate {
|
||||
|
||||
public:
|
||||
Scheduler();
|
||||
~Scheduler();
|
||||
|
||||
#pragma mark - Root Nodes Managerment
|
||||
|
||||
void registerRootTag(Tag rootTag);
|
||||
void unregisterRootTag(Tag rootTag);
|
||||
|
||||
void setLayoutConstraints(Tag rootTag, LayoutConstraints layoutConstraints);
|
||||
|
||||
#pragma mark - Delegate
|
||||
|
||||
/*
|
||||
* Sets and gets the Scheduler's delegate.
|
||||
* The delegate is stored as a raw pointer, so the owner must null
|
||||
* the pointer before being destroyed.
|
||||
*/
|
||||
void setDelegate(SchedulerDelegate *delegate);
|
||||
SchedulerDelegate *getDelegate();
|
||||
|
||||
#pragma mark - UIManagerDelegate
|
||||
|
||||
void uiManagerDidFinishTransaction(Tag rootTag, const SharedShadowNodeUnsharedList &rootChildNodes) override;
|
||||
void uiManagerDidCreateShadowNode(const SharedShadowNode &shadowNode) override;
|
||||
|
||||
#pragma mark - Deprecated
|
||||
|
||||
/*
|
||||
* UIManager instance must be temporarily exposed for registration purposes.
|
||||
*/
|
||||
std::shared_ptr<FabricUIManager> getUIManager_DO_NOT_USE();
|
||||
|
||||
private:
|
||||
SchedulerDelegate *delegate_;
|
||||
std::shared_ptr<FabricUIManager> uiManager_;
|
||||
|
||||
/*
|
||||
* All commited `RootShadowNode` instances to differentiate against.
|
||||
*/
|
||||
std::unordered_map<Tag, SharedRootShadowNode> rootNodeRegistry_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <fabric/core/ReactPrimitives.h>
|
||||
#include <fabric/core/ShadowNode.h>
|
||||
#include <fabric/uimanager/TreeMutationInstruction.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* Abstract class for Scheduler's delegate.
|
||||
*/
|
||||
class SchedulerDelegate {
|
||||
public:
|
||||
/*
|
||||
* Called right after Scheduler computed (and laid out) a new updated version
|
||||
* of the tree and calculated a set of mutation instructions which are
|
||||
* suffisient to construct a new one.
|
||||
*/
|
||||
virtual void schedulerDidComputeMutationInstructions(Tag rootTag, const TreeMutationInstructionList &instructions) = 0;
|
||||
|
||||
/*
|
||||
* Called right after a new ShadowNode was created.
|
||||
*/
|
||||
virtual void schedulerDidRequestPreliminaryViewAllocation(ComponentName componentName) = 0;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
Loading…
Reference in New Issue