UIManager.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #include "UIManager.h"
  8. #include <react/core/ShadowNodeFragment.h>
  9. #include <react/debug/SystraceSection.h>
  10. #include <react/graphics/Geometry.h>
  11. #include <glog/logging.h>
  12. namespace facebook {
  13. namespace react {
  14. UIManager::~UIManager() {
  15. LOG(WARNING) << "UIManager::~UIManager() was called (address: " << this
  16. << ").";
  17. }
  18. SharedShadowNode UIManager::createNode(
  19. Tag tag,
  20. std::string const &name,
  21. SurfaceId surfaceId,
  22. const RawProps &rawProps,
  23. SharedEventTarget eventTarget) const {
  24. SystraceSection s("UIManager::createNode");
  25. auto &componentDescriptor = componentDescriptorRegistry_->at(name);
  26. auto fallbackDescriptor =
  27. componentDescriptorRegistry_->getFallbackComponentDescriptor();
  28. auto family = componentDescriptor.createFamily(
  29. ShadowNodeFamilyFragment{tag, surfaceId, nullptr},
  30. std::move(eventTarget));
  31. auto const props = componentDescriptor.cloneProps(nullptr, rawProps);
  32. auto const state =
  33. componentDescriptor.createInitialState(ShadowNodeFragment{props}, family);
  34. auto shadowNode = componentDescriptor.createShadowNode(
  35. ShadowNodeFragment{
  36. /* .props = */
  37. fallbackDescriptor != nullptr &&
  38. fallbackDescriptor->getComponentHandle() ==
  39. componentDescriptor.getComponentHandle()
  40. ? componentDescriptor.cloneProps(
  41. props, RawProps(folly::dynamic::object("name", name)))
  42. : props,
  43. /* .children = */ ShadowNodeFragment::childrenPlaceholder(),
  44. /* .state = */ state,
  45. },
  46. family);
  47. if (delegate_) {
  48. delegate_->uiManagerDidCreateShadowNode(shadowNode);
  49. }
  50. return shadowNode;
  51. }
  52. SharedShadowNode UIManager::cloneNode(
  53. const ShadowNode::Shared &shadowNode,
  54. const SharedShadowNodeSharedList &children,
  55. const RawProps *rawProps) const {
  56. SystraceSection s("UIManager::cloneNode");
  57. auto &componentDescriptor = shadowNode->getComponentDescriptor();
  58. auto clonedShadowNode = componentDescriptor.cloneShadowNode(
  59. *shadowNode,
  60. {
  61. /* .props = */
  62. rawProps ? componentDescriptor.cloneProps(
  63. shadowNode->getProps(), *rawProps)
  64. : ShadowNodeFragment::propsPlaceholder(),
  65. /* .children = */ children,
  66. });
  67. return clonedShadowNode;
  68. }
  69. void UIManager::appendChild(
  70. const ShadowNode::Shared &parentShadowNode,
  71. const ShadowNode::Shared &childShadowNode) const {
  72. SystraceSection s("UIManager::appendChild");
  73. auto &componentDescriptor = parentShadowNode->getComponentDescriptor();
  74. componentDescriptor.appendChild(parentShadowNode, childShadowNode);
  75. }
  76. void UIManager::completeSurface(
  77. SurfaceId surfaceId,
  78. const SharedShadowNodeUnsharedList &rootChildren) const {
  79. SystraceSection s("UIManager::completeSurface");
  80. shadowTreeRegistry_.visit(surfaceId, [&](ShadowTree const &shadowTree) {
  81. shadowTree.commit(
  82. [&](RootShadowNode::Shared const &oldRootShadowNode) {
  83. return std::make_shared<RootShadowNode>(
  84. *oldRootShadowNode,
  85. ShadowNodeFragment{
  86. /* .props = */ ShadowNodeFragment::propsPlaceholder(),
  87. /* .children = */ rootChildren,
  88. });
  89. },
  90. true);
  91. });
  92. }
  93. void UIManager::setJSResponder(
  94. const ShadowNode::Shared &shadowNode,
  95. const bool blockNativeResponder) const {
  96. if (delegate_) {
  97. delegate_->uiManagerDidSetJSResponder(
  98. shadowNode->getSurfaceId(), shadowNode, blockNativeResponder);
  99. }
  100. }
  101. void UIManager::clearJSResponder() const {
  102. if (delegate_) {
  103. delegate_->uiManagerDidClearJSResponder();
  104. }
  105. }
  106. ShadowNode::Shared const *UIManager::getNewestCloneOfShadowNode(
  107. ShadowNode::Shared const &shadowNode) const {
  108. auto findNewestChildInParent =
  109. [&](auto const &parentNode) -> ShadowNode::Shared const * {
  110. for (auto const &child : parentNode.getChildren()) {
  111. if (ShadowNode::sameFamily(*child, *shadowNode)) {
  112. return &child;
  113. }
  114. }
  115. return nullptr;
  116. };
  117. ShadowNode const *ancestorShadowNode;
  118. shadowTreeRegistry_.visit(
  119. shadowNode->getSurfaceId(), [&](ShadowTree const &shadowTree) {
  120. shadowTree.tryCommit(
  121. [&](RootShadowNode::Shared const &oldRootShadowNode) {
  122. ancestorShadowNode = oldRootShadowNode.get();
  123. return nullptr;
  124. },
  125. true);
  126. });
  127. auto ancestors = shadowNode->getFamily().getAncestors(*ancestorShadowNode);
  128. return findNewestChildInParent(ancestors.rbegin()->first.get());
  129. }
  130. ShadowNode::Shared UIManager::findNodeAtPoint(
  131. ShadowNode::Shared const &node,
  132. Point point) const {
  133. return LayoutableShadowNode::findNodeAtPoint(
  134. *getNewestCloneOfShadowNode(node), point);
  135. }
  136. void UIManager::setNativeProps(
  137. ShadowNode const &shadowNode,
  138. RawProps const &rawProps) const {
  139. SystraceSection s("UIManager::setNativeProps");
  140. auto &componentDescriptor = shadowNode.getComponentDescriptor();
  141. auto props = componentDescriptor.cloneProps(shadowNode.getProps(), rawProps);
  142. shadowTreeRegistry_.visit(
  143. shadowNode.getSurfaceId(), [&](ShadowTree const &shadowTree) {
  144. shadowTree.tryCommit(
  145. [&](RootShadowNode::Shared const &oldRootShadowNode) {
  146. return std::static_pointer_cast<RootShadowNode>(
  147. oldRootShadowNode->cloneTree(
  148. shadowNode.getFamily(),
  149. [&](ShadowNode const &oldShadowNode) {
  150. return oldShadowNode.clone({
  151. /* .props = */ props,
  152. });
  153. }));
  154. },
  155. true);
  156. });
  157. }
  158. LayoutMetrics UIManager::getRelativeLayoutMetrics(
  159. ShadowNode const &shadowNode,
  160. ShadowNode const *ancestorShadowNode,
  161. LayoutableShadowNode::LayoutInspectingPolicy policy) const {
  162. SystraceSection s("UIManager::getRelativeLayoutMetrics");
  163. if (!ancestorShadowNode) {
  164. shadowTreeRegistry_.visit(
  165. shadowNode.getSurfaceId(), [&](ShadowTree const &shadowTree) {
  166. shadowTree.tryCommit(
  167. [&](RootShadowNode::Shared const &oldRootShadowNode) {
  168. ancestorShadowNode = oldRootShadowNode.get();
  169. return nullptr;
  170. },
  171. true);
  172. });
  173. }
  174. auto layoutableShadowNode =
  175. traitCast<LayoutableShadowNode const *>(&shadowNode);
  176. auto layoutableAncestorShadowNode =
  177. traitCast<LayoutableShadowNode const *>(ancestorShadowNode);
  178. if (!layoutableShadowNode || !layoutableAncestorShadowNode) {
  179. return EmptyLayoutMetrics;
  180. }
  181. return layoutableShadowNode->getRelativeLayoutMetrics(
  182. *layoutableAncestorShadowNode, policy);
  183. }
  184. void UIManager::updateState(StateUpdate const &stateUpdate) const {
  185. auto &callback = stateUpdate.callback;
  186. auto &family = stateUpdate.family;
  187. auto &componentDescriptor = family->getComponentDescriptor();
  188. shadowTreeRegistry_.visit(
  189. family->getSurfaceId(), [&](ShadowTree const &shadowTree) {
  190. shadowTree.tryCommit([&](RootShadowNode::Shared const
  191. &oldRootShadowNode) {
  192. return std::static_pointer_cast<
  193. RootShadowNode>(oldRootShadowNode->cloneTree(
  194. *family, [&](ShadowNode const &oldShadowNode) {
  195. auto newData =
  196. callback(oldShadowNode.getState()->getDataPointer());
  197. auto newState =
  198. componentDescriptor.createState(*family, newData);
  199. return oldShadowNode.clone({
  200. /* .props = */ ShadowNodeFragment::propsPlaceholder(),
  201. /* .children = */ ShadowNodeFragment::childrenPlaceholder(),
  202. /* .state = */ newState,
  203. });
  204. }));
  205. });
  206. });
  207. }
  208. void UIManager::dispatchCommand(
  209. const ShadowNode::Shared &shadowNode,
  210. std::string const &commandName,
  211. folly::dynamic const args) const {
  212. if (delegate_) {
  213. delegate_->uiManagerDidDispatchCommand(shadowNode, commandName, args);
  214. }
  215. }
  216. void UIManager::setComponentDescriptorRegistry(
  217. const SharedComponentDescriptorRegistry &componentDescriptorRegistry) {
  218. componentDescriptorRegistry_ = componentDescriptorRegistry;
  219. }
  220. void UIManager::setDelegate(UIManagerDelegate *delegate) {
  221. delegate_ = delegate;
  222. }
  223. UIManagerDelegate *UIManager::getDelegate() {
  224. return delegate_;
  225. }
  226. void UIManager::visitBinding(
  227. std::function<void(UIManagerBinding const &uiManagerBinding)> callback)
  228. const {
  229. if (!uiManagerBinding_) {
  230. return;
  231. }
  232. callback(*uiManagerBinding_);
  233. }
  234. ShadowTreeRegistry const &UIManager::getShadowTreeRegistry() const {
  235. return shadowTreeRegistry_;
  236. }
  237. #pragma mark - ShadowTreeDelegate
  238. void UIManager::shadowTreeDidFinishTransaction(
  239. ShadowTree const &shadowTree,
  240. MountingCoordinator::Shared const &mountingCoordinator) const {
  241. SystraceSection s("UIManager::shadowTreeDidFinishTransaction");
  242. if (delegate_) {
  243. delegate_->uiManagerDidFinishTransaction(mountingCoordinator);
  244. }
  245. }
  246. } // namespace react
  247. } // namespace facebook