From 1d034cf91ddc2ee89765b5a718bfd907f79cab3e Mon Sep 17 00:00:00 2001 From: Seth Kirby Date: Thu, 28 Jul 2016 16:44:13 -0700 Subject: [PATCH] Delay dropping root views until the drop views step of StateBuilder. Summary: @public Make UIOperation public so that custom implementations can expose instances of it. Reviewed By: ahmedre Differential Revision: D3618197 --- .../flat/FlatNativeViewHierarchyManager.java | 7 ++++- .../react/flat/FlatUIImplementation.java | 1 - .../react/flat/FlatUIViewOperationQueue.java | 16 ++++------- .../com/facebook/react/flat/StateBuilder.java | 28 ++++++++++--------- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java index 84b3fbff0..740c46409 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java @@ -140,7 +140,12 @@ import com.facebook.react.uimanager.ViewManagerRegistry; /* package */ void dropViews(int[] viewsToDrop) { for (int viewToDrop : viewsToDrop) { - dropView(resolveView(viewToDrop)); + if (viewToDrop > 0) { + dropView(resolveView(viewToDrop)); + } else { + // Root views are noted with a negative tag from StateBuilder. + removeRootView(-viewToDrop); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java index c89cfdc77..de57540da 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java @@ -490,7 +490,6 @@ public class FlatUIImplementation extends UIImplementation { @Override public void removeRootView(int rootViewTag) { mStateBuilder.removeRootView(rootViewTag); - super.removeRootView(rootViewTag); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java index 7cf0f80e7..fdbeeae25 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIViewOperationQueue.java @@ -230,7 +230,7 @@ import com.facebook.react.uimanager.UIViewOperationQueue; } } - public final class DetachAllChildrenFromViews implements UIViewOperationQueue.UIOperation { + public final class DetachAllChildrenFromViews implements UIOperation { private @Nullable int[] mViewsToDetachAllChildrenFrom; public void setViewsToDetachAllChildrenFrom(int[] viewsToDetachAllChildrenFrom) { @@ -369,6 +369,9 @@ import com.facebook.react.uimanager.UIViewOperationQueue; enqueueUIOperation(new UpdateViewGroup(reactTag, viewsToAdd, viewsToDetach)); } + /** + * Creates a new UIOperation that will update View bounds for a View defined by reactTag. + */ public UpdateViewBounds createUpdateViewBounds( int reactTag, int left, @@ -378,13 +381,6 @@ import com.facebook.react.uimanager.UIViewOperationQueue; return new UpdateViewBounds(reactTag, left, top, right, bottom); } - /** - * Enqueues a new UIOperation that will update View bounds for a View defined by reactTag. - */ - public void enqueueUpdateViewBounds(UpdateViewBounds updateViewBounds) { - enqueueUIOperation(updateViewBounds); - } - public ViewManagerCommand createViewManagerCommand( int reactTag, int command, @@ -392,8 +388,8 @@ import com.facebook.react.uimanager.UIViewOperationQueue; return new ViewManagerCommand(reactTag, command, args); } - public void enqueueViewManagerCommand(ViewManagerCommand viewManagerCommand) { - enqueueUIOperation(viewManagerCommand); + /* package */ void enqueueFlatUIOperation(UIOperation operation) { + enqueueUIOperation(operation); } public void enqueueSetPadding( diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java index a966e6694..0f59af1b4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java @@ -18,6 +18,7 @@ import com.facebook.react.bridge.ReadableArray; import com.facebook.react.uimanager.OnLayoutEvent; import com.facebook.react.uimanager.ReactShadowNode; import com.facebook.react.uimanager.ReactStylesDiffMap; +import com.facebook.react.uimanager.UIViewOperationQueue; import com.facebook.react.uimanager.events.EventDispatcher; /** @@ -45,11 +46,11 @@ import com.facebook.react.uimanager.events.EventDispatcher; private final ArrayList mViewsToDetachAllChildrenFrom = new ArrayList<>(); private final ArrayList mViewsToDetach = new ArrayList<>(); - private final ArrayList mViewsToDrop = new ArrayList<>(); + private final ArrayList mViewsToDrop = new ArrayList<>(); private final ArrayList mOnLayoutEvents = new ArrayList<>(); - private final ArrayList mUpdateViewBoundsOperations = + private final ArrayList mUpdateViewBoundsOperations = new ArrayList<>(); - private final ArrayList mViewManagerCommands = + private final ArrayList mViewManagerCommands = new ArrayList<>(); private @Nullable FlatUIViewOperationQueue.DetachAllChildrenFromViews mDetachAllChildrenFromViews; @@ -98,7 +99,7 @@ import com.facebook.react.uimanager.events.EventDispatcher; } for (int i = 0, size = mUpdateViewBoundsOperations.size(); i != size; ++i) { - mOperationsQueue.enqueueUpdateViewBounds(mUpdateViewBoundsOperations.get(i)); + mOperationsQueue.enqueueFlatUIOperation(mUpdateViewBoundsOperations.get(i)); } mUpdateViewBoundsOperations.clear(); @@ -106,7 +107,7 @@ import com.facebook.react.uimanager.events.EventDispatcher; // happened before we actually dispatch the view manager command. This prevents things like // commands going to empty parents and views not yet being created. for (int i = 0, size = mViewManagerCommands.size(); i != size; i++) { - mOperationsQueue.enqueueViewManagerCommand(mViewManagerCommands.get(i)); + mOperationsQueue.enqueueFlatUIOperation(mViewManagerCommands.get(i)); } mViewManagerCommands.clear(); @@ -118,7 +119,12 @@ import com.facebook.react.uimanager.events.EventDispatcher; mOnLayoutEvents.clear(); if (!mViewsToDrop.isEmpty()) { - mOperationsQueue.enqueueDropViews(collectViewTags(mViewsToDrop)); + int[] viewsToDrop = new int[mViewsToDrop.size()]; + int i = 0; + for (int x : mViewsToDrop) { + viewsToDrop[i++] = x; + } + mOperationsQueue.enqueueDropViews(viewsToDrop); mViewsToDrop.clear(); } @@ -126,12 +132,8 @@ import com.facebook.react.uimanager.events.EventDispatcher; } /* package */ void removeRootView(int rootViewTag) { - // Don't remove Views that are connected to a View that we are about to remove. - for (int i = mViewsToDrop.size() - 1; i >= 0; --i) { - if (mViewsToDrop.get(i).getRootNode().getReactTag() == rootViewTag) { - mViewsToDrop.remove(i); - } - } + // Note root view tags with a negative value. + mViewsToDrop.add(-rootViewTag); } /** @@ -185,7 +187,7 @@ import com.facebook.react.uimanager.events.EventDispatcher; } /* package */ void dropView(FlatShadowNode node) { - mViewsToDrop.add(node); + mViewsToDrop.add(node.getReactTag()); } private void addNodeRegion(