mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-06 21:22:44 +00:00
Create a centralized configuration API (#747)
* Update the dangerfile * Make a trivial change to test new dangerfile * Try out the new value with another trivial change * Add a configuration API to make a unified place for pulling config from clients safely * Specify properties for delegate * Finish removing text experiment global enable * Generate the config file * Clean up configuration to fix tests * Work on making it serializable * Finish it up * Fix example code * Update sample project * Clean up a few things * Align with new project order * Make it faster and update license header * Add an option to specify your config at compile time * Update another license header * Add a version field, and bring interface state coalescing into configuration * Update CA queue code * Update CATransactionQueue tests * Turn transaction queue on by default (for now, see comment) * Update the tests * Update the tests AGAIN * Remove unused ordered set
This commit is contained in:
@@ -327,6 +327,8 @@
|
||||
CC0F886C1E4286FA00576FED /* ReferenceImages_64 in Resources */ = {isa = PBXBuildFile; fileRef = CC0F88691E4286FA00576FED /* ReferenceImages_64 */; };
|
||||
CC0F886D1E4286FA00576FED /* ReferenceImages_iOS_10 in Resources */ = {isa = PBXBuildFile; fileRef = CC0F886A1E4286FA00576FED /* ReferenceImages_iOS_10 */; };
|
||||
CC11F97A1DB181180024D77B /* ASNetworkImageNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.m */; };
|
||||
CC18248C200D49C800875940 /* ASTextNodeCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = CC18248B200D49C800875940 /* ASTextNodeCommon.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CC224E962066CA6D00BBA57F /* configuration.json in Resources */ = {isa = PBXBuildFile; fileRef = CC224E952066CA6D00BBA57F /* configuration.json */; };
|
||||
CC2F65EE1E5FFB1600DA57C9 /* ASMutableElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CC2F65EC1E5FFB1600DA57C9 /* ASMutableElementMap.h */; };
|
||||
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, ); }; };
|
||||
@@ -355,6 +357,8 @@
|
||||
CC58AA4B1E398E1D002C8CB4 /* ASBlockTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CC6AA2DA1E9F03B900978E87 /* ASDisplayNode+Ancestry.h in Headers */ = {isa = PBXBuildFile; fileRef = CC6AA2D81E9F03B900978E87 /* ASDisplayNode+Ancestry.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CC6AA2DB1E9F03B900978E87 /* ASDisplayNode+Ancestry.m in Sources */ = {isa = PBXBuildFile; fileRef = CC6AA2D91E9F03B900978E87 /* ASDisplayNode+Ancestry.m */; };
|
||||
CC7AF196200D9BD500A21BDE /* ASExperimentalFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7AF195200D9BD500A21BDE /* ASExperimentalFeatures.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CC7AF198200DAB2200A21BDE /* ASExperimentalFeatures.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.m */; };
|
||||
CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */; };
|
||||
CC7FD9E21BB603FF005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CC84C7F220474C5300A3851B /* ASCGImageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = CC84C7F020474C5300A3851B /* ASCGImageBuffer.h */; };
|
||||
@@ -413,6 +417,12 @@
|
||||
CCED5E3E2020D36800395C40 /* ASNetworkImageLoadInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = CCED5E3C2020D36800395C40 /* ASNetworkImageLoadInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CCED5E3F2020D36800395C40 /* ASNetworkImageLoadInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.m */; };
|
||||
CCED5E412020D49D00395C40 /* ASNetworkImageLoadInfo+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
CCEDDDCA200C2AC300FFCD0A /* ASConfigurationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = CCEDDDC8200C2AC300FFCD0A /* ASConfigurationInternal.h */; };
|
||||
CCEDDDCB200C2AC300FFCD0A /* ASConfigurationInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.m */; };
|
||||
CCEDDDCD200C2CB900FFCD0A /* ASConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = CCEDDDCC200C2CB900FFCD0A /* ASConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CCEDDDCF200C42A200FFCD0A /* ASConfigurationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = CCEDDDCE200C42A200FFCD0A /* ASConfigurationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CCEDDDD1200C488000FFCD0A /* ASConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDD0200C488000FFCD0A /* ASConfiguration.m */; };
|
||||
CCEDDDD9200C518800FFCD0A /* ASConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.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 */; };
|
||||
@@ -816,6 +826,8 @@
|
||||
CC0F88691E4286FA00576FED /* ReferenceImages_64 */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ReferenceImages_64; sourceTree = "<group>"; };
|
||||
CC0F886A1E4286FA00576FED /* ReferenceImages_iOS_10 */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ReferenceImages_iOS_10; sourceTree = "<group>"; };
|
||||
CC11F9791DB181180024D77B /* ASNetworkImageNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASNetworkImageNodeTests.m; sourceTree = "<group>"; };
|
||||
CC18248B200D49C800875940 /* ASTextNodeCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASTextNodeCommon.h; sourceTree = "<group>"; };
|
||||
CC224E952066CA6D00BBA57F /* configuration.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = configuration.json; 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.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASMutableElementMap.m; sourceTree = "<group>"; };
|
||||
@@ -851,6 +863,8 @@
|
||||
CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBlockTypes.h; sourceTree = "<group>"; };
|
||||
CC6AA2D81E9F03B900978E87 /* ASDisplayNode+Ancestry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ASDisplayNode+Ancestry.h"; path = "Base/ASDisplayNode+Ancestry.h"; sourceTree = "<group>"; };
|
||||
CC6AA2D91E9F03B900978E87 /* ASDisplayNode+Ancestry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "ASDisplayNode+Ancestry.m"; path = "Base/ASDisplayNode+Ancestry.m"; sourceTree = "<group>"; };
|
||||
CC7AF195200D9BD500A21BDE /* ASExperimentalFeatures.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASExperimentalFeatures.h; sourceTree = "<group>"; };
|
||||
CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASExperimentalFeatures.m; sourceTree = "<group>"; };
|
||||
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPhotosFrameworkImageRequest.h; sourceTree = "<group>"; };
|
||||
CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequest.m; sourceTree = "<group>"; };
|
||||
CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequestTests.m; sourceTree = "<group>"; };
|
||||
@@ -919,6 +933,12 @@
|
||||
CCED5E3C2020D36800395C40 /* ASNetworkImageLoadInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASNetworkImageLoadInfo.h; sourceTree = "<group>"; };
|
||||
CCED5E3D2020D36800395C40 /* ASNetworkImageLoadInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASNetworkImageLoadInfo.m; sourceTree = "<group>"; };
|
||||
CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ASNetworkImageLoadInfo+Private.h"; sourceTree = "<group>"; };
|
||||
CCEDDDC8200C2AC300FFCD0A /* ASConfigurationInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASConfigurationInternal.h; sourceTree = "<group>"; };
|
||||
CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASConfigurationInternal.m; sourceTree = "<group>"; };
|
||||
CCEDDDCC200C2CB900FFCD0A /* ASConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASConfiguration.h; sourceTree = "<group>"; };
|
||||
CCEDDDCE200C42A200FFCD0A /* ASConfigurationDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASConfigurationDelegate.h; sourceTree = "<group>"; };
|
||||
CCEDDDD0200C488000FFCD0A /* ASConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASConfiguration.m; sourceTree = "<group>"; };
|
||||
CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASConfigurationTests.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>"; };
|
||||
@@ -1043,6 +1063,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
058D09B1195D04C000B7D73C /* Source */,
|
||||
CC224E942066CA6D00BBA57F /* Schemas */,
|
||||
058D09C5195D04C000B7D73C /* Tests */,
|
||||
058D09AE195D04C000B7D73C /* Frameworks */,
|
||||
058D09AD195D04C000B7D73C /* Products */,
|
||||
@@ -1092,6 +1113,9 @@
|
||||
CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */,
|
||||
DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */,
|
||||
DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */,
|
||||
CCEDDDCC200C2CB900FFCD0A /* ASConfiguration.h */,
|
||||
CCEDDDD0200C488000FFCD0A /* ASConfiguration.m */,
|
||||
CCEDDDCE200C42A200FFCD0A /* ASConfigurationDelegate.h */,
|
||||
055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */,
|
||||
AC6456071B0A335000CF11B8 /* ASCellNode.mm */,
|
||||
CC84C7F020474C5300A3851B /* ASCGImageBuffer.h */,
|
||||
@@ -1123,6 +1147,8 @@
|
||||
058D09DC195D050800B7D73C /* ASDisplayNodeExtras.mm */,
|
||||
0587F9BB1A7309ED00AFF0BA /* ASEditableTextNode.h */,
|
||||
0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */,
|
||||
CC7AF195200D9BD500A21BDE /* ASExperimentalFeatures.h */,
|
||||
CC7AF197200D9E8400A21BDE /* ASExperimentalFeatures.m */,
|
||||
058D09DD195D050800B7D73C /* ASImageNode.h */,
|
||||
058D09DE195D050800B7D73C /* ASImageNode.mm */,
|
||||
68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */,
|
||||
@@ -1158,6 +1184,7 @@
|
||||
055F1A3319ABD3E3004DAFF1 /* ASTableView.mm */,
|
||||
AC7A2C161BDE11DF0093FE1A /* ASTableViewInternal.h */,
|
||||
0574D5E119C110610097DC25 /* ASTableViewProtocols.h */,
|
||||
CC18248B200D49C800875940 /* ASTextNodeCommon.h */,
|
||||
058D09DF195D050800B7D73C /* ASTextNode.h */,
|
||||
058D09E0195D050800B7D73C /* ASTextNode.mm */,
|
||||
A373200E1C571B050011FC94 /* ASTextNode+Beta.h */,
|
||||
@@ -1204,6 +1231,7 @@
|
||||
CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m */,
|
||||
2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */,
|
||||
9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.mm */,
|
||||
CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.m */,
|
||||
2911485B1A77147A005D0878 /* ASControlNodeTests.m */,
|
||||
1A6C000F1FAB4ED400D05926 /* ASCornerLayoutSpecSnapshotTests.mm */,
|
||||
ACF6ED541B178DC700DA7C62 /* ASDimensionTests.mm */,
|
||||
@@ -1386,6 +1414,8 @@
|
||||
058D0A01195D050800B7D73C /* Private */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CCEDDDC8200C2AC300FFCD0A /* ASConfigurationInternal.h */,
|
||||
CCEDDDC9200C2AC300FFCD0A /* ASConfigurationInternal.m */,
|
||||
CCE04B2A1E313EDA006AEBBB /* Collection Data Adapter */,
|
||||
E52F8AEE1EAE659600B5A912 /* Collection Layout */,
|
||||
6947B0BB1E36B4E30007C478 /* Layout */,
|
||||
@@ -1602,6 +1632,14 @@
|
||||
path = Layout;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CC224E942066CA6D00BBA57F /* Schemas */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CC224E952066CA6D00BBA57F /* configuration.json */,
|
||||
);
|
||||
path = Schemas;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CC583ABF1EF9BAB400134156 /* Common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1777,6 +1815,7 @@
|
||||
696F01EC1DD2AF450049FBD5 /* ASEventLog.h in Headers */,
|
||||
690C35641E055C7B00069B91 /* ASDimensionInternal.h in Headers */,
|
||||
3917EBD41E9C2FC400D04A01 /* _ASCollectionReusableView.h in Headers */,
|
||||
CC18248C200D49C800875940 /* ASTextNodeCommon.h in Headers */,
|
||||
698371DB1E4379CD00437585 /* ASNodeController+Beta.h in Headers */,
|
||||
6907C2581DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h in Headers */,
|
||||
69E0E8A71D356C9400627613 /* ASEqualityHelpers.h in Headers */,
|
||||
@@ -1829,6 +1868,7 @@
|
||||
CC6AA2DA1E9F03B900978E87 /* ASDisplayNode+Ancestry.h in Headers */,
|
||||
8021EC1D1D2B00B100799119 /* UIImage+ASConvenience.h in Headers */,
|
||||
B35061FD1B010EFD0018CF92 /* ASDisplayNode+Subclasses.h in Headers */,
|
||||
CCEDDDCD200C2CB900FFCD0A /* ASConfiguration.h in Headers */,
|
||||
B35061FB1B010EFD0018CF92 /* ASDisplayNode.h in Headers */,
|
||||
B35061FE1B010EFD0018CF92 /* ASDisplayNodeExtras.h in Headers */,
|
||||
CC0F88601E4280B800576FED /* _ASCollectionViewCell.h in Headers */,
|
||||
@@ -1841,6 +1881,7 @@
|
||||
B35062021B010EFD0018CF92 /* ASImageNode.h in Headers */,
|
||||
B350621F1B010EFD0018CF92 /* ASImageProtocols.h in Headers */,
|
||||
34EFC75F1B701C8600AD841F /* ASInsetLayoutSpec.h in Headers */,
|
||||
CCEDDDCA200C2AC300FFCD0A /* ASConfigurationInternal.h in Headers */,
|
||||
34EFC7671B701CD900AD841F /* ASLayout.h in Headers */,
|
||||
DBDB83951C6E879900D0098C /* ASPagerFlowLayout.h in Headers */,
|
||||
34EFC7691B701CE100AD841F /* ASLayoutElement.h in Headers */,
|
||||
@@ -1942,6 +1983,7 @@
|
||||
34EFC76E1B701CF400AD841F /* ASRatioLayoutSpec.h in Headers */,
|
||||
DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */,
|
||||
CCA282C41E9EAE630037E8B7 /* ASLayerBackingTipProvider.h in Headers */,
|
||||
CCEDDDCF200C42A200FFCD0A /* ASConfigurationDelegate.h in Headers */,
|
||||
E5C347B31ECB40AA00EC4BE4 /* ASTableNode+Beta.h in Headers */,
|
||||
6900C5F41E8072DA00BCD75C /* ASImageNode+Private.h in Headers */,
|
||||
68B0277B1C1A79D60041016B /* ASDisplayNode+Beta.h in Headers */,
|
||||
@@ -1953,6 +1995,7 @@
|
||||
CCCCCCDB1EC3EF060087FE10 /* ASTextLine.h in Headers */,
|
||||
9C70F20E1CDBE9E5007D6C76 /* NSArray+Diffing.h in Headers */,
|
||||
CCCCCCE71EC3F0FC0087FE10 /* NSAttributedString+ASText.h in Headers */,
|
||||
CC7AF196200D9BD500A21BDE /* ASExperimentalFeatures.h in Headers */,
|
||||
CCCCCCDF1EC3EF060087FE10 /* ASTextRunDelegate.h in Headers */,
|
||||
9C49C3701B853961000B0DD5 /* ASStackLayoutElement.h in Headers */,
|
||||
34EFC7701B701CFA00AD841F /* ASStackLayoutDefines.h in Headers */,
|
||||
@@ -2105,6 +2148,7 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CC224E962066CA6D00BBA57F /* configuration.json in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -2175,6 +2219,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CCEDDDD9200C518800FFCD0A /* ASConfigurationTests.m in Sources */,
|
||||
E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.m in Sources */,
|
||||
4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.m in Sources */,
|
||||
29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m in Sources */,
|
||||
@@ -2315,6 +2360,7 @@
|
||||
B35062181B010EFD0018CF92 /* ASDataController.mm in Sources */,
|
||||
CCB1F95A1EFB60A5009C7475 /* ASLog.m in Sources */,
|
||||
767E7F8E1C90191D0066C000 /* AsyncDisplayKit+Debug.m in Sources */,
|
||||
CCEDDDCB200C2AC300FFCD0A /* ASConfigurationInternal.m in Sources */,
|
||||
CCCCCCD61EC3EF060087FE10 /* ASTextDebugOption.m in Sources */,
|
||||
34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */,
|
||||
B350624E1B010EFD0018CF92 /* ASDisplayNode+AsyncDisplay.mm in Sources */,
|
||||
@@ -2353,6 +2399,7 @@
|
||||
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */,
|
||||
CCCCCCE01EC3EF060087FE10 /* ASTextRunDelegate.m in Sources */,
|
||||
CCCCCCDA1EC3EF060087FE10 /* ASTextLayout.m in Sources */,
|
||||
CCEDDDD1200C488000FFCD0A /* ASConfiguration.m in Sources */,
|
||||
254C6B841BF94F8A003EC431 /* ASTextNodeWordKerner.m in Sources */,
|
||||
E5E2D7301EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm in Sources */,
|
||||
34EFC76B1B701CEB00AD841F /* ASLayoutSpec.mm in Sources */,
|
||||
@@ -2383,6 +2430,7 @@
|
||||
E54E81FD1EB357BD00FFE8E1 /* ASPageTable.m in Sources */,
|
||||
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
|
||||
7AB338661C55B3420055FDE8 /* ASRelativeLayoutSpec.mm in Sources */,
|
||||
CC7AF198200DAB2200A21BDE /* ASExperimentalFeatures.m in Sources */,
|
||||
E5B2252E1F17E521001E1431 /* ASDispatch.m in Sources */,
|
||||
696F01EE1DD2AF450049FBD5 /* ASEventLog.mm in Sources */,
|
||||
9C70F2051CDA4F06007D6C76 /* ASTraitCollection.m in Sources */,
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
- [ASCollectionNode] Added support for interactive item movement. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||
- Added an experimental "no-copy" rendering API. See ASGraphicsContext.h for info. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||
- Dropped support for iOS 8. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||
- Added a configuration API – a unified place to turn on/off experimental Texture features. See `ASConfiguration.h` for info. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||
- **Breaking** Changes to ASNetworkImageNode: [Adlai Holler](https://github.com/Adlai-Holler)
|
||||
- Modified `ASImageDownloaderCompletion` to add an optional `id userInfo` field. Your custom downloader can pass `nil`.
|
||||
- Modified the last argument to `-[ASNetworkImageNodeDelegate imageNode:didLoadImage:info:]` method from a struct to an object of new class `ASNetworkImageLoadInfo` which includes other metadata about the load operation.
|
||||
|
||||
23
Schemas/configuration.json
Normal file
23
Schemas/configuration.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": "configuration.json",
|
||||
"title": "configuration",
|
||||
"description" : "Schema definition of a Texture Configuration",
|
||||
"$schema": "http://json-schema.org/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version" : {
|
||||
"type" : "number"
|
||||
},
|
||||
"experimental_features": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"exp_graphics_contexts",
|
||||
"exp_text_node",
|
||||
"exp_interface_state_coalesce"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
62
Source/ASConfiguration.h
Normal file
62
Source/ASConfiguration.h
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// ASConfiguration.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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>
|
||||
#import <AsyncDisplayKit/ASExperimentalFeatures.h>
|
||||
|
||||
@protocol ASConfigurationDelegate;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
static NSInteger const ASConfigurationSchemaCurrentVersion = 1;
|
||||
|
||||
AS_SUBCLASSING_RESTRICTED
|
||||
@interface ASConfiguration : NSObject <NSCopying>
|
||||
|
||||
/**
|
||||
* Initialize this configuration with the provided dictionary,
|
||||
* or nil to create an empty configuration.
|
||||
*
|
||||
* The schema is located in `schemas/configuration.json`.
|
||||
*/
|
||||
- (instancetype)initWithDictionary:(nullable NSDictionary *)dictionary;
|
||||
|
||||
/**
|
||||
* The delegate for configuration-related events.
|
||||
* Delegate methods are called from a serial queue.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) id<ASConfigurationDelegate> delegate;
|
||||
|
||||
/**
|
||||
* The experimental features to enable in Texture.
|
||||
* See ASExperimentalFeatures for functions to convert to/from a string array.
|
||||
*/
|
||||
@property (nonatomic) ASExperimentalFeatures experimentalFeatures;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* Implement this method in a category to make your
|
||||
* configuration available to Texture. It will be read
|
||||
* only once and copied.
|
||||
*
|
||||
* NOTE: To specify your configuration at compile-time, you can
|
||||
* define AS_FIXED_CONFIG_JSON as a C-string of JSON. This method
|
||||
* will then be implemented to parse that string and generate
|
||||
* a configuration.
|
||||
*/
|
||||
@interface ASConfiguration (UserProvided)
|
||||
+ (ASConfiguration *)textureConfiguration NS_RETURNS_RETAINED;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
67
Source/ASConfiguration.m
Normal file
67
Source/ASConfiguration.m
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// ASConfiguration.m
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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 <AsyncDisplayKit/ASConfiguration.h>
|
||||
#import <AsyncDisplayKit/ASConfigurationInternal.h>
|
||||
|
||||
/// Not too performance-sensitive here.
|
||||
|
||||
/// Get this from C++, without the extra exception handling.
|
||||
#define autotype __auto_type
|
||||
|
||||
@implementation ASConfiguration
|
||||
|
||||
- (instancetype)initWithDictionary:(NSDictionary *)dictionary
|
||||
{
|
||||
if (self = [super init]) {
|
||||
autotype featureStrings = ASDynamicCast(dictionary[@"experimental_features"], NSArray);
|
||||
autotype version = ASDynamicCast(dictionary[@"version"], NSNumber).integerValue;
|
||||
if (version != ASConfigurationSchemaCurrentVersion) {
|
||||
NSLog(@"Texture warning: configuration schema is old version (%zd vs %zd)", version, ASConfigurationSchemaCurrentVersion);
|
||||
}
|
||||
self.experimentalFeatures = ASExperimentalFeaturesFromArray(featureStrings);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
ASConfiguration *config = [[ASConfiguration alloc] initWithDictionary:nil];
|
||||
config.experimentalFeatures = self.experimentalFeatures;
|
||||
config.delegate = self.delegate;
|
||||
return config;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//#define AS_FIXED_CONFIG_JSON "{ \"version\" : 1, \"experimental_features\": [ \"exp_text_node\" ] }"
|
||||
|
||||
#ifdef AS_FIXED_CONFIG_JSON
|
||||
|
||||
@implementation ASConfiguration (UserProvided)
|
||||
|
||||
+ (ASConfiguration *)textureConfiguration NS_RETURNS_RETAINED
|
||||
{
|
||||
NSData *data = [@AS_FIXED_CONFIG_JSON dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *error;
|
||||
NSDictionary *d = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
|
||||
if (!d) {
|
||||
NSAssert(NO, @"Error parsing fixed config string '%s': %@", AS_FIXED_CONFIG_JSON, error);
|
||||
return nil;
|
||||
} else {
|
||||
return [[ASConfiguration alloc] initWithDictionary:d];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // AS_FIXED_CONFIG_JSON
|
||||
31
Source/ASConfigurationDelegate.h
Normal file
31
Source/ASConfigurationDelegate.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// ASConfigurationDelegate.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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/ASConfiguration.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Used to communicate configuration-related events to the client.
|
||||
*/
|
||||
@protocol ASConfigurationDelegate <NSObject>
|
||||
|
||||
/**
|
||||
* Texture performed its first behavior related to the feature(s).
|
||||
* This can be useful for tracking the impact of the behavior (A/B testing).
|
||||
*/
|
||||
- (void)textureDidActivateExperimentalFeatures:(ASExperimentalFeatures)features;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -2915,7 +2915,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
}
|
||||
};
|
||||
|
||||
if ([[ASCATransactionQueue sharedQueue] disabled]) {
|
||||
if (!ASCATransactionQueue.sharedQueue.enabled) {
|
||||
dispatch_async(dispatch_get_main_queue(), exitVisibleInterfaceState);
|
||||
} else {
|
||||
exitVisibleInterfaceState();
|
||||
@@ -2980,7 +2980,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
|
||||
- (void)setInterfaceState:(ASInterfaceState)newState
|
||||
{
|
||||
if ([[ASCATransactionQueue sharedQueue] disabled]) {
|
||||
if (!ASCATransactionQueue.sharedQueue.enabled) {
|
||||
[self applyPendingInterfaceState:newState];
|
||||
} else {
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
@@ -3012,7 +3012,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
// newPendingState will not be used when ASCATransactionQueue is enabled
|
||||
// and use _pendingInterfaceState instead for interfaceState update.
|
||||
if ([[ASCATransactionQueue sharedQueue] disabled]) {
|
||||
if (!ASCATransactionQueue.sharedQueue.enabled) {
|
||||
_pendingInterfaceState = newPendingState;
|
||||
}
|
||||
oldState = _interfaceState;
|
||||
|
||||
36
Source/ASExperimentalFeatures.h
Normal file
36
Source/ASExperimentalFeatures.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// ASExperimentalFeatures.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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
|
||||
ASDISPLAYNODE_EXTERN_C_BEGIN
|
||||
|
||||
/**
|
||||
* A bit mask of features.
|
||||
*/
|
||||
typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) {
|
||||
ASExperimentalGraphicsContexts = 1 << 0, // exp_graphics_contexts
|
||||
ASExperimentalTextNode = 1 << 1, // exp_text_node
|
||||
ASExperimentalInterfaceStateCoalescing = 1 << 2, // exp_interface_state_coalesce
|
||||
ASExperimentalFeatureAll = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
/// Convert flags -> name array.
|
||||
NSArray<NSString *> *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags);
|
||||
|
||||
/// Convert name array -> flags.
|
||||
ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray<NSString *> *array);
|
||||
|
||||
ASDISPLAYNODE_EXTERN_C_END
|
||||
NS_ASSUME_NONNULL_END
|
||||
45
Source/ASExperimentalFeatures.m
Normal file
45
Source/ASExperimentalFeatures.m
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// ASExperimentalFeatures.m
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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 <AsyncDisplayKit/ASExperimentalFeatures.h>
|
||||
|
||||
NSArray<NSString *> *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags)
|
||||
{
|
||||
NSArray *allNames = ASCreateOnce((@[@"exp_graphics_contexts",
|
||||
@"exp_text_node",
|
||||
@"exp_interface_state_coalesce"]));
|
||||
|
||||
if (flags == ASExperimentalFeatureAll) {
|
||||
return allNames;
|
||||
}
|
||||
|
||||
// Go through all names, testing each bit.
|
||||
NSUInteger i = 0;
|
||||
return ASArrayByFlatMapping(allNames, NSString *name, ({
|
||||
(flags & (1 << i++)) ? name : nil;
|
||||
}));
|
||||
}
|
||||
|
||||
// O(N^2) but with counts this small, it's probably faster
|
||||
// than hashing the strings.
|
||||
ASExperimentalFeatures ASExperimentalFeaturesFromArray(NSArray<NSString *> *array)
|
||||
{
|
||||
NSArray *allNames = ASExperimentalFeaturesGetNames(ASExperimentalFeatureAll);
|
||||
ASExperimentalFeatures result = 0;
|
||||
for (NSString *str in array) {
|
||||
NSUInteger i = [allNames indexOfObject:str];
|
||||
if (i != NSNotFound) {
|
||||
result |= (1 << i);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
//
|
||||
// ASNetworkImageLoadInfo.h
|
||||
// AsyncDisplayKit
|
||||
// Texture
|
||||
//
|
||||
// Created by Adlai on 1/30/18.
|
||||
// Copyright © 2018 Facebook. All rights reserved.
|
||||
// Copyright (c) 2018-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>
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
//
|
||||
// ASNetworkImageLoadInfo.m
|
||||
// AsyncDisplayKit
|
||||
// Texture
|
||||
//
|
||||
// Created by Adlai on 1/30/18.
|
||||
// Copyright © 2018 Facebook. All rights reserved.
|
||||
// Copyright (c) 2018-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 <AsyncDisplayKit/ASNetworkImageLoadInfo.h>
|
||||
|
||||
@@ -59,7 +59,9 @@ AS_SUBCLASSING_RESTRICTED
|
||||
@interface ASCATransactionQueue : ASAbstractRunLoopQueue
|
||||
|
||||
@property (atomic, readonly) BOOL isEmpty;
|
||||
@property (atomic, readonly) BOOL disabled;
|
||||
|
||||
@property (atomic, readonly, getter=isEnabled) BOOL enabled;
|
||||
|
||||
/**
|
||||
* The queue to run on main run loop before CATransaction commit.
|
||||
*
|
||||
@@ -72,11 +74,6 @@ AS_SUBCLASSING_RESTRICTED
|
||||
|
||||
- (void)enqueue:(id<ASCATransactionQueueObserving>)object;
|
||||
|
||||
/**
|
||||
* @abstract Apply a node's interfaceState immediately rather than adding to the queue.
|
||||
*/
|
||||
- (void)disable;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/ASAvailability.h>
|
||||
#import <AsyncDisplayKit/ASConfigurationInternal.h>
|
||||
#import <AsyncDisplayKit/ASLog.h>
|
||||
#import <AsyncDisplayKit/ASObjectDescriptionHelpers.h>
|
||||
#import <AsyncDisplayKit/ASRunLoopQueue.h>
|
||||
@@ -494,7 +495,6 @@ typedef enum {
|
||||
CFRunLoopObserverRef _postTransactionObserver;
|
||||
NSPointerArray *_internalQueue;
|
||||
ASDN::RecursiveMutex _internalQueueLock;
|
||||
BOOL _disableInterfaceStateCoalesce;
|
||||
BOOL _CATransactionCommitInProgress;
|
||||
|
||||
// In order to not pollute the top-level activities, each queue has 1 root activity.
|
||||
@@ -671,7 +671,7 @@ static int const kASASCATransactionQueuePostOrder = 3000000;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_disableInterfaceStateCoalesce || _CATransactionCommitInProgress) {
|
||||
if (!self.enabled || _CATransactionCommitInProgress) {
|
||||
[object prepareForCATransactionCommit];
|
||||
return;
|
||||
}
|
||||
@@ -702,14 +702,9 @@ static int const kASASCATransactionQueuePostOrder = 3000000;
|
||||
return _internalQueue.count == 0;
|
||||
}
|
||||
|
||||
- (void)disable
|
||||
- (BOOL)isEnabled
|
||||
{
|
||||
_disableInterfaceStateCoalesce = YES;
|
||||
}
|
||||
|
||||
- (BOOL)disabled
|
||||
{
|
||||
return _disableInterfaceStateCoalesce;
|
||||
return ASActivateExperimentalFeature(ASExperimentalInterfaceStateCoalescing);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,20 +21,6 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// When enabled, use ASTextNode2 for subclasses, random instances, or all instances of ASTextNode.
|
||||
// See ASAvailability.h declaration of ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE for a compile-time option.
|
||||
typedef NS_OPTIONS(NSUInteger, ASTextNodeExperimentOptions) {
|
||||
// All subclass instances use the experimental implementation.
|
||||
ASTextNodeExperimentSubclasses = 1 << 0,
|
||||
// Random instances of ASTextNode (50% chance) (not subclasses) use experimental impl.
|
||||
// Useful for profiling with apps that have no custom text node subclasses.
|
||||
ASTextNodeExperimentRandomInstances = 1 << 1,
|
||||
// All instances of ASTextNode itself use experimental implementation. Supersedes `.randomInstances`.
|
||||
ASTextNodeExperimentAllInstances = 1 << 2,
|
||||
// Add highlighting etc. for debugging.
|
||||
ASTextNodeExperimentDebugging = 1 << 3
|
||||
};
|
||||
|
||||
@interface ASTextNode ()
|
||||
|
||||
/**
|
||||
@@ -52,14 +38,6 @@ typedef NS_OPTIONS(NSUInteger, ASTextNodeExperimentOptions) {
|
||||
*/
|
||||
@property (nonatomic, assign) UIEdgeInsets textContainerInset;
|
||||
|
||||
/**
|
||||
* Opt in to an experimental implementation of text node. The implementation may improve performance and correctness,
|
||||
* but may not support all features and has not been thoroughly tested in production.
|
||||
*
|
||||
* @precondition You may not call this after allocating any text nodes. You may only call this once.
|
||||
*/
|
||||
+ (void)setExperimentOptions:(ASTextNodeExperimentOptions)options;
|
||||
|
||||
/**
|
||||
* Returns YES if this node is using the experimental implementation. NO otherwise. Will not change.
|
||||
*/
|
||||
|
||||
@@ -17,31 +17,10 @@
|
||||
|
||||
#import <AsyncDisplayKit/ASAvailability.h>
|
||||
#import <AsyncDisplayKit/ASControlNode.h>
|
||||
#if ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE
|
||||
#import <AsyncDisplayKit/ASTextNode2.h>
|
||||
#endif
|
||||
#import <AsyncDisplayKit/ASTextNodeCommon.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol ASTextNodeDelegate;
|
||||
|
||||
#if !ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE
|
||||
|
||||
/**
|
||||
* Highlight styles.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
|
||||
/**
|
||||
* Highlight style for text on a light background.
|
||||
*/
|
||||
ASTextNodeHighlightStyleLight,
|
||||
|
||||
/**
|
||||
* Highlight style for text on a dark background.
|
||||
*/
|
||||
ASTextNodeHighlightStyleDark
|
||||
};
|
||||
|
||||
/**
|
||||
@abstract Draws interactive rich text.
|
||||
@discussion Backed by TextKit.
|
||||
@@ -238,70 +217,6 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
|
||||
@interface ASTextNode : ASTextNode2
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @abstract Text node delegate.
|
||||
*/
|
||||
@protocol ASTextNodeDelegate <NSObject>
|
||||
@optional
|
||||
|
||||
/**
|
||||
@abstract Indicates to the delegate that a link was tapped within a text node.
|
||||
@param textNode The ASTextNode containing the link that was tapped.
|
||||
@param attribute The attribute that was tapped. Will not be nil.
|
||||
@param value The value of the tapped attribute.
|
||||
@param point The point within textNode, in textNode's coordinate system, that was tapped.
|
||||
@param textRange The range of highlighted text.
|
||||
*/
|
||||
- (void)textNode:(ASTextNode *)textNode tappedLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point textRange:(NSRange)textRange;
|
||||
|
||||
/**
|
||||
@abstract Indicates to the delegate that a link was tapped within a text node.
|
||||
@param textNode The ASTextNode containing the link that was tapped.
|
||||
@param attribute The attribute that was tapped. Will not be nil.
|
||||
@param value The value of the tapped attribute.
|
||||
@param point The point within textNode, in textNode's coordinate system, that was tapped.
|
||||
@param textRange The range of highlighted text.
|
||||
@discussion In addition to implementing this method, the delegate must be set on the text
|
||||
node before it is loaded (the recognizer is created in -didLoad)
|
||||
*/
|
||||
- (void)textNode:(ASTextNode *)textNode longPressedLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point textRange:(NSRange)textRange;
|
||||
|
||||
//! @abstract Called when the text node's truncation string has been tapped.
|
||||
- (void)textNodeTappedTruncationToken:(ASTextNode *)textNode;
|
||||
|
||||
/**
|
||||
@abstract Indicates to the text node if an attribute should be considered a link.
|
||||
@param textNode The text node containing the entity attribute.
|
||||
@param attribute The attribute that was tapped. Will not be nil.
|
||||
@param value The value of the tapped attribute.
|
||||
@param point The point within textNode, in textNode's coordinate system, that was touched to trigger a highlight.
|
||||
@discussion If not implemented, the default value is YES.
|
||||
@return YES if the entity attribute should be a link, NO otherwise.
|
||||
*/
|
||||
- (BOOL)textNode:(ASTextNode *)textNode shouldHighlightLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point;
|
||||
|
||||
/**
|
||||
@abstract Indicates to the text node if an attribute is a valid long-press target
|
||||
@param textNode The text node containing the entity attribute.
|
||||
@param attribute The attribute that was tapped. Will not be nil.
|
||||
@param value The value of the tapped attribute.
|
||||
@param point The point within textNode, in textNode's coordinate system, that was long-pressed.
|
||||
@discussion If not implemented, the default value is NO.
|
||||
@return YES if the entity attribute should be treated as a long-press target, NO otherwise.
|
||||
*/
|
||||
- (BOOL)textNode:(ASTextNode *)textNode shouldLongPressLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point;
|
||||
|
||||
@end
|
||||
|
||||
#if !ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE
|
||||
|
||||
@interface ASTextNode (Unavailable)
|
||||
|
||||
- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)viewBlock didLoadBlock:(nullable ASDisplayNodeDidLoadBlock)didLoadBlock __unavailable;
|
||||
@@ -334,6 +249,4 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#import <AsyncDisplayKit/ASTextNode.h>
|
||||
#import <AsyncDisplayKit/ASTextNode2.h>
|
||||
|
||||
#if !ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE
|
||||
#import <AsyncDisplayKit/ASTextNode+Beta.h>
|
||||
|
||||
#import <mutex>
|
||||
@@ -27,6 +26,7 @@
|
||||
#import <AsyncDisplayKit/_ASDisplayLayer.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
#import <AsyncDisplayKit/ASConfigurationInternal.h>
|
||||
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
||||
#import <AsyncDisplayKit/ASGraphicsContext.h>
|
||||
@@ -1309,69 +1309,35 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allocate _experimentLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136)
|
||||
static ASDN::StaticMutex& _experimentLock = *new ASDN::StaticMutex;
|
||||
static ASTextNodeExperimentOptions _experimentOptions;
|
||||
static BOOL _hasAllocatedNode;
|
||||
|
||||
+ (void)setExperimentOptions:(ASTextNodeExperimentOptions)options
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
ASDN::StaticMutexLocker lock(_experimentLock);
|
||||
|
||||
// They must call this before allocating any text nodes.
|
||||
ASDisplayNodeAssertFalse(_hasAllocatedNode);
|
||||
|
||||
_experimentOptions = options;
|
||||
|
||||
// Set superclass of all subclasses to ASTextNode2
|
||||
if (options & ASTextNodeExperimentSubclasses) {
|
||||
unsigned int classCount;
|
||||
Class originalClass = [ASTextNode class];
|
||||
Class newClass = [ASTextNode2 class];
|
||||
Class *classes = objc_copyClassList(&classCount);
|
||||
for (int i = 0; i < classCount; i++) {
|
||||
Class c = classes[i];
|
||||
if (class_getSuperclass(c) == originalClass) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
class_setSuperclass(c, newClass);
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
free(classes);
|
||||
}
|
||||
|
||||
if (options & ASTextNodeExperimentDebugging) {
|
||||
[ASTextNode2 enableDebugging];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+ (id)allocWithZone:(struct _NSZone *)zone
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
ASDN::StaticMutexLocker lock(_experimentLock);
|
||||
_hasAllocatedNode = YES;
|
||||
});
|
||||
|
||||
// All instances || (random instances && rand() != 0)
|
||||
BOOL useExperiment = (_experimentOptions & ASTextNodeExperimentAllInstances)
|
||||
|| ((_experimentOptions & ASTextNodeExperimentRandomInstances)
|
||||
&& (arc4random_uniform(2) != 0));
|
||||
|
||||
if (useExperiment) {
|
||||
return (ASTextNode *)[ASTextNode2 allocWithZone:zone];
|
||||
} else {
|
||||
// If they're not experimenting, just forward.
|
||||
if (!ASActivateExperimentalFeature(ASExperimentalTextNode)) {
|
||||
return [super allocWithZone:zone];
|
||||
}
|
||||
}
|
||||
|
||||
// We are plain ASTextNode. Just swap in an ASTextNode2 instead.
|
||||
if (self == [ASTextNode class]) {
|
||||
return (ASTextNode *)[ASTextNode2 allocWithZone:zone];
|
||||
}
|
||||
|
||||
// We are descended from ASTextNode. We need to change the superclass for the
|
||||
// ASTextNode subclass to ASTextNode2.
|
||||
// Walk up the class hierarchy until we find ASTextNode.
|
||||
Class s;
|
||||
for (Class c = self; c != [ASTextNode class]; c = s) {
|
||||
s = class_getSuperclass(c);
|
||||
if (s == [ASTextNode class]) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
// Direct descendent. Update superclass of c and end.
|
||||
class_setSuperclass(c, [ASTextNode2 class]);
|
||||
#pragma clang diagnostic pop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)usingExperiment
|
||||
{
|
||||
return NO;
|
||||
return [super allocWithZone:zone];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1399,10 +1365,3 @@ static BOOL _hasAllocatedNode;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
|
||||
@implementation ASTextNode
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,28 +11,7 @@
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/ASControlNode.h>
|
||||
|
||||
#if !ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE
|
||||
// Import this to get ASTextNodeHighlightStyle
|
||||
#import <AsyncDisplayKit/ASTextNode.h>
|
||||
#else
|
||||
@protocol ASTextNodeDelegate;
|
||||
|
||||
/**
|
||||
* Highlight styles.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
|
||||
/**
|
||||
* Highlight style for text on a light background.
|
||||
*/
|
||||
ASTextNodeHighlightStyleLight,
|
||||
|
||||
/**
|
||||
* Highlight style for text on a dark background.
|
||||
*/
|
||||
ASTextNodeHighlightStyleDark
|
||||
};
|
||||
#endif
|
||||
#import <AsyncDisplayKit/ASTextNodeCommon.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
86
Source/ASTextNodeCommon.h
Normal file
86
Source/ASTextNodeCommon.h
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// ASTextNodeCommon.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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>
|
||||
|
||||
@class ASTextNode;
|
||||
|
||||
/**
|
||||
* Highlight styles.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
|
||||
/**
|
||||
* Highlight style for text on a light background.
|
||||
*/
|
||||
ASTextNodeHighlightStyleLight,
|
||||
|
||||
/**
|
||||
* Highlight style for text on a dark background.
|
||||
*/
|
||||
ASTextNodeHighlightStyleDark
|
||||
};
|
||||
|
||||
/**
|
||||
* @abstract Text node delegate.
|
||||
*/
|
||||
@protocol ASTextNodeDelegate <NSObject>
|
||||
@optional
|
||||
|
||||
/**
|
||||
@abstract Indicates to the delegate that a link was tapped within a text node.
|
||||
@param textNode The ASTextNode containing the link that was tapped.
|
||||
@param attribute The attribute that was tapped. Will not be nil.
|
||||
@param value The value of the tapped attribute.
|
||||
@param point The point within textNode, in textNode's coordinate system, that was tapped.
|
||||
@param textRange The range of highlighted text.
|
||||
*/
|
||||
- (void)textNode:(ASTextNode *)textNode tappedLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point textRange:(NSRange)textRange;
|
||||
|
||||
/**
|
||||
@abstract Indicates to the delegate that a link was tapped within a text node.
|
||||
@param textNode The ASTextNode containing the link that was tapped.
|
||||
@param attribute The attribute that was tapped. Will not be nil.
|
||||
@param value The value of the tapped attribute.
|
||||
@param point The point within textNode, in textNode's coordinate system, that was tapped.
|
||||
@param textRange The range of highlighted text.
|
||||
@discussion In addition to implementing this method, the delegate must be set on the text
|
||||
node before it is loaded (the recognizer is created in -didLoad)
|
||||
*/
|
||||
- (void)textNode:(ASTextNode *)textNode longPressedLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point textRange:(NSRange)textRange;
|
||||
|
||||
//! @abstract Called when the text node's truncation string has been tapped.
|
||||
- (void)textNodeTappedTruncationToken:(ASTextNode *)textNode;
|
||||
|
||||
/**
|
||||
@abstract Indicates to the text node if an attribute should be considered a link.
|
||||
@param textNode The text node containing the entity attribute.
|
||||
@param attribute The attribute that was tapped. Will not be nil.
|
||||
@param value The value of the tapped attribute.
|
||||
@param point The point within textNode, in textNode's coordinate system, that was touched to trigger a highlight.
|
||||
@discussion If not implemented, the default value is YES.
|
||||
@return YES if the entity attribute should be a link, NO otherwise.
|
||||
*/
|
||||
- (BOOL)textNode:(ASTextNode *)textNode shouldHighlightLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point;
|
||||
|
||||
/**
|
||||
@abstract Indicates to the text node if an attribute is a valid long-press target
|
||||
@param textNode The text node containing the entity attribute.
|
||||
@param attribute The attribute that was tapped. Will not be nil.
|
||||
@param value The value of the tapped attribute.
|
||||
@param point The point within textNode, in textNode's coordinate system, that was long-pressed.
|
||||
@discussion If not implemented, the default value is NO.
|
||||
@return YES if the entity attribute should be treated as a long-press target, NO otherwise.
|
||||
*/
|
||||
- (BOOL)textNode:(ASTextNode *)textNode shouldLongPressLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point;
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Ancestry.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Convenience.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
||||
#import <AsyncDisplayKit/ASConfiguration.h>
|
||||
#import <AsyncDisplayKit/ASConfigurationDelegate.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASControlNode.h>
|
||||
#import <AsyncDisplayKit/ASImageNode.h>
|
||||
|
||||
@@ -56,11 +56,8 @@
|
||||
#define YOGA __has_include(YOGA_HEADER_PATH)
|
||||
#endif
|
||||
|
||||
// When enabled, use ASTextNode2 for ALL instances of ASTextNode.
|
||||
// This includes what ASButtonNode uses internally, as well as all app references to ASTextNode.
|
||||
// See ASTextNode+Beta.h declaration of ASTextNodeExperimentOptions for more details.
|
||||
#ifndef ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE
|
||||
#define ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE 0
|
||||
#ifdef ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE
|
||||
#error "ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE is unavailable. See ASConfiguration.h."
|
||||
#endif
|
||||
|
||||
#define AS_PIN_REMOTE_IMAGE __has_include(<PINRemoteImage/PINRemoteImage.h>)
|
||||
|
||||
@@ -31,6 +31,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
AS_SUBCLASSING_RESTRICTED
|
||||
@interface ASElementMap : NSObject <NSCopying, NSFastEnumeration>
|
||||
|
||||
/**
|
||||
* The total number of elements in this map.
|
||||
*/
|
||||
@property (readonly) NSUInteger count;
|
||||
|
||||
/**
|
||||
* The number of sections (of items) in this map.
|
||||
*/
|
||||
|
||||
@@ -75,6 +75,11 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSUInteger)count
|
||||
{
|
||||
return _elementToIndexPathMap.count;
|
||||
}
|
||||
|
||||
- (NSArray<NSIndexPath *> *)itemIndexPaths
|
||||
{
|
||||
return ASIndexPathsForTwoDimensionalArray(_sectionsOfItems);
|
||||
|
||||
@@ -31,15 +31,6 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
ASDISPLAYNODE_EXTERN_C_BEGIN
|
||||
|
||||
/**
|
||||
* Call this to enable the experimental no-copy rendering.
|
||||
*
|
||||
* Returns YES if it was enabled, or NO + assert if it's too late because
|
||||
* rendering has already started. In practice it's fine to call this
|
||||
* during -didFinishLaunchingWithOptions:.
|
||||
*/
|
||||
extern BOOL ASEnableNoCopyRendering(void);
|
||||
|
||||
/**
|
||||
* Creates a one-shot context.
|
||||
*
|
||||
|
||||
@@ -13,36 +13,12 @@
|
||||
#import "ASGraphicsContext.h"
|
||||
#import <AsyncDisplayKit/ASCGImageBuffer.h>
|
||||
#import <AsyncDisplayKit/ASAssert.h>
|
||||
#import <AsyncDisplayKit/ASConfigurationInternal.h>
|
||||
#import <AsyncDisplayKit/ASInternalHelpers.h>
|
||||
#import <UIKit/UIGraphics.h>
|
||||
#import <UIKit/UIImage.h>
|
||||
#import <stdatomic.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#pragma mark - Feature Gating
|
||||
|
||||
// Two flags that we atomically manipulate to control the feature.
|
||||
typedef NS_OPTIONS(uint, ASNoCopyFlags) {
|
||||
ASNoCopyEnabled = 1 << 0,
|
||||
ASNoCopyBlocked = 1 << 1
|
||||
};
|
||||
static atomic_uint __noCopyFlags;
|
||||
|
||||
// Check if it's blocked, and set the enabled flag if not.
|
||||
extern BOOL ASEnableNoCopyRendering()
|
||||
{
|
||||
ASNoCopyFlags expectedFlags = 0;
|
||||
BOOL enabled = atomic_compare_exchange_strong(&__noCopyFlags, &expectedFlags, ASNoCopyEnabled);
|
||||
ASDisplayNodeCAssert(enabled, @"Can't enable no-copy rendering after first render started.");
|
||||
return enabled;
|
||||
}
|
||||
|
||||
// Check if it's enabled and set the "blocked" flag either way.
|
||||
static BOOL ASNoCopyRenderingBlockAndCheckEnabled() {
|
||||
ASNoCopyFlags oldFlags = atomic_fetch_or(&__noCopyFlags, ASNoCopyBlocked);
|
||||
return (oldFlags & ASNoCopyEnabled) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our version of the private CGBitmapGetAlignedBytesPerRow function.
|
||||
*
|
||||
@@ -67,7 +43,7 @@ static UInt8 __contextDataAssociationKey;
|
||||
|
||||
extern void ASGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
|
||||
{
|
||||
if (!ASNoCopyRenderingBlockAndCheckEnabled()) {
|
||||
if (!ASActivateExperimentalFeature(ASExperimentalGraphicsContexts)) {
|
||||
UIGraphicsBeginImageContextWithOptions(size, opaque, scale);
|
||||
return;
|
||||
}
|
||||
@@ -132,7 +108,7 @@ extern void ASGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGF
|
||||
|
||||
extern UIImage * _Nullable ASGraphicsGetImageAndEndCurrentContext() NS_RETURNS_RETAINED
|
||||
{
|
||||
if (!ASNoCopyRenderingBlockAndCheckEnabled()) {
|
||||
if (!ASActivateExperimentalFeature(ASExperimentalGraphicsContexts)) {
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
@@ -186,7 +162,7 @@ extern UIImage * _Nullable ASGraphicsGetImageAndEndCurrentContext() NS_RETURNS_R
|
||||
|
||||
extern void ASGraphicsEndImageContext()
|
||||
{
|
||||
if (!ASNoCopyRenderingBlockAndCheckEnabled()) {
|
||||
if (!ASActivateExperimentalFeature(ASExperimentalGraphicsContexts)) {
|
||||
UIGraphicsEndImageContext();
|
||||
return;
|
||||
}
|
||||
|
||||
38
Source/Private/ASConfigurationInternal.h
Normal file
38
Source/Private/ASConfigurationInternal.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// ASConfigurationInternal.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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/ASConfiguration.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
ASDISPLAYNODE_EXTERN_C_BEGIN
|
||||
|
||||
/**
|
||||
* Quickly check if an experiment is enabled and notify the delegate
|
||||
* that it's been activated.
|
||||
*
|
||||
* The delegate will be notified asynchronously.
|
||||
*/
|
||||
BOOL ASActivateExperimentalFeature(ASExperimentalFeatures option);
|
||||
|
||||
AS_SUBCLASSING_RESTRICTED
|
||||
@interface ASConfigurationManager : NSObject
|
||||
|
||||
/**
|
||||
* No API for now.
|
||||
* Just use ASActivateExperimentalFeature to access this efficiently.
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
ASDISPLAYNODE_EXTERN_C_END
|
||||
96
Source/Private/ASConfigurationInternal.m
Normal file
96
Source/Private/ASConfigurationInternal.m
Normal file
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// ASConfigurationInternal.m
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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 "ASConfigurationInternal.h"
|
||||
#import <AsyncDisplayKit/ASConfiguration.h>
|
||||
#import <AsyncDisplayKit/ASConfigurationDelegate.h>
|
||||
#import <stdatomic.h>
|
||||
|
||||
#define ASGetSharedConfigMgr() (__bridge ASConfigurationManager *)ASConfigurationManager.sharedInstance
|
||||
|
||||
@implementation ASConfigurationManager {
|
||||
ASConfiguration *_config;
|
||||
dispatch_queue_t _delegateQueue;
|
||||
_Atomic(ASExperimentalFeatures) _activatedExperiments;
|
||||
}
|
||||
|
||||
/// Return CFTypeRef to avoid retain/release on this singleton.
|
||||
+ (CFTypeRef)sharedInstance
|
||||
{
|
||||
static CFTypeRef inst;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
inst = (__bridge_retained CFTypeRef)[[ASConfigurationManager alloc] init];
|
||||
});
|
||||
return inst;
|
||||
}
|
||||
|
||||
+ (ASConfiguration *)defaultConfiguration NS_RETURNS_RETAINED
|
||||
{
|
||||
ASConfiguration *config = [[ASConfiguration alloc] init];
|
||||
// On by default for now, pending fix for https://github.com/TextureGroup/Texture/issues/853
|
||||
config.experimentalFeatures = ASExperimentalInterfaceStateCoalescing;
|
||||
return config;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_delegateQueue = dispatch_queue_create("org.TextureGroup.Texture.ConfigNotifyQueue", DISPATCH_QUEUE_SERIAL);
|
||||
if ([ASConfiguration respondsToSelector:@selector(textureConfiguration)]) {
|
||||
_config = [[ASConfiguration textureConfiguration] copy];
|
||||
} else {
|
||||
_config = [ASConfigurationManager defaultConfiguration];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)activateExperimentalFeature:(ASExperimentalFeatures)requested
|
||||
{
|
||||
if (_config == nil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSAssert(__builtin_popcount(requested) == 1, @"Cannot activate multiple features at once with this method.");
|
||||
|
||||
// If they're disabled, ignore them.
|
||||
ASExperimentalFeatures enabled = requested & _config.experimentalFeatures;
|
||||
ASExperimentalFeatures prevTriggered = atomic_fetch_or(&_activatedExperiments, enabled);
|
||||
ASExperimentalFeatures newlyTriggered = enabled & ~prevTriggered;
|
||||
|
||||
// Notify delegate if needed.
|
||||
if (newlyTriggered != 0) {
|
||||
__unsafe_unretained id<ASConfigurationDelegate> del = _config.delegate;
|
||||
dispatch_async(_delegateQueue, ^{
|
||||
[del textureDidActivateExperimentalFeatures:newlyTriggered];
|
||||
});
|
||||
}
|
||||
|
||||
return (enabled != 0);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
+ (void)test_resetWithConfiguration:(ASConfiguration *)configuration
|
||||
{
|
||||
ASConfigurationManager *inst = ASGetSharedConfigMgr();
|
||||
inst->_config = configuration ?: [self defaultConfiguration];
|
||||
atomic_store(&inst->_activatedExperiments, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
BOOL ASActivateExperimentalFeature(ASExperimentalFeatures feature)
|
||||
{
|
||||
return [ASGetSharedConfigMgr() activateExperimentalFeature:feature];
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
//
|
||||
// ASNetworkImageLoadInfo+Private.h
|
||||
// AsyncDisplayKit
|
||||
// Texture
|
||||
//
|
||||
// Created by Adlai on 1/30/18.
|
||||
// Copyright © 2018 Facebook. All rights reserved.
|
||||
// Copyright (c) 2018-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 <AsyncDisplayKit/ASNetworkImageLoadInfo.h>
|
||||
|
||||
@@ -862,7 +862,7 @@
|
||||
[cn waitUntilAllUpdatesAreProcessed];
|
||||
[cn.view layoutIfNeeded];
|
||||
ASCellNode *node = [cn nodeForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
|
||||
ASCATransactionQueueWait();
|
||||
ASCATransactionQueueWait(nil);
|
||||
XCTAssertTrue(node.visible);
|
||||
testController.asyncDelegate->_itemCounts = {0};
|
||||
[cn deleteItemsAtIndexPaths: @[[NSIndexPath indexPathForItem:0 inSection:0]]];
|
||||
@@ -1074,7 +1074,7 @@
|
||||
for (NSInteger i = 0; i < c; i++) {
|
||||
NSIndexPath *ip = [NSIndexPath indexPathForItem:i inSection:s];
|
||||
ASCellNode *node = [cn nodeForItemAtIndexPath:ip];
|
||||
ASCATransactionQueueWait();
|
||||
ASCATransactionQueueWait(nil);
|
||||
if (node.inPreloadState) {
|
||||
CGRect frame = [cn.view layoutAttributesForItemAtIndexPath:ip].frame;
|
||||
r = CGRectUnion(r, frame);
|
||||
|
||||
77
Tests/ASConfigurationTests.m
Normal file
77
Tests/ASConfigurationTests.m
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// ASConfigurationTests.m
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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 <XCTest/XCTest.h>
|
||||
#import "ASTestCase.h"
|
||||
#import "ASConfiguration.h"
|
||||
#import "ASConfigurationDelegate.h"
|
||||
#import "ASConfigurationInternal.h"
|
||||
|
||||
@interface ASConfigurationTests : ASTestCase <ASConfigurationDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASConfigurationTests {
|
||||
void (^onActivate)(ASConfigurationTests *self, ASExperimentalFeatures feature);
|
||||
}
|
||||
|
||||
- (void)testExperimentalFeatureConfig
|
||||
{
|
||||
// Set the config
|
||||
ASConfiguration *config = [[ASConfiguration alloc] initWithDictionary:nil];
|
||||
config.experimentalFeatures = ASExperimentalGraphicsContexts;
|
||||
config.delegate = self;
|
||||
[ASConfigurationManager test_resetWithConfiguration:config];
|
||||
|
||||
// Set an expectation for a callback, and assert we only get one.
|
||||
XCTestExpectation *e = [self expectationWithDescription:@"Callback 1 done."];
|
||||
onActivate = ^(ASConfigurationTests *self, ASExperimentalFeatures feature) {
|
||||
XCTAssertEqual(feature, ASExperimentalGraphicsContexts);
|
||||
[e fulfill];
|
||||
// Next time it's a fail.
|
||||
self->onActivate = ^(ASConfigurationTests *self, ASExperimentalFeatures feature) {
|
||||
XCTFail(@"Too many callbacks.");
|
||||
};
|
||||
};
|
||||
|
||||
// Now activate the graphics experiment and expect it works.
|
||||
XCTAssertTrue(ASActivateExperimentalFeature(ASExperimentalGraphicsContexts));
|
||||
// We should get a callback here
|
||||
// Now activate text node and expect it fails.
|
||||
XCTAssertFalse(ASActivateExperimentalFeature(ASExperimentalTextNode));
|
||||
[self waitForExpectationsWithTimeout:3 handler:nil];
|
||||
}
|
||||
|
||||
- (void)textureDidActivateExperimentalFeatures:(ASExperimentalFeatures)feature
|
||||
{
|
||||
if (onActivate) {
|
||||
onActivate(self, feature);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testMappingNamesToFlags
|
||||
{
|
||||
// Throw in a bad bit.
|
||||
ASExperimentalFeatures features = ASExperimentalTextNode | ASExperimentalGraphicsContexts | (1 << 22);
|
||||
NSArray *expectedNames = @[ @"exp_graphics_contexts", @"exp_text_node" ];
|
||||
XCTAssertEqualObjects(expectedNames, ASExperimentalFeaturesGetNames(features));
|
||||
}
|
||||
|
||||
- (void)testMappingFlagsFromNames
|
||||
{
|
||||
// Throw in a bad name.
|
||||
NSArray *names = @[ @"exp_text_node", @"exp_graphics_contexts", @"__invalid_name" ];
|
||||
ASExperimentalFeatures expected = ASExperimentalGraphicsContexts | ASExperimentalTextNode;
|
||||
XCTAssertEqual(expected, ASExperimentalFeaturesFromArray(names));
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -131,7 +131,7 @@
|
||||
ASDisplayNodeSizeToFitSizeRange(node, ASSizeRangeMake(CGSizeZero, CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)));
|
||||
[node recursivelySetInterfaceState:ASInterfaceStatePreload];
|
||||
|
||||
ASCATransactionQueueWait();
|
||||
ASCATransactionQueueWait(nil);
|
||||
// No premature view allocation
|
||||
XCTAssertFalse(node.isNodeLoaded);
|
||||
// Subnodes should be inserted, laid out and entered preload state
|
||||
|
||||
@@ -131,7 +131,7 @@ for (ASDisplayNode *n in @[ nodes ]) {\
|
||||
- (void)setInterfaceState:(ASInterfaceState)state
|
||||
{
|
||||
[super setInterfaceState:state];
|
||||
ASCATransactionQueueWait();
|
||||
ASCATransactionQueueWait(nil);
|
||||
}
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AsyncDisplayKit/ASDimension.h>
|
||||
|
||||
@class ASDisplayNode;
|
||||
@class ASCATransactionQueue, ASDisplayNode;
|
||||
|
||||
typedef BOOL (^as_condition_block_t)(void);
|
||||
|
||||
@@ -28,6 +28,6 @@ BOOL ASDisplayNodeRunRunLoopUntilBlockIsTrue(as_condition_block_t block);
|
||||
|
||||
void ASDisplayNodeSizeToFitSize(ASDisplayNode *node, CGSize size);
|
||||
void ASDisplayNodeSizeToFitSizeRange(ASDisplayNode *node, ASSizeRange sizeRange);
|
||||
void ASCATransactionQueueWait(void);
|
||||
void ASCATransactionQueueWait(ASCATransactionQueue *q); // nil means shared queue
|
||||
|
||||
ASDISPLAYNODE_EXTERN_C_END
|
||||
|
||||
@@ -64,12 +64,13 @@ void ASDisplayNodeSizeToFitSizeRange(ASDisplayNode *node, ASSizeRange sizeRange)
|
||||
node.bounds = (CGRect){.origin = CGPointZero, .size = sizeThatFits};
|
||||
}
|
||||
|
||||
void ASCATransactionQueueWait(void)
|
||||
void ASCATransactionQueueWait(ASCATransactionQueue *q)
|
||||
{
|
||||
if (!q) { q = ASCATransactionQueue.sharedQueue; }
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:1];
|
||||
BOOL whileResult = YES;
|
||||
while ([date timeIntervalSinceNow] > 0 &&
|
||||
(whileResult = ![[ASCATransactionQueue sharedQueue] isEmpty])) {
|
||||
(whileResult = ![q isEmpty])) {
|
||||
[[NSRunLoop currentRunLoop] runUntilDate:
|
||||
[NSDate dateWithTimeIntervalSinceNow:0.01]];
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
// ASNetworkImageNodeTests.m
|
||||
// Texture
|
||||
//
|
||||
// Created by Adlai Holler on 10/14/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
// Copyright (c) 2018-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 <XCTest/XCTest.h>
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
// ASPerformanceTestContext.h
|
||||
// Texture
|
||||
//
|
||||
// Created by Adlai Holler on 8/28/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
// Copyright (c) 2018-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>
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "ASTestCase.h"
|
||||
|
||||
#import <AsyncDisplayKit/ASRunLoopQueue.h>
|
||||
#import "ASDisplayNodeTestsHelper.h"
|
||||
|
||||
@@ -27,7 +28,7 @@ static NSTimeInterval const kRunLoopRunTime = 0.001; // Allow the RunLoop to run
|
||||
}
|
||||
@end
|
||||
|
||||
@interface ASRunLoopQueueTests : XCTestCase
|
||||
@interface ASRunLoopQueueTests : ASTestCase
|
||||
|
||||
@end
|
||||
|
||||
@@ -171,12 +172,18 @@ static NSTimeInterval const kRunLoopRunTime = 0.001; // Allow the RunLoop to run
|
||||
|
||||
- (void)testASCATransactionQueueDisable
|
||||
{
|
||||
// Disable coalescing.
|
||||
ASConfiguration *config = [[ASConfiguration alloc] init];
|
||||
config.experimentalFeatures = kNilOptions;
|
||||
[ASConfigurationManager test_resetWithConfiguration:config];
|
||||
|
||||
ASCATransactionQueue *queue = [[ASCATransactionQueue alloc] init];
|
||||
[queue disable];
|
||||
QueueObject *object = [[QueueObject alloc] init];
|
||||
[[ASCATransactionQueue sharedQueue] enqueue:object];
|
||||
XCTAssertFalse(object.queueObjectProcessed);
|
||||
[queue enqueue:object];
|
||||
XCTAssertTrue(object.queueObjectProcessed);
|
||||
XCTAssertTrue([queue isEmpty]);
|
||||
XCTAssertTrue([queue disabled]);
|
||||
XCTAssertFalse(queue.enabled);
|
||||
}
|
||||
|
||||
- (void)testASCATransactionQueueProcess
|
||||
@@ -185,8 +192,9 @@ static NSTimeInterval const kRunLoopRunTime = 0.001; // Allow the RunLoop to run
|
||||
QueueObject *object = [[QueueObject alloc] init];
|
||||
[queue enqueue:object];
|
||||
XCTAssertFalse(object.queueObjectProcessed);
|
||||
ASCATransactionQueueWait();
|
||||
ASCATransactionQueueWait(queue);
|
||||
XCTAssertTrue(object.queueObjectProcessed);
|
||||
XCTAssertTrue(queue.enabled);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
// ASTextNodePerformanceTests.m
|
||||
// Texture
|
||||
//
|
||||
// Created by Adlai Holler on 8/28/16.
|
||||
// Copyright © 2016 Facebook. All rights reserved.
|
||||
// Copyright (c) 2018-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 <XCTest/XCTest.h>
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#import <CoreText/CoreText.h>
|
||||
|
||||
#import "ASTestCase.h"
|
||||
|
||||
#import <OCMock/OCMock.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASLayout.h>
|
||||
@@ -31,6 +33,10 @@
|
||||
@property (nonatomic, copy, readonly) NSString *tappedLinkAttribute;
|
||||
@property (nonatomic, assign, readonly) id tappedLinkValue;
|
||||
|
||||
@end
|
||||
@interface ASTextNodeSubclass : ASTextNode
|
||||
@end
|
||||
@interface ASTextNodeSecondSubclass : ASTextNodeSubclass
|
||||
@end
|
||||
|
||||
@implementation ASTextNodeTestDelegate
|
||||
@@ -235,4 +241,23 @@
|
||||
XCTAssertGreaterThan(sizeWithExclusionPaths.height, sizeWithoutExclusionPaths.height, @"Setting exclusions paths should invalidate the calculated size and return a greater size");
|
||||
}
|
||||
|
||||
- (void)testThatTheExperimentWorksCorrectly
|
||||
{
|
||||
ASConfiguration *config = [ASConfiguration new];
|
||||
config.experimentalFeatures = ASExperimentalTextNode;
|
||||
[ASConfigurationManager test_resetWithConfiguration:config];
|
||||
|
||||
ASTextNode *plainTextNode = [[ASTextNode alloc] init];
|
||||
XCTAssertEqualObjects(plainTextNode.class, [ASTextNode2 class]);
|
||||
|
||||
ASTextNodeSecondSubclass *sc2 = [[ASTextNodeSecondSubclass alloc] init];
|
||||
XCTAssertEqualObjects([ASTextNodeSubclass superclass], [ASTextNode2 class]);
|
||||
XCTAssertEqualObjects(sc2.superclass, [ASTextNodeSubclass class]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASTextNodeSubclass
|
||||
@end
|
||||
@implementation ASTextNodeSecondSubclass
|
||||
@end
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
|
||||
[_videoNode setInterfaceState:ASInterfaceStateVisible | ASInterfaceStateDisplay | ASInterfaceStatePreload];
|
||||
[_videoNode prepareToPlayAsset:assetMock withKeys:_requestedKeys];
|
||||
ASCATransactionQueueWait();
|
||||
ASCATransactionQueueWait(nil);
|
||||
[_videoNode pause];
|
||||
_videoNode.shouldBePlaying = YES;
|
||||
XCTAssertFalse(_videoNode.isPlaying);
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
// ASTestCase.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
|
||||
// grant of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present,
|
||||
// Pinterest, Inc. 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
|
||||
//
|
||||
@@ -16,6 +21,7 @@
|
||||
#import <OCMock/OCMock.h>
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
#import "OCMockObject+ASAdditions.h"
|
||||
#import "ASConfigurationInternal.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -25,4 +31,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@end
|
||||
|
||||
@interface ASConfigurationManager (Testing)
|
||||
|
||||
+ (void)test_resetWithConfiguration:(nullable ASConfiguration *)configuration;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
// ASTestCase.m
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
|
||||
// grant of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present,
|
||||
// Pinterest, Inc. 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
|
||||
//
|
||||
@@ -31,6 +36,8 @@ static __weak ASTestCase *currentTestCase;
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
[ASConfigurationManager test_resetWithConfiguration:nil];
|
||||
|
||||
// Clear out all application windows. Note: the system will retain these sometimes on its
|
||||
// own but we'll do our best.
|
||||
for (UIWindow *window in [UIApplication sharedApplication].windows) {
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
CC5532171E15CC1E0011C01F /* ASCollectionSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5532161E15CC1E0011C01F /* ASCollectionSectionController.m */; };
|
||||
CC6350BB1E1C482D002BC613 /* TailLoadingNode.m in Sources */ = {isa = PBXBuildFile; fileRef = CC6350BA1E1C482D002BC613 /* TailLoadingNode.m */; };
|
||||
CC85250F1E36B392008EABE6 /* FeedHeaderNode.m in Sources */ = {isa = PBXBuildFile; fileRef = CC85250E1E36B392008EABE6 /* FeedHeaderNode.m */; };
|
||||
CCEDDDD7200C4C0E00FFCD0A /* TextureConfigDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CCEDDDD6200C4C0E00FFCD0A /* TextureConfigDelegate.m */; };
|
||||
E5F128F01E09625400B4335F /* PhotoFeedBaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = E5F128EF1E09625400B4335F /* PhotoFeedBaseController.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -98,6 +99,7 @@
|
||||
CC6350BA1E1C482D002BC613 /* TailLoadingNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TailLoadingNode.m; sourceTree = "<group>"; };
|
||||
CC85250D1E36B392008EABE6 /* FeedHeaderNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeedHeaderNode.h; sourceTree = "<group>"; };
|
||||
CC85250E1E36B392008EABE6 /* FeedHeaderNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedHeaderNode.m; sourceTree = "<group>"; };
|
||||
CCEDDDD6200C4C0E00FFCD0A /* TextureConfigDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TextureConfigDelegate.m; sourceTree = "<group>"; };
|
||||
D09B5DF0BFB37583DE8F3142 /* Pods-Sample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.release.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.release.xcconfig"; sourceTree = "<group>"; };
|
||||
E5F128EE1E09612700B4335F /* PhotoFeedBaseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoFeedBaseController.h; sourceTree = "<group>"; };
|
||||
E5F128EF1E09625400B4335F /* PhotoFeedBaseController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhotoFeedBaseController.m; sourceTree = "<group>"; };
|
||||
@@ -141,6 +143,7 @@
|
||||
children = (
|
||||
768843511CAA37EF00D8629E /* AppDelegate.h */,
|
||||
768843681CAA37EF00D8629E /* AppDelegate.m */,
|
||||
CCEDDDD6200C4C0E00FFCD0A /* TextureConfigDelegate.m */,
|
||||
76229A761CBB79E000B62CEF /* WindowWithStatusBarUnderlay.h */,
|
||||
76229A771CBB79E000B62CEF /* WindowWithStatusBarUnderlay.m */,
|
||||
767A5F141CAA3D8A004CDA8D /* Controller */,
|
||||
@@ -427,6 +430,7 @@
|
||||
CC5532171E15CC1E0011C01F /* ASCollectionSectionController.m in Sources */,
|
||||
768843801CAA37EF00D8629E /* AppDelegate.m in Sources */,
|
||||
768843811CAA37EF00D8629E /* CommentFeedModel.m in Sources */,
|
||||
CCEDDDD7200C4C0E00FFCD0A /* TextureConfigDelegate.m in Sources */,
|
||||
7688438E1CAA37EF00D8629E /* PhotoFeedNodeController.m in Sources */,
|
||||
CC6350BB1E1C482D002BC613 /* TailLoadingNode.m in Sources */,
|
||||
CC85250F1E36B392008EABE6 /* FeedHeaderNode.m in Sources */,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
|
||||
// grant of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present,
|
||||
// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present,
|
||||
// Pinterest, Inc. 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
|
||||
@@ -40,8 +40,6 @@
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
|
||||
ASEnableNoCopyRendering();
|
||||
|
||||
// this UIWindow subclass is neccessary to make the status bar opaque
|
||||
_window = [[WindowWithStatusBarUnderlay alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
_window.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
41
examples/ASDKgram/Sample/TextureConfigDelegate.m
Normal file
41
examples/ASDKgram/Sample/TextureConfigDelegate.m
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// TextureConfigDelegate.m
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2018-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 <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@interface TextureConfigDelegate : NSObject <ASConfigurationDelegate>
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASConfiguration (UserProvided)
|
||||
|
||||
+ (ASConfiguration *)textureConfiguration
|
||||
{
|
||||
ASConfiguration *config = [[ASConfiguration alloc] init];
|
||||
config.experimentalFeatures = ASExperimentalGraphicsContexts | ASExperimentalTextNode;
|
||||
config.delegate = [[TextureConfigDelegate alloc] init];
|
||||
return config;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation TextureConfigDelegate
|
||||
|
||||
- (void)textureDidActivateExperimentalFeatures:(ASExperimentalFeatures)features
|
||||
{
|
||||
if (features & ASExperimentalGraphicsContexts) {
|
||||
NSLog(@"Texture activated experimental graphics contexts.");
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// Sample
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
|
||||
// grant of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present,
|
||||
// Pinterest, Inc. 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 "AppDelegate.h"
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
[ASTextNode setExperimentOptions:ASTextNodeExperimentRandomInstances];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
//
|
||||
// ViewController.m
|
||||
// Sample
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
// This source code is licensed under the BSD-style license found in the
|
||||
// LICENSE file in the root directory of this source tree. An additional grant
|
||||
// of patent rights can be found in the PATENTS file in the same directory.
|
||||
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
|
||||
// grant of patent rights can be found in the PATENTS file in the same directory.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// Modifications to this file made after 4/13/2017 are: Copyright (c) through the present,
|
||||
// Pinterest, Inc. 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 "ViewController.h"
|
||||
@@ -35,12 +35,10 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
|
||||
// array of boxed CGSizes corresponding to placekitten.com kittens
|
||||
NSMutableArray *_kittenDataSource;
|
||||
|
||||
BOOL _dataSourceLocked;
|
||||
NSIndexPath *_blurbNodeIndexPath;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray *kittenDataSource;
|
||||
@property (atomic, assign) BOOL dataSourceLocked;
|
||||
|
||||
@end
|
||||
|
||||
@@ -96,12 +94,6 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
|
||||
return kittens;
|
||||
}
|
||||
|
||||
- (void)setKittenDataSource:(NSMutableArray *)kittenDataSource {
|
||||
ASDisplayNodeAssert(!self.dataSourceLocked, @"Could not update data source when it is locked !");
|
||||
|
||||
_kittenDataSource = kittenDataSource;
|
||||
}
|
||||
|
||||
- (void)toggleEditingMode
|
||||
{
|
||||
[_tableNode.view setEditing:!_tableNode.view.editing animated:YES];
|
||||
|
||||
Reference in New Issue
Block a user