Abstract classes for ShadowNode and Props
Summary: Foundation clases for Fabric designed to be "const-first". Reviewed By: fkgozali Differential Revision: D7230672 fbshipit-source-id: 433acd35a7958d5d577358b0a306923f970e573f
This commit is contained in:
parent
d16772a31e
commit
c623455845
|
@ -8,7 +8,6 @@
|
|||
#include "FabricUIManager.h"
|
||||
|
||||
#include "IFabricPlatformUIOperationManager.h"
|
||||
#include "ShadowNode.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
@ -16,38 +15,38 @@ namespace react {
|
|||
FabricUIManager::FabricUIManager(const std::shared_ptr<IFabricPlatformUIOperationManager> &platformUIOperationManager) :
|
||||
platformUIOperationManager_(platformUIOperationManager) {};
|
||||
|
||||
ShadowNodeRef FabricUIManager::createNode(int reactTag, std::string viewName, int rootTag, folly::dynamic props, void *instanceHandle) {
|
||||
SharedShadowNode FabricUIManager::createNode(int reactTag, std::string viewName, int rootTag, folly::dynamic props, void *instanceHandle) {
|
||||
platformUIOperationManager_->performUIOperation();
|
||||
return std::make_shared<ShadowNode>(reactTag, viewName, rootTag, props, instanceHandle);
|
||||
}
|
||||
|
||||
ShadowNodeRef FabricUIManager::cloneNode(const ShadowNodeRef &node) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ShadowNodeRef FabricUIManager::cloneNodeWithNewChildren(const ShadowNodeRef &node) {
|
||||
SharedShadowNode FabricUIManager::cloneNode(const SharedShadowNode &node) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ShadowNodeRef FabricUIManager::cloneNodeWithNewProps(const ShadowNodeRef &node, folly::dynamic props) {
|
||||
SharedShadowNode FabricUIManager::cloneNodeWithNewChildren(const SharedShadowNode &node) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ShadowNodeRef FabricUIManager::cloneNodeWithNewChildrenAndProps(const ShadowNodeRef &node, folly::dynamic newProps) {
|
||||
SharedShadowNode FabricUIManager::cloneNodeWithNewProps(const SharedShadowNode &node, folly::dynamic props) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FabricUIManager::appendChild(const ShadowNodeRef &parentNode, const ShadowNodeRef &childNode) {
|
||||
}
|
||||
|
||||
ShadowNodeSetRef FabricUIManager::createChildSet(int rootTag) {
|
||||
SharedShadowNode FabricUIManager::cloneNodeWithNewChildrenAndProps(const SharedShadowNode &node, folly::dynamic newProps) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FabricUIManager::appendChildToSet(const ShadowNodeSetRef &childSet, const ShadowNodeRef &childNode) {
|
||||
void FabricUIManager::appendChild(const SharedShadowNode &parentNode, const SharedShadowNode &childNode) {
|
||||
}
|
||||
|
||||
void FabricUIManager::completeRoot(int rootTag, const ShadowNodeSetRef &childSet) {
|
||||
SharedShadowNodeUnsharedList FabricUIManager::createChildSet(int rootTag) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FabricUIManager::appendChildToSet(const SharedShadowNodeUnsharedList &childSet, const SharedShadowNode &childNode) {
|
||||
}
|
||||
|
||||
void FabricUIManager::completeRoot(int rootTag, const SharedShadowNodeUnsharedList &childSet) {
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -11,29 +11,26 @@
|
|||
#include <folly/FBVector.h>
|
||||
#include <memory>
|
||||
|
||||
#include <fabric/core/ShadowNode.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class ShadowNode;
|
||||
class IFabricPlatformUIOperationManager;
|
||||
|
||||
typedef std::shared_ptr<const ShadowNode> ShadowNodeRef;
|
||||
typedef folly::fbvector<const ShadowNodeRef> ShadowNodeSet;
|
||||
typedef std::shared_ptr<const ShadowNodeSet> ShadowNodeSetRef;
|
||||
|
||||
class FabricUIManager {
|
||||
public:
|
||||
FabricUIManager(const std::shared_ptr<IFabricPlatformUIOperationManager> &platformUIOperationManager);
|
||||
|
||||
ShadowNodeRef createNode(int reactTag, std::string viewName, int rootTag, folly::dynamic props, void *instanceHandle);
|
||||
ShadowNodeRef cloneNode(const ShadowNodeRef &node);
|
||||
ShadowNodeRef cloneNodeWithNewChildren(const ShadowNodeRef &node);
|
||||
ShadowNodeRef cloneNodeWithNewProps(const ShadowNodeRef &node, folly::dynamic props);
|
||||
ShadowNodeRef cloneNodeWithNewChildrenAndProps(const ShadowNodeRef &node, folly::dynamic newProps);
|
||||
void appendChild(const ShadowNodeRef &parentNode, const ShadowNodeRef &childNode);
|
||||
ShadowNodeSetRef createChildSet(int rootTag);
|
||||
void appendChildToSet(const ShadowNodeSetRef &childSet, const ShadowNodeRef &childNode);
|
||||
void completeRoot(int rootTag, const ShadowNodeSetRef &childSet);
|
||||
SharedShadowNode createNode(int reactTag, std::string viewName, int rootTag, folly::dynamic props, void *instanceHandle);
|
||||
SharedShadowNode cloneNode(const SharedShadowNode &node);
|
||||
SharedShadowNode cloneNodeWithNewChildren(const SharedShadowNode &node);
|
||||
SharedShadowNode cloneNodeWithNewProps(const SharedShadowNode &node, folly::dynamic props);
|
||||
SharedShadowNode cloneNodeWithNewChildrenAndProps(const SharedShadowNode &node, folly::dynamic newProps);
|
||||
void appendChild(const SharedShadowNode &parentNode, const SharedShadowNode &childNode);
|
||||
SharedShadowNodeUnsharedList createChildSet(int rootTag);
|
||||
void appendChildToSet(const SharedShadowNodeUnsharedList &childSet, const SharedShadowNode &childNode);
|
||||
void completeRoot(int rootTag, const SharedShadowNodeUnsharedList &childSet);
|
||||
|
||||
private:
|
||||
std::shared_ptr<IFabricPlatformUIOperationManager> platformUIOperationManager_;
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "ShadowNode.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
ShadowNode::ShadowNode(int reactTag, std::string viewName, int rootTag, folly::dynamic props, void *instanceHandle) :
|
||||
reactTag_(reactTag),
|
||||
viewName_(viewName),
|
||||
rootTag_(rootTag),
|
||||
props_(props),
|
||||
instanceHandle_(instanceHandle) {}
|
||||
|
||||
}}
|
|
@ -1,27 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
#include <memory>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class ShadowNode {
|
||||
public:
|
||||
int reactTag_;
|
||||
std::string viewName_;
|
||||
int rootTag_;
|
||||
folly::dynamic props_;
|
||||
void *instanceHandle_;
|
||||
|
||||
ShadowNode(int reactTag, std::string viewName, int rootTag, folly::dynamic props, void *instanceHandle);
|
||||
};
|
||||
|
||||
}}
|
|
@ -23,6 +23,7 @@ rn_xplat_cxx_library(
|
|||
exported_headers = subdir_glob(
|
||||
[
|
||||
("primitives", "*.h"),
|
||||
("shadownode", "*.h"),
|
||||
],
|
||||
prefix = "fabric/core",
|
||||
),
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* `Tag` and `InstanceHandle` are used to address React Native components.
|
||||
*/
|
||||
using Tag = int32_t;
|
||||
using InstanceHandle = void *;
|
||||
|
||||
/*
|
||||
* `RawProps` represents untyped map with props comes from JavaScript side.
|
||||
*/
|
||||
// TODO(T26954420): Use iterator as underlying type for RawProps.
|
||||
using RawProps = std::map<std::string, folly::dynamic>;
|
||||
using SharedRawProps = std::shared_ptr<const RawProps>;
|
||||
|
||||
/*
|
||||
* Components event handlers.
|
||||
* Something which usually called from JavaScript side.
|
||||
*/
|
||||
using BubblingEventHandler = void (*)(void);
|
||||
using SharedBubblingEventHandler = std::shared_ptr<BubblingEventHandler>;
|
||||
using DirectEventHandler = void (*)(void);
|
||||
using SharedDirectEventHandler = std::shared_ptr<DirectEventHandler>;
|
||||
|
||||
/*
|
||||
* Universal component handle which allows to refer to `ComponentDescriptor`s
|
||||
* in maps efficiently.
|
||||
* Practically, it's something that concrete ShadowNode and concrete
|
||||
* ComponentDescriptor have in common.
|
||||
*/
|
||||
using ComponentHandle = size_t;
|
||||
|
||||
/*
|
||||
* String identifier for components used for addressing them from
|
||||
* JavaScript side.
|
||||
*/
|
||||
using ComponentName = std::string;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "Props.h"
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
void Props::apply(const RawProps &rawProps) {
|
||||
ensureUnsealed();
|
||||
|
||||
for (auto const &pair : rawProps) {
|
||||
auto const &name = pair.first;
|
||||
auto const &value = pair.second;
|
||||
|
||||
if (name == "nativeID") {
|
||||
nativeId_ = value.asString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
#include <fabric/core/Sealable.h>
|
||||
#include <fabric/core/ReactPrimitives.h>
|
||||
#include <fabric/debug/DebugStringConvertible.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class Props;
|
||||
|
||||
using SharedProps = std::shared_ptr<const Props>;
|
||||
|
||||
/*
|
||||
* Represents the most generic props object.
|
||||
*/
|
||||
class Props:
|
||||
public virtual Sealable,
|
||||
public virtual DebugStringConvertible {
|
||||
|
||||
public:
|
||||
virtual void apply(const RawProps &rawProps);
|
||||
|
||||
private:
|
||||
std::string nativeId_ {""};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "ShadowNode.h"
|
||||
|
||||
#include <fabric/debug/DebugStringConvertible.h>
|
||||
#include <fabric/debug/DebugStringConvertibleItem.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
SharedShadowNodeSharedList ShadowNode::emptySharedShadowNodeSharedList() {
|
||||
static const auto emptySharedShadowNodeSharedList = std::make_shared<SharedShadowNodeList>();
|
||||
return emptySharedShadowNodeSharedList;
|
||||
}
|
||||
|
||||
#pragma mark - Constructors
|
||||
|
||||
ShadowNode::ShadowNode(
|
||||
Tag tag,
|
||||
InstanceHandle instanceHandle,
|
||||
SharedProps props,
|
||||
SharedShadowNodeSharedList children
|
||||
):
|
||||
tag_(tag),
|
||||
instanceHandle_(instanceHandle),
|
||||
props_(props),
|
||||
children_(children) {}
|
||||
|
||||
ShadowNode::ShadowNode(
|
||||
SharedShadowNode shadowNode,
|
||||
SharedProps props,
|
||||
SharedShadowNodeSharedList children
|
||||
):
|
||||
tag_(shadowNode->tag_),
|
||||
instanceHandle_(shadowNode->instanceHandle_),
|
||||
props_(props ? props : shadowNode->props_),
|
||||
children_(children ? children : shadowNode->children_) {}
|
||||
|
||||
#pragma mark - Getters
|
||||
|
||||
SharedShadowNodeSharedList ShadowNode::getChildren() const {
|
||||
return children_;
|
||||
}
|
||||
|
||||
SharedProps ShadowNode::getProps() const {
|
||||
return props_;
|
||||
}
|
||||
|
||||
Tag ShadowNode::getTag() const {
|
||||
return tag_;
|
||||
}
|
||||
|
||||
#pragma mark - Mutating Methods
|
||||
|
||||
void ShadowNode::sealRecursive() const {
|
||||
if (getSealed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
seal();
|
||||
|
||||
props_->seal();
|
||||
|
||||
for (auto child : *children_) {
|
||||
child->sealRecursive();
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowNode::appendChild(const SharedShadowNode &child) {
|
||||
ensureUnsealed();
|
||||
|
||||
// We cannot mutate `children_` in place here because it is a *shared*
|
||||
// data structure which means other `ShadowNodes` might refer to its old value.
|
||||
// So, we have to clone this and only then mutate.
|
||||
auto nonConstChildrenCopy = SharedShadowNodeList(*children_);
|
||||
nonConstChildrenCopy.push_back(child);
|
||||
children_ = std::make_shared<const SharedShadowNodeList>(nonConstChildrenCopy);
|
||||
}
|
||||
|
||||
void ShadowNode::replaceChild(const SharedShadowNode &oldChild, const SharedShadowNode &newChild) {
|
||||
ensureUnsealed();
|
||||
|
||||
// We cannot mutate `children_` in place here because it is a *shared*
|
||||
// data structure which means other `ShadowNodes` might refer to its old value.
|
||||
// So, we have to clone this and only then mutate.
|
||||
auto nonConstChildrenCopy = SharedShadowNodeList(*children_);
|
||||
std::replace(nonConstChildrenCopy.begin(), nonConstChildrenCopy.end(), oldChild, newChild);
|
||||
children_ = std::make_shared<const SharedShadowNodeList>(nonConstChildrenCopy);
|
||||
}
|
||||
|
||||
#pragma mark - DebugStringConvertible
|
||||
|
||||
std::string ShadowNode::getDebugName() const {
|
||||
return getComponentName();
|
||||
}
|
||||
|
||||
std::string ShadowNode::getDebugValue() const {
|
||||
return getSealed() ? "sealed" : "";
|
||||
}
|
||||
|
||||
SharedDebugStringConvertibleList ShadowNode::getDebugChildren() const {
|
||||
SharedDebugStringConvertibleList debugChildren = {};
|
||||
|
||||
for (auto child : *children_) {
|
||||
auto debugChild = std::dynamic_pointer_cast<const DebugStringConvertible>(child);
|
||||
if (debugChild) {
|
||||
debugChildren.push_back(debugChild);
|
||||
}
|
||||
}
|
||||
|
||||
return debugChildren;
|
||||
}
|
||||
|
||||
SharedDebugStringConvertibleList ShadowNode::getDebugProps() const {
|
||||
SharedDebugStringConvertibleList list = {};
|
||||
|
||||
list.push_back(std::make_shared<DebugStringConvertibleItem>("tag", std::to_string(tag_)));
|
||||
|
||||
if (instanceHandle_) {
|
||||
list.push_back(std::make_shared<DebugStringConvertibleItem>("handle", std::to_string((size_t)instanceHandle_)));
|
||||
}
|
||||
|
||||
SharedDebugStringConvertibleList propsList = props_->getDebugProps();
|
||||
std::move(propsList.begin(), propsList.end(), std::back_inserter(list));
|
||||
return list;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <fabric/core/Props.h>
|
||||
#include <fabric/core/Sealable.h>
|
||||
#include <fabric/core/ReactPrimitives.h>
|
||||
#include <fabric/debug/DebugStringConvertible.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class ShadowNode;
|
||||
|
||||
using SharedShadowNode = std::shared_ptr<const ShadowNode>;
|
||||
using SharedShadowNodeList = std::vector<std::shared_ptr<const ShadowNode>>;
|
||||
using SharedShadowNodeSharedList = std::shared_ptr<const SharedShadowNodeList>;
|
||||
using SharedShadowNodeUnsharedList = std::shared_ptr<SharedShadowNodeList>;
|
||||
|
||||
class ShadowNode:
|
||||
public virtual Sealable,
|
||||
public virtual DebugStringConvertible {
|
||||
public:
|
||||
static SharedShadowNodeSharedList emptySharedShadowNodeSharedList();
|
||||
|
||||
#pragma mark - Constructors
|
||||
|
||||
ShadowNode(
|
||||
Tag tag,
|
||||
InstanceHandle instanceHandle,
|
||||
SharedProps props = SharedProps(),
|
||||
SharedShadowNodeSharedList children = SharedShadowNodeSharedList()
|
||||
);
|
||||
|
||||
ShadowNode(
|
||||
SharedShadowNode shadowNode,
|
||||
SharedProps props = nullptr,
|
||||
SharedShadowNodeSharedList children = nullptr
|
||||
);
|
||||
|
||||
#pragma mark - Getters
|
||||
|
||||
virtual ComponentHandle getComponentHandle() const = 0;
|
||||
virtual ComponentName getComponentName() const = 0;
|
||||
|
||||
SharedShadowNodeSharedList getChildren() const;
|
||||
SharedProps getProps() const;
|
||||
Tag getTag() const;
|
||||
|
||||
#pragma mark - Mutating Methods
|
||||
|
||||
void sealRecursive() const;
|
||||
|
||||
void appendChild(const SharedShadowNode &child);
|
||||
void replaceChild(const SharedShadowNode &oldChild, const SharedShadowNode &newChild);
|
||||
|
||||
#pragma mark - DebugStringConvertible
|
||||
|
||||
std::string getDebugName() const override;
|
||||
std::string getDebugValue() const override;
|
||||
SharedDebugStringConvertibleList getDebugChildren() const override;
|
||||
SharedDebugStringConvertibleList getDebugProps() const override;
|
||||
|
||||
protected:
|
||||
Tag tag_;
|
||||
InstanceHandle instanceHandle_;
|
||||
SharedProps props_;
|
||||
SharedShadowNodeSharedList children_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
Loading…
Reference in New Issue