Properly implement manageChildren(), correctly handling moveFrom and moveTo

Summary: Previously, manageChildren() would throw an Exception if moveFrom != null or moveTo != null. This is obviously not correct, because no matter how rare these events are, they actually happen in practice. This diff re-implements manageChildren() to support all the cases. It does so by first removing all the elements that need to be removed. During removal, those elements that need to be moved will be temporarily put into `mNodesToMove` array. Then the next step is to add all elements (including new elements to add, and existing elements to move). There is an fast path when only one of another is present. If both types are present, they need to be sorted, first, to maintain correct orded. A similar optimization is applied to `removeChildren()`: there is a fast path when moveFrom == null and a another fast path when removeFrom == null. When both are != null, a merge sort is used (it is assumed that both moveFrom and removeFrom are sorted).

Reviewed By: ahmedre

Differential Revision: D2768689
This commit is contained in:
Denis Koroskin
2015-12-17 19:45:24 -08:00
committed by Ahmed El-Helw
parent 04ae4b0ba3
commit 99d1c15c4d
2 changed files with 205 additions and 33 deletions

View File

@@ -46,6 +46,7 @@ import com.facebook.react.uimanager.ViewProps;
private boolean mMountsToView;
private boolean mBackingViewIsCreated;
private @Nullable DrawBackgroundColor mDrawBackground;
private int mMoveToIndexInParent;
/* package */ void handleUpdateProperties(CatalystStylesDiffMap styles) {
if (!mountsToView()) {
@@ -171,6 +172,14 @@ import com.facebook.react.uimanager.ViewProps;
mNodeRegions = nodeRegion;
}
/* package */ final void setMoveToIndexInParent(int moveToIndexInParent) {
mMoveToIndexInParent = moveToIndexInParent;
}
/* package */ final int getMoveToIndexInParent() {
return mMoveToIndexInParent;
}
/* package */ void updateNodeRegion(float left, float top, float right, float bottom) {
if (mNodeRegion.mLeft != left || mNodeRegion.mTop != top ||
mNodeRegion.mRight != right || mNodeRegion.mBottom != bottom) {