From 70f0dfc0e67d8f3489ab31deeec12524bfde57fb Mon Sep 17 00:00:00 2001 From: Dan Witte Date: Thu, 3 Dec 2015 16:04:34 -0800 Subject: [PATCH] revert D2707930 Reviewed By: fkgozali Differential Revision: D2720828 fb-gh-sync-id: 53113fb33150b42a7b597a7dfd04bb9885def029 --- .../ReactNative/ReactNativeBaseComponent.js | 15 +-- .../ReactNative/ReactNativeDOMIDOperations.js | 1 - Libraries/ReactNative/ReactNativeMount.js | 10 -- React/Modules/RCTUIManager.m | 101 +++++------------- 4 files changed, 32 insertions(+), 95 deletions(-) diff --git a/Libraries/ReactNative/ReactNativeBaseComponent.js b/Libraries/ReactNative/ReactNativeBaseComponent.js index c7b4b42a8..266c7b30f 100644 --- a/Libraries/ReactNative/ReactNativeBaseComponent.js +++ b/Libraries/ReactNative/ReactNativeBaseComponent.js @@ -104,11 +104,11 @@ ReactNativeBaseComponent.Mixin = { // no children - let's avoid calling out to the native bridge for a large // portion of the children. if (mountImages.length) { - + var indexes = cachedIndexArray(mountImages.length); // TODO: Pool these per platform view class. Reusing the `mountImages` // array would likely be a jit deopt. var createdTags = []; - for (var i = 0, l = mountImages.length; i < l; i++) { + for (var i = 0; i < mountImages.length; i++) { var mountImage = mountImages[i]; var childTag = mountImage.tag; var childID = mountImage.rootNodeID; @@ -122,15 +122,8 @@ ReactNativeBaseComponent.Mixin = { ); createdTags[i] = mountImage.tag; } - - // Fast path for iOS - if (UIManager.addChildren) { - UIManager.addChildren(containerTag, createdTags); - return; - } - - var indexes = cachedIndexArray(mountImages.length); - UIManager.manageChildren(containerTag, null, null, createdTags, indexes, null); + UIManager + .manageChildren(containerTag, null, null, createdTags, indexes, null); } }, diff --git a/Libraries/ReactNative/ReactNativeDOMIDOperations.js b/Libraries/ReactNative/ReactNativeDOMIDOperations.js index a3ef1cc36..fbf90db50 100644 --- a/Libraries/ReactNative/ReactNativeDOMIDOperations.js +++ b/Libraries/ReactNative/ReactNativeDOMIDOperations.js @@ -53,7 +53,6 @@ var dangerouslyProcessChildrenUpdates = function(childrenUpdates, markupList) { (updates.addChildTags || (updates.addChildTags = [])).push(tag); } } - // Note this enumeration order will be different on V8! Move `byContainerTag` // to a sparse array as soon as we confirm there are not horrible perf // penalties. diff --git a/Libraries/ReactNative/ReactNativeMount.js b/Libraries/ReactNative/ReactNativeMount.js index 758fe1e5c..1f6dab51b 100644 --- a/Libraries/ReactNative/ReactNativeMount.js +++ b/Libraries/ReactNative/ReactNativeMount.js @@ -188,16 +188,6 @@ var ReactNativeMount = { mountImage.rootNodeID, mountImage.tag ); - - // Fast path for iOS - if (UIManager.addChildren) { - UIManager.addChildren( - ReactNativeTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID), - [mountImage.tag] - ); - return; - } - var addChildTags = [mountImage.tag]; var addAtIndices = [0]; UIManager.manageChildren( diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index 96ed3aa4e..c3c1ea589 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -720,33 +720,6 @@ RCT_EXPORT_METHOD(replaceExistingNonRootView:(nonnull NSNumber *)reactTag removeAtIndices:removeAtIndices]; } -RCT_EXPORT_METHOD(addChildren:(nonnull NSNumber *)containerTag - reactTags:(NSNumberArray *)reactTags) -{ - RCTAddChildren(containerTag, reactTags, - (NSDictionary> *)_shadowViewRegistry); - - [self addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry){ - - RCTAddChildren(containerTag, reactTags, - (NSDictionary> *)viewRegistry); - }]; -} - -static void RCTAddChildren(NSNumber *containerTag, - NSArray *reactTags, - NSDictionary> *registry) -{ - id container = registry[containerTag]; - NSInteger index = [container reactSubviews].count; - for (NSNumber *reactTag in reactTags) { - id view = registry[reactTag]; - if (view) { - [container insertReactSubview:view atIndex:index++]; - } - } -} - RCT_EXPORT_METHOD(manageChildren:(nonnull NSNumber *)containerReactTag moveFromIndices:(NSNumberArray *)moveFromIndices moveToIndices:(NSNumberArray *)moveToIndices @@ -781,57 +754,39 @@ RCT_EXPORT_METHOD(manageChildren:(nonnull NSNumber *)containerReactTag removeAtIndices:(NSArray *)removeAtIndices registry:(NSMutableDictionary> *)registry { - RCTAssert(moveFromIndices.count == moveToIndices.count, - @"moveFromIndices had size %tu, moveToIndices had size %tu", - moveFromIndices.count, moveToIndices.count); - - RCTAssert(addChildReactTags.count == addAtIndices.count, - @"addChildReactTags had size %tu, addAtIndices had size %tu", - addChildReactTags.count, addAtIndices.count); - id container = registry[containerReactTag]; - NSArray> *views = [container reactSubviews]; + RCTAssert(moveFromIndices.count == moveToIndices.count, @"moveFromIndices had size %tu, moveToIndices had size %tu", moveFromIndices.count, moveToIndices.count); + RCTAssert(addChildReactTags.count == addAtIndices.count, @"there should be at least one React child to add"); - // Get indices to insert/remove - NSUInteger purgeCount = removeAtIndices.count; - NSUInteger moveCount = moveFromIndices.count; - NSUInteger insertCount = addAtIndices.count; - NSUInteger removeCount = purgeCount + moveCount; - NSMutableArray> *toRemove = removeCount ? [NSMutableArray new] : nil; - NSMutableDictionary *toInsert = insertCount ? [NSMutableDictionary new] : nil; - for (NSNumber *index in removeAtIndices) { - id view = views[index.integerValue]; - [toRemove addObject:view]; - RCTTraverseViewNodes(registry[view.reactTag], ^(id subview) { - RCTAssert(![subview isReactRootView], @"Root views should not be unregistered"); - if ([subview conformsToProtocol:@protocol(RCTInvalidating)]) { - [(id)subview invalidate]; - } - [registry removeObjectForKey:subview.reactTag]; - [_bridgeTransactionListeners removeObject:subview]; - }); + // Removes (both permanent and temporary moves) are using "before" indices + NSArray> *permanentlyRemovedChildren = + [self _childrenToRemoveFromContainer:container atIndices:removeAtIndices]; + NSArray> *temporarilyRemovedChildren = + [self _childrenToRemoveFromContainer:container atIndices:moveFromIndices]; + [self _removeChildren:permanentlyRemovedChildren fromContainer:container]; + [self _removeChildren:temporarilyRemovedChildren fromContainer:container]; + + [self _purgeChildren:permanentlyRemovedChildren fromRegistry:registry]; + + // TODO (#5906496): optimize all these loops - constantly calling array.count is not efficient + + // Figure out what to insert - merge temporary inserts and adds + NSMutableDictionary *destinationsToChildrenToAdd = [NSMutableDictionary dictionary]; + for (NSInteger index = 0, length = temporarilyRemovedChildren.count; index < length; index++) { + destinationsToChildrenToAdd[moveToIndices[index]] = temporarilyRemovedChildren[index]; } - NSInteger i = 0; - for (NSNumber *index in moveFromIndices) { - id view = views[index.integerValue]; - [toRemove addObject:view]; - toInsert[moveToIndices[i]] = view; - i++; - } - i = 0; - for (NSNumber *reactTag in addChildReactTags) { - toInsert[addAtIndices[i]] = registry[reactTag]; - i++; + for (NSInteger index = 0, length = addAtIndices.count; index < length; index++) { + id view = registry[addChildReactTags[index]]; + if (view) { + destinationsToChildrenToAdd[addAtIndices[index]] = view; + } } - // Remove old views - for (id view in toRemove) { - [container removeReactSubview:view]; - } - - // Insert new views in ascending order - for (NSNumber *index in [toInsert.allKeys sortedArrayUsingSelector:@selector(compare:)]) { - [container insertReactSubview:toInsert[index] atIndex:index.integerValue]; + NSArray *sortedIndices = + [destinationsToChildrenToAdd.allKeys sortedArrayUsingSelector:@selector(compare:)]; + for (NSNumber *reactIndex in sortedIndices) { + [container insertReactSubview:destinationsToChildrenToAdd[reactIndex] + atIndex:reactIndex.integerValue]; } }