Permalink
Browse files

Initial FlatUIImplemenatation

Summary: public This patch adds an alternative UIImplementation based on an idea of creating UI hierarchy off-the-main-thread (everything but Views), flattening ReactShadowNode hierarchy and displaying it within a single View when possible. While NativeViewHierarchyOptimizer allows removing layout-only RCTViews, this allows removing RCTView, RCTText and RCTImage.

This is an initial bare-bones implementation that doesn't really draw anything, only lays out the shadow nodes. Followup diffs will add missing features.

Reviewed By: astreet

Differential Revision: D2564309

fb-gh-sync-id: 2dda4c8cfc2bac3eb39c5c15e97bd23a57550a1d
  • Loading branch information...
korDen authored and facebook-github-bot-5 committed Dec 1, 2015
1 parent b0e39d2 commit b828ae4200c6e2650d1ae608982e945cfb1470ec
@@ -41,15 +41,40 @@
private final int[] mMeasureBuffer = new int[4];
public UIImplementation(ReactApplicationContext reactContext, List<ViewManager> viewManagers) {
- mViewManagers = new ViewManagerRegistry(viewManagers);
- mOperationsQueue = new UIViewOperationQueue(
- reactContext,
- new NativeViewHierarchyManager(mViewManagers));
+ this(reactContext, new ViewManagerRegistry(viewManagers));
+ }
+
+ private UIImplementation(ReactApplicationContext reactContext, ViewManagerRegistry viewManagers) {
+ this(
+ viewManagers,
+ new UIViewOperationQueue(reactContext, new NativeViewHierarchyManager(viewManagers)));
+ }
+
+ protected UIImplementation(
+ ViewManagerRegistry viewManagers,
+ UIViewOperationQueue operationsQueue) {
+ mViewManagers = viewManagers;
+ mOperationsQueue = operationsQueue;
mNativeViewHierarchyOptimizer = new NativeViewHierarchyOptimizer(
mOperationsQueue,
mShadowNodeRegistry);
}
+ protected ReactShadowNode createRootShadowNode() {
+ ReactShadowNode rootCSSNode = new ReactShadowNode();
+ rootCSSNode.setViewClassName("Root");
+ return rootCSSNode;
+ }
+
+ protected ReactShadowNode createShadowNode(String className) {
+ ViewManager viewManager = mViewManagers.get(className);
+ return viewManager.createShadowNodeInstance();
+ }
+
+ protected final ReactShadowNode resolveShadowNode(int reactTag) {
+ return mShadowNodeRegistry.getNode(reactTag);
+ }
+
/**
* Registers a root node with a given tag, size and ThemedReactContext
* and adds it to a node registry.
@@ -60,12 +85,11 @@ public void registerRootView(
int width,
int height,
ThemedReactContext context) {
- final ReactShadowNode rootCSSNode = new ReactShadowNode();
+ final ReactShadowNode rootCSSNode = createRootShadowNode();
rootCSSNode.setReactTag(tag);
rootCSSNode.setThemedContext(context);
rootCSSNode.setStyleWidth(width);
rootCSSNode.setStyleHeight(height);
- rootCSSNode.setViewClassName("Root");
mShadowNodeRegistry.addRootNode(rootCSSNode);
// register it within NativeViewHierarchyManager
@@ -104,8 +128,7 @@ public void updateRootNodeSize(
* Invoked by React to create a new node with a given tag, class name and properties.
*/
public void createView(int tag, String className, int rootViewTag, ReadableMap props) {
- ViewManager viewManager = mViewManagers.get(className);
- ReactShadowNode cssNode = viewManager.createShadowNodeInstance();
+ ReactShadowNode cssNode = createShadowNode(className);
ReactShadowNode rootNode = mShadowNodeRegistry.getNode(rootViewTag);
cssNode.setReactTag(tag);
cssNode.setViewClassName(className);
@@ -120,8 +143,15 @@ public void createView(int tag, String className, int rootViewTag, ReadableMap p
cssNode.updateProperties(styles);
}
+ handleCreateView(cssNode, rootViewTag, styles);
+ }
+
+ protected void handleCreateView(
+ ReactShadowNode cssNode,
+ int rootViewTag,
+ @Nullable CatalystStylesDiffMap styles) {
if (!cssNode.isVirtual()) {
- mNativeViewHierarchyOptimizer.handleCreateView(cssNode, rootNode.getThemedContext(), styles);
+ mNativeViewHierarchyOptimizer.handleCreateView(cssNode, cssNode.getThemedContext(), styles);
}
}
@@ -141,9 +171,16 @@ public void updateView(int tag, String className, ReadableMap props) {
if (props != null) {
CatalystStylesDiffMap styles = new CatalystStylesDiffMap(props);
cssNode.updateProperties(styles);
- if (!cssNode.isVirtual()) {
- mNativeViewHierarchyOptimizer.handleUpdateView(cssNode, className, styles);
- }
+ handleUpdateView(cssNode, className, styles);
+ }
+ }
+
+ protected void handleUpdateView(
+ ReactShadowNode cssNode,
+ String className,
+ CatalystStylesDiffMap styles) {
+ if (!cssNode.isVirtual()) {
+ mNativeViewHierarchyOptimizer.handleUpdateView(cssNode, className, styles);
}
}
@@ -401,14 +438,7 @@ public void dispatchViewUpdates(EventDispatcher eventDispatcher, int batchId) {
ReactShadowNode cssRoot = mShadowNodeRegistry.getNode(tag);
notifyOnBeforeLayoutRecursive(cssRoot);
- SystraceMessage.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "cssRoot.calculateLayout")
- .arg("rootTag", tag)
- .flush();
- try {
- cssRoot.calculateLayout(mLayoutContext);
- } finally {
- Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
- }
+ calculateRootLayout(cssRoot);
applyUpdatesRecursive(cssRoot, 0f, 0f, eventDispatcher);
}
@@ -492,7 +522,7 @@ public void setViewHierarchyUpdateDebugListener(
mOperationsQueue.setViewHierarchyUpdateDebugListener(listener);
}
- private void removeShadowNode(ReactShadowNode nodeToRemove) {
+ protected final void removeShadowNode(ReactShadowNode nodeToRemove) {
mNativeViewHierarchyOptimizer.handleRemoveNode(nodeToRemove);
mShadowNodeRegistry.removeNode(nodeToRemove.getReactTag());
for (int i = nodeToRemove.getChildCount() - 1; i >= 0; i--) {
@@ -597,7 +627,18 @@ private void notifyOnBeforeLayoutRecursive(ReactShadowNode cssNode) {
cssNode.onBeforeLayout();
}
- private void applyUpdatesRecursive(
+ protected void calculateRootLayout(ReactShadowNode cssRoot) {
+ SystraceMessage.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "cssRoot.calculateLayout")
+ .arg("rootTag", cssRoot.getReactTag())
+ .flush();
+ try {
+ cssRoot.calculateLayout(mLayoutContext);
+ } finally {
+ Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
+ }
+ }
+
+ protected void applyUpdatesRecursive(
ReactShadowNode cssNode,
float absoluteX,
float absoluteY,
@@ -440,7 +440,7 @@ public void execute() {
private @Nullable NotThreadSafeViewHierarchyUpdateDebugListener mViewHierarchyUpdateDebugListener;
- protected UIViewOperationQueue(
+ public UIViewOperationQueue(
ReactApplicationContext reactContext,
NativeViewHierarchyManager nativeViewHierarchyManager) {
mNativeViewHierarchyManager = nativeViewHierarchyManager;

0 comments on commit b828ae4

Please sign in to comment.