mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Implement ASChangeSetDataController.
This commit is contained in:
@@ -237,6 +237,14 @@
|
|||||||
9CDC18CC1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
9CDC18CC1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
9CDC18CD1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
9CDC18CD1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */; };
|
9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */; };
|
||||||
|
AC026B691BD57D6F00BBC17E /* ASChangeSetDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
AC026B6A1BD57D6F00BBC17E /* ASChangeSetDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
AC026B6B1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */; };
|
||||||
|
AC026B6C1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */; };
|
||||||
|
AC026B6F1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */; };
|
||||||
|
AC026B701BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */; };
|
||||||
|
AC026B711BD57DBF00BBC17E /* _ASHierarchyChangeSet.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */; };
|
||||||
|
AC026B721BD57DBF00BBC17E /* _ASHierarchyChangeSet.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */; };
|
||||||
AC026B581BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B571BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m */; };
|
AC026B581BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B571BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m */; };
|
||||||
AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
@@ -597,6 +605,10 @@
|
|||||||
9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackBaselinePositionedLayout.mm; sourceTree = "<group>"; };
|
9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackBaselinePositionedLayout.mm; sourceTree = "<group>"; };
|
||||||
9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutablePrivate.h; path = AsyncDisplayKit/Layout/ASLayoutablePrivate.h; sourceTree = "<group>"; };
|
9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutablePrivate.h; path = AsyncDisplayKit/Layout/ASLayoutablePrivate.h; sourceTree = "<group>"; };
|
||||||
9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewTests.m; sourceTree = "<group>"; };
|
9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewTests.m; sourceTree = "<group>"; };
|
||||||
|
AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASChangeSetDataController.h; sourceTree = "<group>"; };
|
||||||
|
AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASChangeSetDataController.m; sourceTree = "<group>"; };
|
||||||
|
AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASHierarchyChangeSet.h; sourceTree = "<group>"; };
|
||||||
|
AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _ASHierarchyChangeSet.m; sourceTree = "<group>"; };
|
||||||
AC026B571BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASStaticLayoutSpecSnapshotTests.m; sourceTree = "<group>"; };
|
AC026B571BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASStaticLayoutSpecSnapshotTests.m; sourceTree = "<group>"; };
|
||||||
AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = AsyncDisplayKit/Layout/ASStackLayoutDefines.h; sourceTree = "<group>"; };
|
AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = AsyncDisplayKit/Layout/ASStackLayoutDefines.h; sourceTree = "<group>"; };
|
||||||
AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionView.h; sourceTree = "<group>"; };
|
AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionView.h; sourceTree = "<group>"; };
|
||||||
@@ -890,6 +902,8 @@
|
|||||||
205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.mm */,
|
205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.mm */,
|
||||||
464052191A3F83C40061C0BA /* ASDataController.h */,
|
464052191A3F83C40061C0BA /* ASDataController.h */,
|
||||||
4640521A1A3F83C40061C0BA /* ASDataController.mm */,
|
4640521A1A3F83C40061C0BA /* ASDataController.mm */,
|
||||||
|
AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */,
|
||||||
|
AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */,
|
||||||
05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */,
|
05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */,
|
||||||
05A6D05919D0EB64002DD95E /* ASDealloc2MainObject.m */,
|
05A6D05919D0EB64002DD95E /* ASDealloc2MainObject.m */,
|
||||||
4640521B1A3F83C40061C0BA /* ASFlowLayoutController.h */,
|
4640521B1A3F83C40061C0BA /* ASFlowLayoutController.h */,
|
||||||
@@ -954,6 +968,8 @@
|
|||||||
058D0A01195D050800B7D73C /* Private */ = {
|
058D0A01195D050800B7D73C /* Private */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */,
|
||||||
|
AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */,
|
||||||
9C65A7291BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h */,
|
9C65A7291BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h */,
|
||||||
9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */,
|
9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */,
|
||||||
9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */,
|
9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */,
|
||||||
@@ -1075,6 +1091,7 @@
|
|||||||
isa = PBXHeadersBuildPhase;
|
isa = PBXHeadersBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
AC026B691BD57D6F00BBC17E /* ASChangeSetDataController.h in Headers */,
|
||||||
058D0A71195D05F800B7D73C /* _AS-objc-internal.h in Headers */,
|
058D0A71195D05F800B7D73C /* _AS-objc-internal.h in Headers */,
|
||||||
058D0A68195D05EC00B7D73C /* _ASAsyncTransaction.h in Headers */,
|
058D0A68195D05EC00B7D73C /* _ASAsyncTransaction.h in Headers */,
|
||||||
058D0A6A195D05EC00B7D73C /* _ASAsyncTransactionContainer+Private.h in Headers */,
|
058D0A6A195D05EC00B7D73C /* _ASAsyncTransactionContainer+Private.h in Headers */,
|
||||||
@@ -1133,6 +1150,7 @@
|
|||||||
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */,
|
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */,
|
||||||
ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */,
|
ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */,
|
||||||
ACF6ED4D1B17847A00DA7C62 /* ASLayoutSpecUtilities.h in Headers */,
|
ACF6ED4D1B17847A00DA7C62 /* ASLayoutSpecUtilities.h in Headers */,
|
||||||
|
AC026B6F1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */,
|
||||||
0516FA3D1A15563400B4EBED /* ASLog.h in Headers */,
|
0516FA3D1A15563400B4EBED /* ASLog.h in Headers */,
|
||||||
0442850D1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h in Headers */,
|
0442850D1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h in Headers */,
|
||||||
0516FA401A1563D200B4EBED /* ASMultiplexImageNode.h in Headers */,
|
0516FA401A1563D200B4EBED /* ASMultiplexImageNode.h in Headers */,
|
||||||
@@ -1182,6 +1200,7 @@
|
|||||||
isa = PBXHeadersBuildPhase;
|
isa = PBXHeadersBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
AC026B6A1BD57D6F00BBC17E /* ASChangeSetDataController.h in Headers */,
|
||||||
B35062481B010EFD0018CF92 /* _AS-objc-internal.h in Headers */,
|
B35062481B010EFD0018CF92 /* _AS-objc-internal.h in Headers */,
|
||||||
B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */,
|
B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */,
|
||||||
B350623E1B010EFD0018CF92 /* _ASAsyncTransactionContainer+Private.h in Headers */,
|
B350623E1B010EFD0018CF92 /* _ASAsyncTransactionContainer+Private.h in Headers */,
|
||||||
@@ -1202,6 +1221,7 @@
|
|||||||
B35062461B010EFD0018CF92 /* ASBasicImageDownloaderInternal.h in Headers */,
|
B35062461B010EFD0018CF92 /* ASBasicImageDownloaderInternal.h in Headers */,
|
||||||
B35062151B010EFD0018CF92 /* ASBatchContext.h in Headers */,
|
B35062151B010EFD0018CF92 /* ASBatchContext.h in Headers */,
|
||||||
044285081BAA63FE00D16268 /* ASBatchFetching.h in Headers */,
|
044285081BAA63FE00D16268 /* ASBatchFetching.h in Headers */,
|
||||||
|
AC026B701BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */,
|
||||||
B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */,
|
B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */,
|
||||||
34EFC7631B701CBF00AD841F /* ASCenterLayoutSpec.h in Headers */,
|
34EFC7631B701CBF00AD841F /* ASCenterLayoutSpec.h in Headers */,
|
||||||
18C2ED7F1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */,
|
18C2ED7F1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */,
|
||||||
@@ -1478,6 +1498,7 @@
|
|||||||
058D0A23195D050800B7D73C /* _ASAsyncTransactionContainer.m in Sources */,
|
058D0A23195D050800B7D73C /* _ASAsyncTransactionContainer.m in Sources */,
|
||||||
058D0A24195D050800B7D73C /* _ASAsyncTransactionGroup.m in Sources */,
|
058D0A24195D050800B7D73C /* _ASAsyncTransactionGroup.m in Sources */,
|
||||||
058D0A26195D050800B7D73C /* _ASCoreAnimationExtras.mm in Sources */,
|
058D0A26195D050800B7D73C /* _ASCoreAnimationExtras.mm in Sources */,
|
||||||
|
AC026B711BD57DBF00BBC17E /* _ASHierarchyChangeSet.m in Sources */,
|
||||||
058D0A18195D050800B7D73C /* _ASDisplayLayer.mm in Sources */,
|
058D0A18195D050800B7D73C /* _ASDisplayLayer.mm in Sources */,
|
||||||
058D0A19195D050800B7D73C /* _ASDisplayView.mm in Sources */,
|
058D0A19195D050800B7D73C /* _ASDisplayView.mm in Sources */,
|
||||||
9C55866A1BD549CB00B50E3A /* ASAsciiArtBoxCreator.m in Sources */,
|
9C55866A1BD549CB00B50E3A /* ASAsciiArtBoxCreator.m in Sources */,
|
||||||
@@ -1533,6 +1554,7 @@
|
|||||||
ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */,
|
ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */,
|
||||||
ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */,
|
ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */,
|
||||||
ACF6ED321B17843500DA7C62 /* ASStaticLayoutSpec.mm in Sources */,
|
ACF6ED321B17843500DA7C62 /* ASStaticLayoutSpec.mm in Sources */,
|
||||||
|
AC026B6B1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */,
|
||||||
055F1A3519ABD3E3004DAFF1 /* ASTableView.mm in Sources */,
|
055F1A3519ABD3E3004DAFF1 /* ASTableView.mm in Sources */,
|
||||||
058D0A17195D050800B7D73C /* ASTextNode.mm in Sources */,
|
058D0A17195D050800B7D73C /* ASTextNode.mm in Sources */,
|
||||||
058D0A1C195D050800B7D73C /* ASTextNodeCoreTextAdditions.m in Sources */,
|
058D0A1C195D050800B7D73C /* ASTextNodeCoreTextAdditions.m in Sources */,
|
||||||
@@ -1593,6 +1615,7 @@
|
|||||||
9B92C8851BC2EB6E00EE46B2 /* ASCollectionDataController.mm in Sources */,
|
9B92C8851BC2EB6E00EE46B2 /* ASCollectionDataController.mm in Sources */,
|
||||||
B350623D1B010EFD0018CF92 /* _ASAsyncTransaction.m in Sources */,
|
B350623D1B010EFD0018CF92 /* _ASAsyncTransaction.m in Sources */,
|
||||||
B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */,
|
B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */,
|
||||||
|
AC026B721BD57DBF00BBC17E /* _ASHierarchyChangeSet.m in Sources */,
|
||||||
B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.m in Sources */,
|
B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.m in Sources */,
|
||||||
B350624A1B010EFD0018CF92 /* _ASCoreAnimationExtras.mm in Sources */,
|
B350624A1B010EFD0018CF92 /* _ASCoreAnimationExtras.mm in Sources */,
|
||||||
2767E9421BB19BD600EA9B77 /* ASViewController.m in Sources */,
|
2767E9421BB19BD600EA9B77 /* ASViewController.m in Sources */,
|
||||||
@@ -1648,6 +1671,7 @@
|
|||||||
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
|
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
|
||||||
34EFC7761B701D2A00AD841F /* ASStackPositionedLayout.mm in Sources */,
|
34EFC7761B701D2A00AD841F /* ASStackPositionedLayout.mm in Sources */,
|
||||||
34EFC7781B701D3100AD841F /* ASStackUnpositionedLayout.mm in Sources */,
|
34EFC7781B701D3100AD841F /* ASStackUnpositionedLayout.mm in Sources */,
|
||||||
|
AC026B6C1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */,
|
||||||
34EFC7741B701D0A00AD841F /* ASStaticLayoutSpec.mm in Sources */,
|
34EFC7741B701D0A00AD841F /* ASStaticLayoutSpec.mm in Sources */,
|
||||||
B350620B1B010EFD0018CF92 /* ASTableView.mm in Sources */,
|
B350620B1B010EFD0018CF92 /* ASTableView.mm in Sources */,
|
||||||
B350620E1B010EFD0018CF92 /* ASTextNode.mm in Sources */,
|
B350620E1B010EFD0018CF92 /* ASTextNode.mm in Sources */,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#import "ASTableView.h"
|
#import "ASTableView.h"
|
||||||
|
|
||||||
#import "ASAssert.h"
|
#import "ASAssert.h"
|
||||||
#import "ASDataController.h"
|
#import "ASChangeSetDataController.h"
|
||||||
#import "ASCollectionViewLayoutController.h"
|
#import "ASCollectionViewLayoutController.h"
|
||||||
#import "ASLayoutController.h"
|
#import "ASLayoutController.h"
|
||||||
#import "ASRangeController.h"
|
#import "ASRangeController.h"
|
||||||
@@ -210,7 +210,7 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
|||||||
_rangeController.layoutController = _layoutController;
|
_rangeController.layoutController = _layoutController;
|
||||||
_rangeController.delegate = self;
|
_rangeController.delegate = self;
|
||||||
|
|
||||||
_dataController = [[ASDataController alloc] initWithAsyncDataFetching:asyncDataFetchingEnabled];
|
_dataController = [[ASChangeSetDataController alloc] initWithAsyncDataFetching:asyncDataFetchingEnabled];
|
||||||
_dataController.dataSource = self;
|
_dataController.dataSource = self;
|
||||||
_dataController.delegate = _rangeController;
|
_dataController.delegate = _rangeController;
|
||||||
|
|
||||||
|
|||||||
19
AsyncDisplayKit/Details/ASChangeSetDataController.h
Normal file
19
AsyncDisplayKit/Details/ASChangeSetDataController.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ASChangeSetDataController.h
|
||||||
|
// AsyncDisplayKit
|
||||||
|
//
|
||||||
|
// Created by Huy Nguyen on 19/10/15.
|
||||||
|
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <AsyncDisplayKit/ASDataController.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclass of ASDataController that enqueues and sorts edit commands during batch updating (using _ASHierarchyChangeSet).
|
||||||
|
*
|
||||||
|
* @see ASDataController
|
||||||
|
* @see _ASHierarchyChangeSet
|
||||||
|
*/
|
||||||
|
@interface ASChangeSetDataController : ASDataController
|
||||||
|
|
||||||
|
@end
|
||||||
179
AsyncDisplayKit/Details/ASChangeSetDataController.m
Normal file
179
AsyncDisplayKit/Details/ASChangeSetDataController.m
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
//
|
||||||
|
// ASChangeSetDataController.m
|
||||||
|
// AsyncDisplayKit
|
||||||
|
//
|
||||||
|
// Created by Huy Nguyen on 19/10/15.
|
||||||
|
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "ASChangeSetDataController.h"
|
||||||
|
#import "ASInternalHelpers.h"
|
||||||
|
#import "_ASHierarchyChangeSet.h"
|
||||||
|
#import "ASAssert.h"
|
||||||
|
|
||||||
|
@interface ASChangeSetDataController ()
|
||||||
|
|
||||||
|
@property (nonatomic, assign) NSUInteger batchUpdateCounter;
|
||||||
|
@property (nonatomic, strong) _ASHierarchyChangeSet *changeSet;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ASChangeSetDataController
|
||||||
|
|
||||||
|
- (instancetype)initWithAsyncDataFetching:(BOOL)asyncDataFetchingEnabled
|
||||||
|
{
|
||||||
|
if (!(self = [super initWithAsyncDataFetching:asyncDataFetchingEnabled])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_batchUpdateCounter = 0;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Batching (External API)
|
||||||
|
|
||||||
|
- (void)beginUpdates
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if (_batchUpdateCounter == 0) {
|
||||||
|
_changeSet = [_ASHierarchyChangeSet new];
|
||||||
|
}
|
||||||
|
_batchUpdateCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)endUpdatesAnimated:(BOOL)animated completion:(void (^)(BOOL))completion
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
_batchUpdateCounter--;
|
||||||
|
|
||||||
|
if (_batchUpdateCounter == 0) {
|
||||||
|
[_changeSet markCompleted];
|
||||||
|
|
||||||
|
[super beginUpdates];
|
||||||
|
|
||||||
|
for (_ASHierarchySectionChange *change in [_changeSet sectionChangesOfType:_ASHierarchyChangeTypeReload]) {
|
||||||
|
[super reloadSections:change.indexSet withAnimationOptions:change.animationOptions];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (_ASHierarchyItemChange *change in [_changeSet itemChangesOfType:_ASHierarchyChangeTypeReload]) {
|
||||||
|
[super reloadRowsAtIndexPaths:change.indexPaths withAnimationOptions:change.animationOptions];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (_ASHierarchyItemChange *change in [_changeSet itemChangesOfType:_ASHierarchyChangeTypeDelete]) {
|
||||||
|
[super deleteRowsAtIndexPaths:change.indexPaths withAnimationOptions:change.animationOptions];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (_ASHierarchySectionChange *change in [_changeSet sectionChangesOfType:_ASHierarchyChangeTypeDelete]) {
|
||||||
|
[super deleteSections:change.indexSet withAnimationOptions:change.animationOptions];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (_ASHierarchySectionChange *change in [_changeSet sectionChangesOfType:_ASHierarchyChangeTypeInsert]) {
|
||||||
|
[super insertSections:change.indexSet withAnimationOptions:change.animationOptions];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (_ASHierarchyItemChange *change in [_changeSet itemChangesOfType:_ASHierarchyChangeTypeInsert]) {
|
||||||
|
[super insertRowsAtIndexPaths:change.indexPaths withAnimationOptions:change.animationOptions];
|
||||||
|
}
|
||||||
|
|
||||||
|
[super endUpdatesAnimated:animated completion:completion];
|
||||||
|
|
||||||
|
_changeSet = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)batchUpdating
|
||||||
|
{
|
||||||
|
BOOL batchUpdating = (_batchUpdateCounter != 0);
|
||||||
|
// _changeSet must be available during batch update
|
||||||
|
ASDisplayNodeAssertTrue(batchUpdating == (_changeSet != nil));
|
||||||
|
return batchUpdating;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Section Editing (External API)
|
||||||
|
|
||||||
|
- (void)insertSections:(NSIndexSet *)sections withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if ([self batchUpdating]) {
|
||||||
|
[_changeSet insertSections:sections animationOptions:animationOptions];
|
||||||
|
} else {
|
||||||
|
[super insertSections:sections withAnimationOptions:animationOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)deleteSections:(NSIndexSet *)sections withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if ([self batchUpdating]) {
|
||||||
|
[_changeSet deleteSections:sections animationOptions:animationOptions];
|
||||||
|
} else {
|
||||||
|
[super deleteSections:sections withAnimationOptions:animationOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reloadSections:(NSIndexSet *)sections withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if ([self batchUpdating]) {
|
||||||
|
[_changeSet reloadSections:sections animationOptions:animationOptions];
|
||||||
|
} else {
|
||||||
|
[super reloadSections:sections withAnimationOptions:animationOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if ([self batchUpdating]) {
|
||||||
|
[_changeSet deleteSections:[NSIndexSet indexSetWithIndex:section] animationOptions:animationOptions];
|
||||||
|
[_changeSet insertSections:[NSIndexSet indexSetWithIndex:newSection] animationOptions:animationOptions];
|
||||||
|
} else {
|
||||||
|
[super moveSection:section toSection:newSection withAnimationOptions:animationOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Row Editing (External API)
|
||||||
|
|
||||||
|
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if ([self batchUpdating]) {
|
||||||
|
[_changeSet insertItems:indexPaths animationOptions:animationOptions];
|
||||||
|
} else {
|
||||||
|
[super insertRowsAtIndexPaths:indexPaths withAnimationOptions:animationOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if ([self batchUpdating]) {
|
||||||
|
[_changeSet deleteItems:indexPaths animationOptions:animationOptions];
|
||||||
|
} else {
|
||||||
|
[super deleteRowsAtIndexPaths:indexPaths withAnimationOptions:animationOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if ([self batchUpdating]) {
|
||||||
|
[_changeSet reloadItems:indexPaths animationOptions:animationOptions];
|
||||||
|
} else {
|
||||||
|
[super reloadRowsAtIndexPaths:indexPaths withAnimationOptions:animationOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
if ([self batchUpdating]) {
|
||||||
|
[_changeSet deleteItems:@[indexPath] animationOptions:animationOptions];
|
||||||
|
[_changeSet insertItems:@[newIndexPath] animationOptions:animationOptions];
|
||||||
|
} else {
|
||||||
|
[super moveRowAtIndexPath:indexPath toIndexPath:newIndexPath withAnimationOptions:animationOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
#import <AsyncDisplayKit/ASDataController.h>
|
#import <AsyncDisplayKit/ASChangeSetDataController.h>
|
||||||
#import <AsyncDisplayKit/ASDimension.h>
|
#import <AsyncDisplayKit/ASDimension.h>
|
||||||
|
|
||||||
@class ASDisplayNode;
|
@class ASDisplayNode;
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ASCollectionDataController : ASDataController
|
@interface ASCollectionDataController : ASChangeSetDataController
|
||||||
|
|
||||||
- (ASCellNode *)supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
- (ASCellNode *)supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ typedef NSUInteger ASDataControllerAnimationOptions;
|
|||||||
*
|
*
|
||||||
* All operations are asynchronous and thread safe. You can call it from background thread (it is recommendated) and the data
|
* All operations are asynchronous and thread safe. You can call it from background thread (it is recommendated) and the data
|
||||||
* will be updated asynchronously. The dataSource must be updated to reflect the changes before these methods has been called.
|
* will be updated asynchronously. The dataSource must be updated to reflect the changes before these methods has been called.
|
||||||
* For each data updatin, the corresponding methods in delegate will be called.
|
* For each data updating, the corresponding methods in delegate will be called.
|
||||||
*/
|
*/
|
||||||
@protocol ASFlowLayoutControllerDataSource;
|
@protocol ASFlowLayoutControllerDataSource;
|
||||||
@interface ASDataController : ASDealloc2MainObject <ASFlowLayoutControllerDataSource>
|
@interface ASDataController : ASDealloc2MainObject <ASFlowLayoutControllerDataSource>
|
||||||
|
|||||||
@@ -26,3 +26,7 @@ CGFloat ASCeilPixelValue(CGFloat f);
|
|||||||
CGFloat ASRoundPixelValue(CGFloat f);
|
CGFloat ASRoundPixelValue(CGFloat f);
|
||||||
|
|
||||||
ASDISPLAYNODE_EXTERN_C_END
|
ASDISPLAYNODE_EXTERN_C_END
|
||||||
|
|
||||||
|
@interface NSIndexPath (ASInverseComparison)
|
||||||
|
- (NSComparisonResult)as_inverseCompare:(NSIndexPath *)otherIndexPath;
|
||||||
|
@end
|
||||||
|
|||||||
@@ -70,3 +70,12 @@ CGFloat ASRoundPixelValue(CGFloat f)
|
|||||||
{
|
{
|
||||||
return roundf(f * ASScreenScale()) / ASScreenScale();
|
return roundf(f * ASScreenScale()) / ASScreenScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@implementation NSIndexPath (ASInverseComparison)
|
||||||
|
|
||||||
|
- (NSComparisonResult)as_inverseCompare:(NSIndexPath *)otherIndexPath
|
||||||
|
{
|
||||||
|
return [otherIndexPath compare:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|||||||
72
AsyncDisplayKit/Private/_ASHierarchyChangeSet.h
Normal file
72
AsyncDisplayKit/Private/_ASHierarchyChangeSet.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
//
|
||||||
|
// _ASHierarchyChangeSet.h
|
||||||
|
// AsyncDisplayKit
|
||||||
|
//
|
||||||
|
// Created by Adlai Holler on 9/29/15.
|
||||||
|
// Copyright © 2015 Facebook. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "ASDataController.h"
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, _ASHierarchyChangeType) {
|
||||||
|
_ASHierarchyChangeTypeReload,
|
||||||
|
_ASHierarchyChangeTypeDelete,
|
||||||
|
_ASHierarchyChangeTypeInsert
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface _ASHierarchySectionChange : NSObject
|
||||||
|
|
||||||
|
// FIXME: Generalize this to `changeMetadata` dict?
|
||||||
|
@property (nonatomic, readonly) ASDataControllerAnimationOptions animationOptions;
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) NSIndexSet *indexSet;
|
||||||
|
@property (nonatomic, readonly) _ASHierarchyChangeType changeType;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface _ASHierarchyItemChange : NSObject
|
||||||
|
@property (nonatomic, readonly) ASDataControllerAnimationOptions animationOptions;
|
||||||
|
|
||||||
|
/// Index paths are sorted descending for changeType .Delete, ascending otherwise
|
||||||
|
@property (nonatomic, strong, readonly) NSArray *indexPaths;
|
||||||
|
@property (nonatomic, readonly) _ASHierarchyChangeType changeType;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface _ASHierarchyChangeSet : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) NSIndexSet *deletedSections;
|
||||||
|
@property (nonatomic, strong, readonly) NSIndexSet *insertedSections;
|
||||||
|
@property (nonatomic, strong, readonly) NSIndexSet *reloadedSections;
|
||||||
|
@property (nonatomic, strong, readonly) NSArray *insertedItems;
|
||||||
|
@property (nonatomic, strong, readonly) NSArray *deletedItems;
|
||||||
|
@property (nonatomic, strong, readonly) NSArray *reloadedItems;
|
||||||
|
|
||||||
|
@property (nonatomic, readonly) BOOL completed;
|
||||||
|
|
||||||
|
/// Call this once the change set has been constructed to prevent future modifications to the changeset. Calling this more than once is a programmer error.
|
||||||
|
- (void)markCompleted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@abstract Return sorted changes of the given type, grouped by animation options.
|
||||||
|
|
||||||
|
Items deleted from deleted sections are not reported.
|
||||||
|
Items inserted into inserted sections are not reported.
|
||||||
|
Items reloaded in reloaded sections are not reported.
|
||||||
|
|
||||||
|
The safe order for processing change groups is:
|
||||||
|
- Reloaded sections & reloaded items
|
||||||
|
- Deleted items, descending order
|
||||||
|
- Deleted sections, descending order
|
||||||
|
- Inserted sections, ascending order
|
||||||
|
- Inserted items, ascending order
|
||||||
|
*/
|
||||||
|
- (NSArray /*<_ASHierarchySectionChange *>*/ *)sectionChangesOfType:(_ASHierarchyChangeType)changeType;
|
||||||
|
- (NSArray /*<_ASHierarchyItemChange *>*/ *)itemChangesOfType:(_ASHierarchyChangeType)changeType;
|
||||||
|
|
||||||
|
- (void)deleteSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options;
|
||||||
|
- (void)insertSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options;
|
||||||
|
- (void)reloadSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options;
|
||||||
|
- (void)insertItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options;
|
||||||
|
- (void)deleteItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options;
|
||||||
|
- (void)reloadItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options;
|
||||||
|
@end
|
||||||
336
AsyncDisplayKit/Private/_ASHierarchyChangeSet.m
Normal file
336
AsyncDisplayKit/Private/_ASHierarchyChangeSet.m
Normal file
@@ -0,0 +1,336 @@
|
|||||||
|
//
|
||||||
|
// _ASHierarchyChangeSet.m
|
||||||
|
// AsyncDisplayKit
|
||||||
|
//
|
||||||
|
// Created by Adlai Holler on 9/29/15.
|
||||||
|
// Copyright © 2015 Facebook. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "_ASHierarchyChangeSet.h"
|
||||||
|
#import "ASInternalHelpers.h"
|
||||||
|
|
||||||
|
@interface _ASHierarchySectionChange ()
|
||||||
|
- (instancetype)initWithChangeType:(_ASHierarchyChangeType)changeType indexSet:(NSIndexSet *)indexSet animationOptions:(ASDataControllerAnimationOptions)animationOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
On return `changes` is sorted according to the change type with changes coalesced by animationOptions
|
||||||
|
Assumes: `changes` is [_ASHierarchySectionChange] all with the same changeType
|
||||||
|
*/
|
||||||
|
+ (void)sortAndCoalesceChanges:(NSMutableArray *)changes;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface _ASHierarchyItemChange ()
|
||||||
|
- (instancetype)initWithChangeType:(_ASHierarchyChangeType)changeType indexPaths:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)animationOptions presorted:(BOOL)presorted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
On return `changes` is sorted according to the change type with changes coalesced by animationOptions
|
||||||
|
Assumes: `changes` is [_ASHierarchyItemChange] all with the same changeType
|
||||||
|
*/
|
||||||
|
+ (void)sortAndCoalesceChanges:(NSMutableArray *)changes ignoringChangesInSections:(NSIndexSet *)sections;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface _ASHierarchyChangeSet ()
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableArray *insertItemChanges;
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableArray *deleteItemChanges;
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableArray *reloadItemChanges;
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableArray *insertSectionChanges;
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableArray *deleteSectionChanges;
|
||||||
|
@property (nonatomic, strong, readonly) NSMutableArray *reloadSectionChanges;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation _ASHierarchyChangeSet {
|
||||||
|
NSMutableIndexSet *_deletedSections;
|
||||||
|
NSMutableIndexSet *_insertedSections;
|
||||||
|
NSMutableIndexSet *_reloadedSections;
|
||||||
|
NSMutableArray *_insertedItems;
|
||||||
|
NSMutableArray *_deletedItems;
|
||||||
|
NSMutableArray *_reloadedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_deletedSections = [NSMutableIndexSet new];
|
||||||
|
_insertedSections = [NSMutableIndexSet new];
|
||||||
|
_reloadedSections = [NSMutableIndexSet new];
|
||||||
|
|
||||||
|
_deletedItems = [NSMutableArray new];
|
||||||
|
_insertedItems = [NSMutableArray new];
|
||||||
|
_reloadedItems = [NSMutableArray new];
|
||||||
|
|
||||||
|
_insertItemChanges = [NSMutableArray new];
|
||||||
|
_deleteItemChanges = [NSMutableArray new];
|
||||||
|
_reloadItemChanges = [NSMutableArray new];
|
||||||
|
_insertSectionChanges = [NSMutableArray new];
|
||||||
|
_deleteSectionChanges = [NSMutableArray new];
|
||||||
|
_reloadSectionChanges = [NSMutableArray new];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark External API
|
||||||
|
|
||||||
|
- (void)markCompleted
|
||||||
|
{
|
||||||
|
NSAssert(!_completed, @"Attempt to mark already-completed changeset as completed.");
|
||||||
|
_completed = YES;
|
||||||
|
[self _sortAndCoalesceChangeArrays];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)sectionChangesOfType:(_ASHierarchyChangeType)changeType
|
||||||
|
{
|
||||||
|
[self _ensureCompleted];
|
||||||
|
switch (changeType) {
|
||||||
|
case _ASHierarchyChangeTypeInsert:
|
||||||
|
return _insertSectionChanges;
|
||||||
|
case _ASHierarchyChangeTypeReload:
|
||||||
|
return _reloadSectionChanges;
|
||||||
|
case _ASHierarchyChangeTypeDelete:
|
||||||
|
return _deleteSectionChanges;
|
||||||
|
default:
|
||||||
|
NSAssert(NO, @"Request for section changes with invalid type: %lu", changeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)itemChangesOfType:(_ASHierarchyChangeType)changeType
|
||||||
|
{
|
||||||
|
[self _ensureCompleted];
|
||||||
|
switch (changeType) {
|
||||||
|
case _ASHierarchyChangeTypeInsert:
|
||||||
|
return _insertItemChanges;
|
||||||
|
case _ASHierarchyChangeTypeReload:
|
||||||
|
return _reloadItemChanges;
|
||||||
|
case _ASHierarchyChangeTypeDelete:
|
||||||
|
return _deleteItemChanges;
|
||||||
|
default:
|
||||||
|
NSAssert(NO, @"Request for item changes with invalid type: %lu", changeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)deleteItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options
|
||||||
|
{
|
||||||
|
[self _ensureNotCompleted];
|
||||||
|
_ASHierarchyItemChange *change = [[_ASHierarchyItemChange alloc] initWithChangeType:_ASHierarchyChangeTypeDelete indexPaths:indexPaths animationOptions:options presorted:NO];
|
||||||
|
[_deleteItemChanges addObject:change];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)deleteSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options
|
||||||
|
{
|
||||||
|
[self _ensureNotCompleted];
|
||||||
|
_ASHierarchySectionChange *change = [[_ASHierarchySectionChange alloc] initWithChangeType:_ASHierarchyChangeTypeDelete indexSet:sections animationOptions:options];
|
||||||
|
[_deleteSectionChanges addObject:change];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)insertItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options
|
||||||
|
{
|
||||||
|
[self _ensureNotCompleted];
|
||||||
|
_ASHierarchyItemChange *change = [[_ASHierarchyItemChange alloc] initWithChangeType:_ASHierarchyChangeTypeInsert indexPaths:indexPaths animationOptions:options presorted:NO];
|
||||||
|
[_insertItemChanges addObject:change];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)insertSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options
|
||||||
|
{
|
||||||
|
[self _ensureNotCompleted];
|
||||||
|
_ASHierarchySectionChange *change = [[_ASHierarchySectionChange alloc] initWithChangeType:_ASHierarchyChangeTypeInsert indexSet:sections animationOptions:options];
|
||||||
|
[_insertSectionChanges addObject:change];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reloadItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options
|
||||||
|
{
|
||||||
|
[self _ensureNotCompleted];
|
||||||
|
_ASHierarchyItemChange *change = [[_ASHierarchyItemChange alloc] initWithChangeType:_ASHierarchyChangeTypeReload indexPaths:indexPaths animationOptions:options presorted:NO];
|
||||||
|
[_reloadItemChanges addObject:change];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reloadSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options
|
||||||
|
{
|
||||||
|
[self _ensureNotCompleted];
|
||||||
|
_ASHierarchySectionChange *change = [[_ASHierarchySectionChange alloc] initWithChangeType:_ASHierarchyChangeTypeReload indexSet:sections animationOptions:options];
|
||||||
|
[_reloadSectionChanges addObject:change];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Private
|
||||||
|
|
||||||
|
- (BOOL)_ensureNotCompleted
|
||||||
|
{
|
||||||
|
NSAssert(!_completed, @"Attempt to modify completed changeset %@", self);
|
||||||
|
return !_completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)_ensureCompleted
|
||||||
|
{
|
||||||
|
NSAssert(_completed, @"Attempt to process incomplete changeset %@", self);
|
||||||
|
return _completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_sortAndCoalesceChangeArrays
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
[_ASHierarchySectionChange sortAndCoalesceChanges:_deleteSectionChanges];
|
||||||
|
[_ASHierarchySectionChange sortAndCoalesceChanges:_insertSectionChanges];
|
||||||
|
[_ASHierarchySectionChange sortAndCoalesceChanges:_reloadSectionChanges];
|
||||||
|
[_ASHierarchyItemChange sortAndCoalesceChanges:_deleteItemChanges ignoringChangesInSections:_deletedSections];
|
||||||
|
[_ASHierarchyItemChange sortAndCoalesceChanges:_reloadItemChanges ignoringChangesInSections:_reloadedSections];
|
||||||
|
[_ASHierarchyItemChange sortAndCoalesceChanges:_insertItemChanges ignoringChangesInSections:_insertedSections];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation _ASHierarchySectionChange
|
||||||
|
|
||||||
|
- (instancetype)initWithChangeType:(_ASHierarchyChangeType)changeType indexSet:(NSIndexSet *)indexSet animationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_changeType = changeType;
|
||||||
|
_indexSet = indexSet;
|
||||||
|
_animationOptions = animationOptions;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)sortAndCoalesceChanges:(NSMutableArray *)changes
|
||||||
|
{
|
||||||
|
if (changes.count < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ASHierarchyChangeType type = [changes.firstObject changeType];
|
||||||
|
|
||||||
|
// Lookup table [Int: AnimationOptions]
|
||||||
|
NSMutableDictionary *animationOptions = [NSMutableDictionary new];
|
||||||
|
|
||||||
|
// All changed indexes, sorted
|
||||||
|
NSMutableIndexSet *allIndexes = [NSMutableIndexSet new];
|
||||||
|
|
||||||
|
for (_ASHierarchySectionChange *change in changes) {
|
||||||
|
[change.indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, __unused BOOL *stop) {
|
||||||
|
animationOptions[@(idx)] = @(change.animationOptions);
|
||||||
|
}];
|
||||||
|
[allIndexes addIndexes:change.indexSet];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new changes by grouping sorted changes by animation option
|
||||||
|
NSMutableArray *result = [NSMutableArray new];
|
||||||
|
|
||||||
|
__block ASDataControllerAnimationOptions currentOptions = 0;
|
||||||
|
__block NSMutableIndexSet *currentIndexes = nil;
|
||||||
|
|
||||||
|
NSEnumerationOptions options = type == _ASHierarchyChangeTypeDelete ? NSEnumerationReverse : kNilOptions;
|
||||||
|
[allIndexes enumerateIndexesWithOptions:options usingBlock:^(NSUInteger idx, __unused BOOL * stop) {
|
||||||
|
|
||||||
|
ASDataControllerAnimationOptions options = [animationOptions[@(idx)] integerValue];
|
||||||
|
if (currentIndexes == nil) {
|
||||||
|
// Starting a new group
|
||||||
|
currentIndexes = [NSMutableIndexSet indexSetWithIndex:idx];
|
||||||
|
currentOptions = options;
|
||||||
|
} else if (options == currentOptions) {
|
||||||
|
// Continuing the current group
|
||||||
|
[currentIndexes addIndex:idx];
|
||||||
|
} else {
|
||||||
|
// Ending the current group
|
||||||
|
_ASHierarchySectionChange *change = [[_ASHierarchySectionChange alloc] initWithChangeType:type indexSet:currentIndexes animationOptions:currentOptions];
|
||||||
|
[result addObject:change];
|
||||||
|
currentOptions = 0;
|
||||||
|
currentIndexes = nil;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
if (currentIndexes != nil) {
|
||||||
|
// Ending the last group
|
||||||
|
_ASHierarchySectionChange *change = [[_ASHierarchySectionChange alloc] initWithChangeType:type indexSet:currentIndexes animationOptions:currentOptions];
|
||||||
|
[result addObject:change];
|
||||||
|
currentOptions = 0;
|
||||||
|
currentIndexes = nil;
|
||||||
|
}
|
||||||
|
[changes setArray:result];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation _ASHierarchyItemChange
|
||||||
|
|
||||||
|
- (instancetype)initWithChangeType:(_ASHierarchyChangeType)changeType indexPaths:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)animationOptions presorted:(BOOL)presorted
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_changeType = changeType;
|
||||||
|
if (presorted) {
|
||||||
|
_indexPaths = indexPaths;
|
||||||
|
} else {
|
||||||
|
SEL sorting = changeType == _ASHierarchyChangeTypeDelete ? @selector(as_inverseCompare:) : @selector(compare:);
|
||||||
|
_indexPaths = [indexPaths sortedArrayUsingSelector:sorting];
|
||||||
|
}
|
||||||
|
_animationOptions = animationOptions;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)sortAndCoalesceChanges:(NSMutableArray *)changes ignoringChangesInSections:(NSIndexSet *)sections
|
||||||
|
{
|
||||||
|
if (changes.count < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ASHierarchyChangeType type = [changes.firstObject changeType];
|
||||||
|
|
||||||
|
// Lookup table [NSIndexPath: AnimationOptions]
|
||||||
|
NSMutableDictionary *animationOptions = [NSMutableDictionary new];
|
||||||
|
|
||||||
|
// All changed index paths, sorted
|
||||||
|
NSMutableArray *allIndexPaths = [NSMutableArray new];
|
||||||
|
|
||||||
|
NSPredicate *indexPathInValidSection = [NSPredicate predicateWithBlock:^BOOL(NSIndexPath *indexPath, __unused NSDictionary *_) {
|
||||||
|
return ![sections containsIndex:indexPath.section];
|
||||||
|
}];
|
||||||
|
for (_ASHierarchyItemChange *change in changes) {
|
||||||
|
for (NSIndexPath *indexPath in change.indexPaths) {
|
||||||
|
if ([indexPathInValidSection evaluateWithObject:indexPath]) {
|
||||||
|
animationOptions[indexPath] = @(change.animationOptions);
|
||||||
|
[allIndexPaths addObject:indexPath];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SEL sorting = type == _ASHierarchyChangeTypeDelete ? @selector(as_inverseCompare:) : @selector(compare:);
|
||||||
|
[allIndexPaths sortUsingSelector:sorting];
|
||||||
|
|
||||||
|
// Create new changes by grouping sorted changes by animation option
|
||||||
|
NSMutableArray *result = [NSMutableArray new];
|
||||||
|
|
||||||
|
ASDataControllerAnimationOptions currentOptions = 0;
|
||||||
|
NSMutableArray *currentIndexPaths = nil;
|
||||||
|
|
||||||
|
for (NSIndexPath *indexPath in allIndexPaths) {
|
||||||
|
ASDataControllerAnimationOptions options = [animationOptions[indexPath] integerValue];
|
||||||
|
if (currentIndexPaths == nil) {
|
||||||
|
// Starting a new group
|
||||||
|
currentIndexPaths = [NSMutableArray arrayWithObject:indexPath];
|
||||||
|
currentOptions = options;
|
||||||
|
} else if (options == currentOptions) {
|
||||||
|
// Continuing the current group
|
||||||
|
[currentIndexPaths addObject:indexPath];
|
||||||
|
} else {
|
||||||
|
// Ending the current group
|
||||||
|
_ASHierarchyItemChange *change = [[_ASHierarchyItemChange alloc] initWithChangeType:type indexPaths:currentIndexPaths animationOptions:currentOptions presorted:YES];
|
||||||
|
[result addObject:change];
|
||||||
|
currentOptions = 0;
|
||||||
|
currentIndexPaths = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentIndexPaths != nil) {
|
||||||
|
// Ending the last group
|
||||||
|
_ASHierarchyItemChange *change = [[_ASHierarchyItemChange alloc] initWithChangeType:type indexPaths:currentIndexPaths animationOptions:currentOptions presorted:YES];
|
||||||
|
[result addObject:change];
|
||||||
|
currentOptions = 0;
|
||||||
|
currentIndexPaths = nil;
|
||||||
|
}
|
||||||
|
[changes setArray:result];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
Reference in New Issue
Block a user