Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce ASIntegerMap, improve our changeset handling #trivial #405

Merged
merged 3 commits into from
Jul 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions AsyncDisplayKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@
CC0F886D1E4286FA00576FED /* ReferenceImages_iOS_10 in Resources */ = {isa = PBXBuildFile; fileRef = CC0F886A1E4286FA00576FED /* ReferenceImages_iOS_10 */; };
CC11F97A1DB181180024D77B /* ASNetworkImageNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.m */; };
CC2F65EE1E5FFB1600DA57C9 /* ASMutableElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CC2F65EC1E5FFB1600DA57C9 /* ASMutableElementMap.h */; };
CC2F65EF1E5FFB1600DA57C9 /* ASMutableElementMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.mm */; };
CC2F65EF1E5FFB1600DA57C9 /* ASMutableElementMap.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.m */; };
CC3B20841C3F76D600798563 /* ASPendingStateController.h in Headers */ = {isa = PBXBuildFile; fileRef = CC3B20811C3F76D600798563 /* ASPendingStateController.h */; settings = {ATTRIBUTES = (Private, ); }; };
CC3B20861C3F76D600798563 /* ASPendingStateController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B20821C3F76D600798563 /* ASPendingStateController.mm */; };
CC3B208A1C3F7A5400798563 /* ASWeakSet.h in Headers */ = {isa = PBXBuildFile; fileRef = CC3B20871C3F7A5400798563 /* ASWeakSet.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand All @@ -343,6 +343,8 @@
CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.m in Sources */ = {isa = PBXBuildFile; fileRef = CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */; };
CC55A7111E52A0F200594372 /* ASResponderChainEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */; };
CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */; };
CC56013B1F06E9A700DC4FBE /* ASIntegerMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CC5601391F06E9A700DC4FBE /* ASIntegerMap.h */; };
CC56013C1F06E9A700DC4FBE /* ASIntegerMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC56013A1F06E9A700DC4FBE /* ASIntegerMap.mm */; };
CC57EAF71E3939350034C595 /* ASCollectionView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = CC2E317F1DAC353700EEE891 /* ASCollectionView+Undeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; };
CC57EAF81E3939450034C595 /* ASTableView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; };
CC583AD61EF9BDBE00134156 /* ASTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = CC583AC21EF9BAB400134156 /* ASTestCase.m */; };
Expand Down Expand Up @@ -399,6 +401,7 @@
CCCCCCE71EC3F0FC0087FE10 /* NSAttributedString+ASText.h in Headers */ = {isa = PBXBuildFile; fileRef = CCCCCCE51EC3F0FC0087FE10 /* NSAttributedString+ASText.h */; };
CCCCCCE81EC3F0FC0087FE10 /* NSAttributedString+ASText.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCCCCE61EC3F0FC0087FE10 /* NSAttributedString+ASText.m */; };
CCDD148B1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m */; };
CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.m */; };
CCF18FF41D2575E300DF5895 /* NSIndexSet+ASHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */; };
Expand Down Expand Up @@ -788,7 +791,7 @@
CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASNetworkImageNodeTests.m; sourceTree = "<group>"; };
CC2E317F1DAC353700EEE891 /* ASCollectionView+Undeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionView+Undeprecated.h"; sourceTree = "<group>"; };
CC2F65EC1E5FFB1600DA57C9 /* ASMutableElementMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMutableElementMap.h; sourceTree = "<group>"; };
CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMutableElementMap.mm; sourceTree = "<group>"; };
CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASMutableElementMap.m; sourceTree = "<group>"; };
CC3B20811C3F76D600798563 /* ASPendingStateController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPendingStateController.h; sourceTree = "<group>"; };
CC3B20821C3F76D600798563 /* ASPendingStateController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPendingStateController.mm; sourceTree = "<group>"; };
CC3B20871C3F7A5400798563 /* ASWeakSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakSet.h; sourceTree = "<group>"; };
Expand All @@ -807,6 +810,8 @@
CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIResponder+AsyncDisplayKit.m"; sourceTree = "<group>"; };
CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASResponderChainEnumerator.h; sourceTree = "<group>"; };
CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASResponderChainEnumerator.m; sourceTree = "<group>"; };
CC5601391F06E9A700DC4FBE /* ASIntegerMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIntegerMap.h; sourceTree = "<group>"; };
CC56013A1F06E9A700DC4FBE /* ASIntegerMap.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASIntegerMap.mm; sourceTree = "<group>"; };
CC57EAF91E394EA40034C595 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CC583AC01EF9BAB400134156 /* ASDisplayNode+OCMock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "ASDisplayNode+OCMock.m"; sourceTree = "<group>"; };
CC583AC11EF9BAB400134156 /* ASTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASTestCase.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -873,6 +878,7 @@
CCE04B201E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "IGListAdapter+AsyncDisplayKit.h"; sourceTree = "<group>"; };
CCE04B211E313EB9006AEBBB /* IGListAdapter+AsyncDisplayKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "IGListAdapter+AsyncDisplayKit.m"; sourceTree = "<group>"; };
CCE04B2B1E314A32006AEBBB /* ASSupplementaryNodeSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSupplementaryNodeSource.h; sourceTree = "<group>"; };
CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIntegerMapTests.m; sourceTree = "<group>"; };
D3779BCFF841AD3EB56537ED /* Pods-AsyncDisplayKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.release.xcconfig"; sourceTree = "<group>"; };
D785F6601A74327E00291744 /* ASScrollNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASScrollNode.h; sourceTree = "<group>"; };
D785F6611A74327E00291744 /* ASScrollNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASScrollNode.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1132,6 +1138,7 @@
CC034A0F1E60C9BF00626263 /* ASRectTableTests.m */,
CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.m */,
CC051F1E1D7A286A006434CB /* ASCALayerTests.m */,
CCE4F9B21F0D60AC00062E4E /* ASIntegerMapTests.m */,
CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.m */,
CC8B05D41D73836400F54286 /* ASPerformanceTestContext.h */,
CC8B05D51D73836400F54286 /* ASPerformanceTestContext.m */,
Expand Down Expand Up @@ -1210,6 +1217,8 @@
058D09E1195D050800B7D73C /* Details */ = {
isa = PBXGroup;
children = (
CC5601391F06E9A700DC4FBE /* ASIntegerMap.h */,
CC56013A1F06E9A700DC4FBE /* ASIntegerMap.mm */,
CC0F885E1E4280B800576FED /* _ASCollectionViewCell.h */,
CC0F885D1E4280B800576FED /* _ASCollectionViewCell.m */,
3917EBD21E9C2FC400D04A01 /* _ASCollectionReusableView.h */,
Expand Down Expand Up @@ -1318,7 +1327,7 @@
CCA282B21E9EA7310037E8B7 /* ASTipsController.h */,
CCA282B31E9EA7310037E8B7 /* ASTipsController.m */,
CC2F65EC1E5FFB1600DA57C9 /* ASMutableElementMap.h */,
CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.mm */,
CC2F65ED1E5FFB1600DA57C9 /* ASMutableElementMap.m */,
E5ABAC791E8564EE007AC15C /* ASRectTable.h */,
E5ABAC7A1E8564EE007AC15C /* ASRectTable.m */,
CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */,
Expand Down Expand Up @@ -1713,6 +1722,7 @@
509E68631B3AEDB4009B9150 /* ASCollectionViewLayoutController.h in Headers */,
B35061F71B010EFD0018CF92 /* ASCollectionViewProtocols.h in Headers */,
68FC85E31CE29B7E00EDD713 /* ASTabBarController.h in Headers */,
CC56013B1F06E9A700DC4FBE /* ASIntegerMap.h in Headers */,
B35061FA1B010EFD0018CF92 /* ASControlNode+Subclasses.h in Headers */,
E54E81FC1EB357BD00FFE8E1 /* ASPageTable.h in Headers */,
B35061F81B010EFD0018CF92 /* ASControlNode.h in Headers */,
Expand Down Expand Up @@ -2089,6 +2099,7 @@
69FEE53D1D95A9AF0086F066 /* ASLayoutElementStyleTests.m in Sources */,
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */,
CC54A81E1D7008B300296A24 /* ASDispatchTests.m in Sources */,
CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.m in Sources */,
058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.m in Sources */,
83A7D95E1D446A6E00BF333E /* ASWeakMapTests.m in Sources */,
056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.m in Sources */,
Expand Down Expand Up @@ -2210,7 +2221,7 @@
B350621E1B010EFD0018CF92 /* ASHighlightOverlayLayer.mm in Sources */,
9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.m in Sources */,
CC0F885F1E4280B800576FED /* _ASCollectionViewCell.m in Sources */,
CC2F65EF1E5FFB1600DA57C9 /* ASMutableElementMap.mm in Sources */,
CC2F65EF1E5FFB1600DA57C9 /* ASMutableElementMap.m in Sources */,
B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.m in Sources */,
E58E9E4A1E941DA5004CFC59 /* ASCollectionLayout.mm in Sources */,
6947B0C01E36B4E30007C478 /* ASStackUnpositionedLayout.mm in Sources */,
Expand Down Expand Up @@ -2279,6 +2290,7 @@
254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */,
CCCCCCE21EC3EF060087FE10 /* ASTextUtilities.m in Sources */,
CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.m in Sources */,
CC56013C1F06E9A700DC4FBE /* ASIntegerMap.mm in Sources */,
697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */,
B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
CCA282CD1E9EB73E0037E8B7 /* ASTipNode.m in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion Source/Details/ASDataController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ - (void)_updateElementsInMap:(ASMutableElementMap *)map
}

// Migrate old supplementary nodes to their new index paths.
[map migrateSupplementaryElementsWithChangeSet:changeSet];
[map migrateSupplementaryElementsWithSectionMapping:changeSet.sectionMapping];

for (_ASHierarchyItemChange *change in [changeSet itemChangesOfType:_ASHierarchyChangeTypeDelete]) {
[map removeItemsAtIndexPaths:change.indexPaths];
Expand Down
70 changes: 70 additions & 0 deletions Source/Details/ASIntegerMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// ASIntegerMap.h
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASBaseDefines.h>

NS_ASSUME_NONNULL_BEGIN

/**
* An objective-C wrapper for unordered_map.
*/
AS_SUBCLASSING_RESTRICTED
@interface ASIntegerMap : NSObject <NSCopying>

/**
* Creates a map based on the specified update to an array.
*
* If oldCount is 0, returns the empty map.
* If deleted and inserted are empty, returns the identity map.
*/
+ (ASIntegerMap *)mapForUpdateWithOldCount:(NSInteger)oldCount
deleted:(nullable NSIndexSet *)deleted
inserted:(nullable NSIndexSet *)inserted;

/**
* A singleton that maps each integer to itself. Its inverse is itself.
*
* Note: You cannot mutate this.
*/
@property (class, atomic, readonly) ASIntegerMap *identityMap;

/**
* A singleton that returns NSNotFound for all keys. Its inverse is itself.
*
* Note: You cannot mutate this.
*/
@property (class, atomic, readonly) ASIntegerMap *emptyMap;

/**
* Retrieves the integer for a given key, or NSNotFound if the key is not found.
*
* @param key A key to lookup the value for.
*/
- (NSInteger)integerForKey:(NSInteger)key;

/**
* Sets the value for a given key.
*
* @param value The new value.
* @param key The key to store the value for.
*/
- (void)setInteger:(NSInteger)value forKey:(NSInteger)key;

/**
* Create and return a map with the inverse mapping.
*/
- (ASIntegerMap *)inverseMap;

@end

NS_ASSUME_NONNULL_END
188 changes: 188 additions & 0 deletions Source/Details/ASIntegerMap.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
//
// ASIntegerMap.mm
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

#import "ASIntegerMap.h"
#import <AsyncDisplayKit/ASAssert.h>
#import <unordered_map>
#import <NSIndexSet+ASHelpers.h>
#import <AsyncDisplayKit/ASObjectDescriptionHelpers.h>

/**
* This is just a friendly Objective-C interface to unordered_map<NSInteger, NSInteger>
*/
@interface ASIntegerMap () <ASDescriptionProvider>
@end

@implementation ASIntegerMap {
std::unordered_map<NSInteger, NSInteger> _map;
BOOL _isIdentity;
BOOL _isEmpty;
BOOL _immutable; // identity map and empty mape are immutable.
}

#pragma mark - Singleton

+ (ASIntegerMap *)identityMap
{
static ASIntegerMap *identityMap;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
identityMap = [[ASIntegerMap alloc] init];
identityMap->_isIdentity = YES;
identityMap->_immutable = YES;
});
return identityMap;
}

+ (ASIntegerMap *)emptyMap
{
static ASIntegerMap *emptyMap;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
emptyMap = [[ASIntegerMap alloc] init];
emptyMap->_isEmpty = YES;
emptyMap->_immutable = YES;
});
return emptyMap;
}

+ (ASIntegerMap *)mapForUpdateWithOldCount:(NSInteger)oldCount deleted:(NSIndexSet *)deletions inserted:(NSIndexSet *)insertions
{
if (oldCount == 0) {
return ASIntegerMap.emptyMap;
}

if (deletions.count == 0 && insertions.count == 0) {
return ASIntegerMap.identityMap;
}

ASIntegerMap *result = [[ASIntegerMap alloc] init];
// Start with the old indexes
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(0, oldCount)];

// Descending order, shift deleted ranges left
[deletions enumerateRangesWithOptions:NSEnumerationReverse usingBlock:^(NSRange range, BOOL * _Nonnull stop) {
[indexes shiftIndexesStartingAtIndex:NSMaxRange(range) by:-range.length];
}];

// Ascending order, shift inserted ranges right
[insertions enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
[indexes shiftIndexesStartingAtIndex:range.location by:range.length];
}];

__block NSInteger oldIndex = 0;
[indexes enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
// Note we advance oldIndex unconditionally, not newIndex
for (NSInteger newIndex = range.location; newIndex < NSMaxRange(range); oldIndex++) {
if ([deletions containsIndex:oldIndex]) {
// index was deleted, do nothing, just let oldIndex advance.
} else {
// assign the next index for this item.
result->_map[oldIndex] = newIndex++;
}
}
}];
return result;
}

- (NSInteger)integerForKey:(NSInteger)key
{
if (_isIdentity) {
return key;
} else if (_isEmpty) {
return NSNotFound;
}

auto result = _map.find(key);
return result != _map.end() ? result->second : NSNotFound;
}

- (void)setInteger:(NSInteger)value forKey:(NSInteger)key
{
if (_immutable) {
ASDisplayNodeFailAssert(@"Cannot mutate special integer map: %@", self);
return;
}

_map[key] = value;
}

- (ASIntegerMap *)inverseMap
{
if (_isIdentity || _isEmpty) {
return self;
}

auto result = [[ASIntegerMap alloc] init];
for (auto it = _map.begin(); it != _map.end(); it++) {
result->_map[it->second] = it->first;
}
return result;
}

#pragma mark - NSCopying

- (id)copyWithZone:(NSZone *)zone
{
if (_immutable) {
return self;
}

auto newMap = [[ASIntegerMap allocWithZone:zone] init];
newMap->_map = _map;
return newMap;
}

#pragma mark - Description

- (NSMutableArray<NSDictionary *> *)propertiesForDescription
{
NSMutableArray *result = [NSMutableArray array];

if (_isIdentity) {
[result addObject:@{ @"map": @"<identity>" }];
} else if (_isEmpty) {
[result addObject:@{ @"map": @"<empty>" }];
} else {
// { 1->2 3->4 5->6 }
NSMutableString *str = [NSMutableString string];
for (auto it = _map.begin(); it != _map.end(); it++) {
[str appendFormat:@" %zd->%zd", it->first, it->second];
}
// Remove leading space
if (str.length > 0) {
[str deleteCharactersInRange:NSMakeRange(0, 1)];
}
[result addObject:@{ @"map": str }];
}

return result;
}

- (NSString *)description
{
return ASObjectDescriptionMakeWithoutObject([self propertiesForDescription]);
}

- (BOOL)isEqual:(id)object
{
if ([super isEqual:object]) {
return YES;
}

if (auto otherMap = ASDynamicCast(object, ASIntegerMap)) {
return otherMap->_map == _map;
}
return NO;
}

@end
3 changes: 2 additions & 1 deletion Source/Private/ASMutableElementMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASBaseDefines.h>
#import <AsyncDisplayKit/ASElementMap.h>
#import <AsyncDisplayKit/ASIntegerMap.h>

NS_ASSUME_NONNULL_BEGIN

Expand Down Expand Up @@ -57,7 +58,7 @@ AS_SUBCLASSING_RESTRICTED
*
* This also deletes any supplementary elements in deleted sections.
*/
- (void)migrateSupplementaryElementsWithChangeSet:(_ASHierarchyChangeSet *)changeSet;
- (void)migrateSupplementaryElementsWithSectionMapping:(ASIntegerMap *)mapping;

@end

Expand Down
Loading