Merge commit '565da7d4935740d12fc204aa061faf093831da1e'

# Conflicts:
#	AsyncDisplayKit.xcodeproj/project.pbxproj
#	AsyncDisplayKit.xcodeproj/xcshareddata/xcschemes/AsyncDisplayKit.xcscheme
#	Source/ASDisplayNode.mm
#	Source/ASEditableTextNode.h
#	Source/ASImageNode.mm
#	Source/ASMapNode.h
#	Source/ASMapNode.mm
#	Source/Base/ASAssert.m
#	Source/Details/ASPhotosFrameworkImageRequest.h
#	Source/Details/ASPhotosFrameworkImageRequest.m
#	Source/Layout/ASLayoutElement.mm
This commit is contained in:
Peter
2018-10-08 22:42:45 +03:00
953 changed files with 7679 additions and 12153 deletions

2
.gitignore vendored
View File

@@ -19,8 +19,6 @@ build
*.swp
*.lock
*.gcov
*.gcno
*.gcda

View File

@@ -1,30 +0,0 @@
BSD License
For AsyncDisplayKit software
Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name Facebook nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,33 +0,0 @@
Additional Grant of Patent Rights Version 2
"Software" means the AsyncDisplayKit software distributed by Facebook, Inc.
Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
(subject to the termination provision below) license under any Necessary
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
transfer the Software. For avoidance of doubt, no license is granted under
Facebook's rights in any patent claims that are infringed by (i) modifications
to the Software made by you or any third party or (ii) the Software in
combination with any software or other technology.
The license granted hereunder will terminate, automatically and without notice,
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
directly or indirectly, or take a direct financial interest in, any Patent
Assertion: (i) against Facebook or any of its subsidiaries or corporate
affiliates, (ii) against any party if such Patent Assertion arises in whole or
in part from any software, technology, product or service of Facebook or any of
its subsidiaries or corporate affiliates, or (iii) against any party relating
to the Software. Notwithstanding the foregoing, if Facebook or any of its
subsidiaries or corporate affiliates files a lawsuit alleging patent
infringement against you in the first instance, and you respond by filing a
patent infringement counterclaim in that lawsuit against that party that is
unrelated to the Software, the license granted hereunder will not terminate
under section (i) of this paragraph due to such counterclaim.
A "Necessary Claim" is a claim of a patent owned by Facebook that is
necessarily infringed by the Software standing alone.
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
or contributory infringement or inducement to infringe any patent, including a
cross-claim or counterclaim.

View File

@@ -31,6 +31,8 @@
058D0A40195D057000B7D73C /* ASTextNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A36195D057000B7D73C /* ASTextNodeTests.m */; };
058D0A41195D057000B7D73C /* ASTextNodeWordKernerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A37195D057000B7D73C /* ASTextNodeWordKernerTests.mm */; };
05EA6FE71AC0966E00E35788 /* ASSnapshotTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.m */; };
0FAFDF7520EC1C90003A51C0 /* ASLayout+IGListKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAFDF7320EC1C8F003A51C0 /* ASLayout+IGListKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
0FAFDF7620EC1C90003A51C0 /* ASLayout+IGListKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FAFDF7420EC1C90003A51C0 /* ASLayout+IGListKit.mm */; };
18C2ED7F1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 18C2ED7C1B9B7DE800F627B3 /* ASCollectionNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
18C2ED831B9B7DE800F627B3 /* ASCollectionNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 18C2ED7D1B9B7DE800F627B3 /* ASCollectionNode.mm */; };
1A6C000D1FAB4E2100D05926 /* ASCornerLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A6C000B1FAB4E2000D05926 /* ASCornerLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -108,13 +110,14 @@
509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.m */; };
509E68651B3AEDC5009B9150 /* CoreGraphics+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.m */; };
636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.m in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DA1C5BF64600B16017 /* NSArray+Diffing.m */; };
636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */; };
636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */; };
680346941CE4052A0009FEB4 /* ASNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
68355B341CB579B9001D4E68 /* ASImageNode+AnimatedImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68355B2E1CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm */; };
68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */; };
68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */; };
68355B411CB57A6C001D4E68 /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; };
683F563720E409D700CEB7A3 /* ASDisplayNode+InterfaceState.h in Headers */ = {isa = PBXBuildFile; fileRef = 683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */; settings = {ATTRIBUTES = (Public, ); }; };
68AF37DB1CBEF4D80077BF76 /* ASImageNode+AnimatedImagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
68B0277B1C1A79D60041016B /* ASDisplayNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; };
68B8A4E21CBDB958007E4543 /* ASWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -131,6 +134,8 @@
6900C5F41E8072DA00BCD75C /* ASImageNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 6900C5F31E8072DA00BCD75C /* ASImageNode+Private.h */; };
6907C2581DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 6907C2561DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; };
6907C25A1DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m */; };
690BC8C120F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 690BC8BF20F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
690BC8C220F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m */; };
690C35621E055C5D00069B91 /* ASDimensionInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 690C35601E055C5D00069B91 /* ASDimensionInternal.mm */; };
690C35641E055C7B00069B91 /* ASDimensionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 690C35631E055C7B00069B91 /* ASDimensionInternal.h */; settings = {ATTRIBUTES = (Public, ); }; };
690ED58E1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 690ED58D1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -143,7 +148,6 @@
6947B0C01E36B4E30007C478 /* ASStackUnpositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6947B0BD1E36B4E30007C478 /* ASStackUnpositionedLayout.mm */; };
6947B0C31E36B5040007C478 /* ASStackPositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 6947B0C11E36B5040007C478 /* ASStackPositionedLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
6947B0C51E36B5040007C478 /* ASStackPositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6947B0C21E36B5040007C478 /* ASStackPositionedLayout.mm */; };
6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */; };
695943401D70815300B0EE1F /* ASDisplayNodeLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
695BE2551DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 695BE2541DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm */; };
696F01EC1DD2AF450049FBD5 /* ASEventLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 696F01EA1DD2AF450049FBD5 /* ASEventLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -153,7 +157,7 @@
697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */; };
697B315A1CFE4B410049936F /* ASEditableTextNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */; };
698371DB1E4379CD00437585 /* ASNodeController+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 698371D91E4379CD00437585 /* ASNodeController+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; };
698371DC1E4379CD00437585 /* ASNodeController+Beta.m in Sources */ = {isa = PBXBuildFile; fileRef = 698371DA1E4379CD00437585 /* ASNodeController+Beta.m */; };
698371DC1E4379CD00437585 /* ASNodeController+Beta.mm in Sources */ = {isa = PBXBuildFile; fileRef = 698371DA1E4379CD00437585 /* ASNodeController+Beta.mm */; };
698C8B621CAB49FC0052DC3F /* ASLayoutElementExtensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 698C8B601CAB49FC0052DC3F /* ASLayoutElementExtensibility.h */; settings = {ATTRIBUTES = (Public, ); }; };
698DFF441E36B6C9002891F1 /* ASStackLayoutSpecUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 698DFF431E36B6C9002891F1 /* ASStackLayoutSpecUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
698DFF471E36B7E9002891F1 /* ASLayoutSpecUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 698DFF461E36B7E9002891F1 /* ASLayoutSpecUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -180,8 +184,6 @@
8BBBAB8D1CEBAF1E00107FC6 /* ASDefaultPlaybackButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.m */; };
8BDA5FC71CDBDF91007D13B2 /* ASVideoPlayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BDA5FC31CDBDDE1007D13B2 /* ASVideoPlayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
8BDA5FC81CDBDF95007D13B2 /* ASVideoPlayerNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8BDA5FC41CDBDDE1007D13B2 /* ASVideoPlayerNode.mm */; };
9019FBBD1ED8061D00C45F72 /* ASYogaLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 9019FBB91ED8061D00C45F72 /* ASYogaLayoutSpec.h */; };
9019FBBE1ED8061D00C45F72 /* ASYogaLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9019FBBA1ED8061D00C45F72 /* ASYogaLayoutSpec.mm */; };
9019FBBF1ED8061D00C45F72 /* ASYogaUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 9019FBBB1ED8061D00C45F72 /* ASYogaUtilities.h */; };
9019FBC01ED8061D00C45F72 /* ASYogaUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9019FBBC1ED8061D00C45F72 /* ASYogaUtilities.mm */; };
909C4C751F09C98B00D6B76F /* ASTextNode2.h in Headers */ = {isa = PBXBuildFile; fileRef = 909C4C731F09C98B00D6B76F /* ASTextNode2.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -225,6 +227,7 @@
ACF6ED611B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED591B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm */; };
ACF6ED621B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED5A1B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm */; };
ACF6ED631B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED5B1B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm */; };
AE440175210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE440174210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm */; };
AE6987C11DD04E1000B9E458 /* ASPagerNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AE6987C01DD04E1000B9E458 /* ASPagerNodeTests.m */; };
AEEC47E41C21D3D200EC1693 /* ASVideoNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */; };
B13CA0F81C519EBA00E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = B13CA0F61C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -332,6 +335,9 @@
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 */; };
CC35CEC320DD7F600006448D /* ASCollections.h in Headers */ = {isa = PBXBuildFile; fileRef = CC35CEC120DD7F600006448D /* ASCollections.h */; settings = {ATTRIBUTES = (Public, ); }; };
CC35CEC420DD7F600006448D /* ASCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = CC35CEC220DD7F600006448D /* ASCollections.m */; };
CC35CEC620DD87280006448D /* ASCollectionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC35CEC520DD87280006448D /* ASCollectionsTests.m */; };
CC3B20841C3F76D600798563 /* ASPendingStateController.h in Headers */ = {isa = PBXBuildFile; fileRef = CC3B20811C3F76D600798563 /* ASPendingStateController.h */; settings = {ATTRIBUTES = (Private, ); }; };
CC3B20861C3F76D600798563 /* ASPendingStateController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B20821C3F76D600798563 /* ASPendingStateController.mm */; };
CC3B208A1C3F7A5400798563 /* ASWeakSet.h in Headers */ = {isa = PBXBuildFile; fileRef = CC3B20871C3F7A5400798563 /* ASWeakSet.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -452,9 +458,6 @@
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
DEFAD8131CC48914000527C4 /* ASVideoNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E01C20C2DD00EC1693 /* ASVideoNode.mm */; };
E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.m */; };
E52AC9BA1FEA90EB00AA4040 /* ASRectMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = E52AC9B81FEA90EB00AA4040 /* ASRectMap.mm */; };
E52AC9BB1FEA90EB00AA4040 /* ASRectMap.h in Headers */ = {isa = PBXBuildFile; fileRef = E52AC9B91FEA90EB00AA4040 /* ASRectMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
E52AC9C01FEA916C00AA4040 /* ASRectMapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E52AC9BE1FEA915D00AA4040 /* ASRectMapTests.m */; };
E54E00721F1D3828000B30D7 /* ASPagerNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = E54E00711F1D3828000B30D7 /* ASPagerNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; };
E54E81FC1EB357BD00FFE8E1 /* ASPageTable.h in Headers */ = {isa = PBXBuildFile; fileRef = E54E81FA1EB357BD00FFE8E1 /* ASPageTable.h */; };
E54E81FD1EB357BD00FFE8E1 /* ASPageTable.m in Sources */ = {isa = PBXBuildFile; fileRef = E54E81FB1EB357BD00FFE8E1 /* ASPageTable.m */; };
@@ -490,6 +493,7 @@
E5E281761E71C845006B67C2 /* ASCollectionLayoutState.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5E281751E71C845006B67C2 /* ASCollectionLayoutState.mm */; };
E5E2D72E1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E5E2D72D1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
E5E2D7301EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */; };
F3F698D2211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */; };
F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */; };
FA4FAF15200A850200E735BD /* ASControlNode+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4FAF14200A850200E735BD /* ASControlNode+Private.h */; };
/* End PBXBuildFile section */
@@ -599,6 +603,8 @@
058D0A44195D058D00B7D73C /* ASBaseDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBaseDefines.h; sourceTree = "<group>"; };
05EA6FE61AC0966E00E35788 /* ASSnapshotTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASSnapshotTestCase.m; sourceTree = "<group>"; };
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageProtocols.h; sourceTree = "<group>"; };
0FAFDF7320EC1C8F003A51C0 /* ASLayout+IGListKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASLayout+IGListKit.h"; sourceTree = "<group>"; };
0FAFDF7420EC1C90003A51C0 /* ASLayout+IGListKit.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASLayout+IGListKit.mm"; sourceTree = "<group>"; };
18C2ED7C1B9B7DE800F627B3 /* ASCollectionNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionNode.h; sourceTree = "<group>"; };
18C2ED7D1B9B7DE800F627B3 /* ASCollectionNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionNode.mm; sourceTree = "<group>"; };
1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHelpers.h; sourceTree = "<group>"; };
@@ -667,6 +673,7 @@
68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageContainerProtocolCategories.h; sourceTree = "<group>"; };
68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASImageContainerProtocolCategories.m; sourceTree = "<group>"; };
68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPINRemoteImageDownloader.h; sourceTree = "<group>"; };
683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+InterfaceState.h"; sourceTree = "<group>"; };
68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Beta.h"; sourceTree = "<group>"; };
68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+AnimatedImagePrivate.h"; sourceTree = "<group>"; };
68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakProxy.h; sourceTree = "<group>"; };
@@ -684,6 +691,8 @@
6900C5F31E8072DA00BCD75C /* ASImageNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+Private.h"; sourceTree = "<group>"; };
6907C2561DC4ECFE00374C66 /* ASObjectDescriptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASObjectDescriptionHelpers.h; sourceTree = "<group>"; };
6907C2571DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASObjectDescriptionHelpers.m; sourceTree = "<group>"; };
690BC8BF20F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeCornerLayerDelegate.h; sourceTree = "<group>"; };
690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeCornerLayerDelegate.m; sourceTree = "<group>"; };
690C35601E055C5D00069B91 /* ASDimensionInternal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDimensionInternal.mm; sourceTree = "<group>"; };
690C35631E055C7B00069B91 /* ASDimensionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDimensionInternal.h; sourceTree = "<group>"; };
690ED58D1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutElementStylePrivate.h; sourceTree = "<group>"; };
@@ -695,7 +704,6 @@
6947B0BD1E36B4E30007C478 /* ASStackUnpositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackUnpositionedLayout.mm; sourceTree = "<group>"; };
6947B0C11E36B5040007C478 /* ASStackPositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackPositionedLayout.h; sourceTree = "<group>"; };
6947B0C21E36B5040007C478 /* ASStackPositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackPositionedLayout.mm; sourceTree = "<group>"; };
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeLayout.mm; sourceTree = "<group>"; };
6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeLayout.h; sourceTree = "<group>"; };
695BE2541DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASWrapperSpecSnapshotTests.mm; sourceTree = "<group>"; };
696F01EA1DD2AF450049FBD5 /* ASEventLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEventLog.h; sourceTree = "<group>"; };
@@ -705,7 +713,7 @@
6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASLayoutSpec+Subclasses.mm"; sourceTree = "<group>"; };
697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASEditableTextNodeTests.m; sourceTree = "<group>"; };
698371D91E4379CD00437585 /* ASNodeController+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASNodeController+Beta.h"; sourceTree = "<group>"; };
698371DA1E4379CD00437585 /* ASNodeController+Beta.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ASNodeController+Beta.m"; sourceTree = "<group>"; };
698371DA1E4379CD00437585 /* ASNodeController+Beta.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "ASNodeController+Beta.mm"; sourceTree = "<group>"; };
698C8B601CAB49FC0052DC3F /* ASLayoutElementExtensibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutElementExtensibility.h; sourceTree = "<group>"; };
698DFF431E36B6C9002891F1 /* ASStackLayoutSpecUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackLayoutSpecUtilities.h; sourceTree = "<group>"; };
698DFF461E36B7E9002891F1 /* ASLayoutSpecUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecUtilities.h; sourceTree = "<group>"; };
@@ -734,8 +742,6 @@
8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDefaultPlaybackButton.m; sourceTree = "<group>"; };
8BDA5FC31CDBDDE1007D13B2 /* ASVideoPlayerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASVideoPlayerNode.h; sourceTree = "<group>"; };
8BDA5FC41CDBDDE1007D13B2 /* ASVideoPlayerNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASVideoPlayerNode.mm; sourceTree = "<group>"; };
9019FBB91ED8061D00C45F72 /* ASYogaLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASYogaLayoutSpec.h; sourceTree = "<group>"; };
9019FBBA1ED8061D00C45F72 /* ASYogaLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASYogaLayoutSpec.mm; sourceTree = "<group>"; };
9019FBBB1ED8061D00C45F72 /* ASYogaUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASYogaUtilities.h; sourceTree = "<group>"; };
9019FBBC1ED8061D00C45F72 /* ASYogaUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASYogaUtilities.mm; sourceTree = "<group>"; };
909C4C731F09C98B00D6B76F /* ASTextNode2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextNode2.h; sourceTree = "<group>"; };
@@ -805,6 +811,7 @@
ACF6ED591B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASOverlayLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
ACF6ED5A1B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRatioLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
ACF6ED5B1B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
AE440174210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextKitFontSizeAdjusterTests.mm; sourceTree = "<group>"; };
AE6987C01DD04E1000B9E458 /* ASPagerNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPagerNodeTests.m; sourceTree = "<group>"; };
AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDefaultPlayButton.h; sourceTree = "<group>"; };
AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDefaultPlayButton.m; sourceTree = "<group>"; };
@@ -839,6 +846,9 @@
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>"; };
CC35CEC120DD7F600006448D /* ASCollections.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASCollections.h; sourceTree = "<group>"; };
CC35CEC220DD7F600006448D /* ASCollections.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASCollections.m; sourceTree = "<group>"; };
CC35CEC520DD87280006448D /* ASCollectionsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASCollectionsTests.m; sourceTree = "<group>"; };
CC3B20811C3F76D600798563 /* ASPendingStateController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPendingStateController.h; sourceTree = "<group>"; };
CC3B20821C3F76D600798563 /* ASPendingStateController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPendingStateController.mm; sourceTree = "<group>"; };
CC3B20871C3F7A5400798563 /* ASWeakSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakSet.h; sourceTree = "<group>"; };
@@ -960,7 +970,7 @@
DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = _ASTransitionContext.m; path = ../_ASTransitionContext.m; sourceTree = "<group>"; };
DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASContextTransitioning.h; sourceTree = "<group>"; };
DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Diffing.h"; sourceTree = "<group>"; };
DBC452DA1C5BF64600B16017 /* NSArray+Diffing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Diffing.m"; sourceTree = "<group>"; };
DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSArray+Diffing.mm"; sourceTree = "<group>"; };
DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ArrayDiffingTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
DBC453211C5FD97200B16017 /* ASDisplayNodeImplicitHierarchyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASDisplayNodeImplicitHierarchyTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
DBDB83921C6E879900D0098C /* ASPagerFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPagerFlowLayout.h; sourceTree = "<group>"; };
@@ -975,9 +985,6 @@
E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLayoutFlatteningTests.m; sourceTree = "<group>"; };
E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutTransition.mm; sourceTree = "<group>"; };
E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutTransition.h; sourceTree = "<group>"; };
E52AC9B81FEA90EB00AA4040 /* ASRectMap.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRectMap.mm; sourceTree = "<group>"; };
E52AC9B91FEA90EB00AA4040 /* ASRectMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRectMap.h; sourceTree = "<group>"; };
E52AC9BE1FEA915D00AA4040 /* ASRectMapTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASRectMapTests.m; sourceTree = "<group>"; };
E54E00711F1D3828000B30D7 /* ASPagerNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASPagerNode+Beta.h"; sourceTree = "<group>"; };
E54E81FA1EB357BD00FFE8E1 /* ASPageTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPageTable.h; sourceTree = "<group>"; };
E54E81FB1EB357BD00FFE8E1 /* ASPageTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPageTable.m; sourceTree = "<group>"; };
@@ -1014,6 +1021,7 @@
E5E2D72D1EA780C4005C24C6 /* ASCollectionGalleryLayoutDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionGalleryLayoutDelegate.h; sourceTree = "<group>"; };
E5E2D72F1EA780DF005C24C6 /* ASCollectionGalleryLayoutDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionGalleryLayoutDelegate.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayViewAccessibilityTests.mm; sourceTree = "<group>"; };
F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeExtrasTests.m; sourceTree = "<group>"; };
FA4FAF14200A850200E735BD /* ASControlNode+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Private.h"; sourceTree = "<group>"; };
FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.debug.xcconfig"; sourceTree = "<group>"; };
@@ -1115,6 +1123,8 @@
058D09B1195D04C000B7D73C /* Source */ = {
isa = PBXGroup;
children = (
CC35CEC120DD7F600006448D /* ASCollections.h */,
CC35CEC220DD7F600006448D /* ASCollections.m */,
058D0A42195D058D00B7D73C /* Base */,
CCE04B1D1E313E99006AEBBB /* Collection Data Adapter */,
DE89C1691DCEB9CC00D49D74 /* Debug */,
@@ -1156,6 +1166,7 @@
68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */,
CC034A071E60BEB400626263 /* ASDisplayNode+Convenience.h */,
CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.m */,
683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */,
69BCE3D71EC6513B007DCCAD /* ASDisplayNode+Layout.mm */,
058D09DA195D050800B7D73C /* ASDisplayNode+Subclasses.h */,
90FC784E1E4BFE1B00383C5A /* ASDisplayNode+Yoga.mm */,
@@ -1182,7 +1193,7 @@
055B9FA61A1C154B00035D6D /* ASNetworkImageNode.h */,
055B9FA71A1C154B00035D6D /* ASNetworkImageNode.mm */,
698371D91E4379CD00437585 /* ASNodeController+Beta.h */,
698371DA1E4379CD00437585 /* ASNodeController+Beta.m */,
698371DA1E4379CD00437585 /* ASNodeController+Beta.mm */,
DBDB83921C6E879900D0098C /* ASPagerFlowLayout.h */,
DBDB83931C6E879900D0098C /* ASPagerFlowLayout.m */,
25E327541C16819500A2170C /* ASPagerNode.h */,
@@ -1238,6 +1249,7 @@
058D09C5195D04C000B7D73C /* Tests */ = {
isa = PBXGroup;
children = (
F3F698D1211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm */,
DBC452DD1C5C6A6A00B16017 /* ArrayDiffingTests.m */,
AC026B571BD3F61800BBC17E /* ASAbsoluteLayoutSpecSnapshotTests.m */,
696FCB301D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm */,
@@ -1248,6 +1260,7 @@
CC051F1E1D7A286A006434CB /* ASCALayerTests.m */,
ACF6ED531B178DC700DA7C62 /* ASCenterLayoutSpecSnapshotTests.mm */,
CCDD148A1EEDCD9D0020834E /* ASCollectionModernDataSourceTests.m */,
CC35CEC520DD87280006448D /* ASCollectionsTests.m */,
2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */,
9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.mm */,
CCEDDDD8200C518800FFCD0A /* ASConfigurationTests.m */,
@@ -1286,7 +1299,6 @@
CC8B05D51D73836400F54286 /* ASPerformanceTestContext.m */,
CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */,
ACF6ED5A1B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm */,
E52AC9BE1FEA915D00AA4040 /* ASRectMapTests.m */,
CCAA0B81206ADECB0057B336 /* ASRecursiveUnfairLockTests.m */,
7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */,
4E9127681F64157600499623 /* ASRunLoopQueueTests.m */,
@@ -1298,8 +1310,10 @@
3C9C128419E616EF00E942A0 /* ASTableViewTests.mm */,
CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */,
058D0A33195D057000B7D73C /* ASTextKitCoreTextAdditionsTests.m */,
AE440174210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm */,
254C6B531BF8FF2A003EC431 /* ASTextKitTests.mm */,
254C6B511BF8FE6D003EC431 /* ASTextKitTruncationTests.mm */,
C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.m */,
CC8B05D71D73979700F54286 /* ASTextNodePerformanceTests.m */,
81E95C131D62639600336598 /* ASTextNodeSnapshotTests.m */,
058D0A36195D057000B7D73C /* ASTextNodeTests.m */,
@@ -1309,7 +1323,6 @@
4496D0721FA9EA6B001CC8D5 /* ASTraitCollectionTests.m */,
CC0AEEA31D66316E005D1C78 /* ASUICollectionViewTests.m */,
AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */,
C057D9BC20B5453D00FC9112 /* ASTextNode2SnapshotTests.m */,
CCA221D21D6FA7EF00AF6A0F /* ASViewControllerTests.m */,
83A7D95D1D446A6E00BF333E /* ASWeakMapTests.m */,
CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */,
@@ -1408,7 +1421,7 @@
205F0E1F1B376416007741D0 /* CoreGraphics+ASConvenience.h */,
205F0E201B376416007741D0 /* CoreGraphics+ASConvenience.m */,
DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */,
DBC452DA1C5BF64600B16017 /* NSArray+Diffing.m */,
DBC452DA1C5BF64600B16017 /* NSArray+Diffing.mm */,
CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */,
CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */,
058D09F5195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.h */,
@@ -1471,9 +1484,10 @@
058D0A0A195D050800B7D73C /* ASDisplayNode+DebugTiming.mm */,
DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */,
058D0A0B195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm */,
690BC8BF20F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h */,
690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m */,
058D0A0C195D050800B7D73C /* ASDisplayNodeInternal.h */,
6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */,
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */,
CCA282C61E9EB64B0037E8B7 /* ASDisplayNodeTipState.h */,
CCA282C71E9EB64B0037E8B7 /* ASDisplayNodeTipState.m */,
68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */,
@@ -1491,8 +1505,6 @@
CCED5E402020D41600395C40 /* ASNetworkImageLoadInfo+Private.h */,
CC3B20811C3F76D600798563 /* ASPendingStateController.h */,
CC3B20821C3F76D600798563 /* ASPendingStateController.mm */,
E52AC9B91FEA90EB00AA4040 /* ASRectMap.h */,
E52AC9B81FEA90EB00AA4040 /* ASRectMap.mm */,
CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */,
CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */,
CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */,
@@ -1627,6 +1639,8 @@
ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutSpec.mm */,
ACF6ED0B1B17843500DA7C62 /* ASLayout.h */,
ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */,
0FAFDF7320EC1C8F003A51C0 /* ASLayout+IGListKit.h */,
0FAFDF7420EC1C90003A51C0 /* ASLayout+IGListKit.mm */,
ACF6ED111B17843500DA7C62 /* ASLayoutElement.h */,
E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */,
698C8B601CAB49FC0052DC3F /* ASLayoutElementExtensibility.h */,
@@ -1645,8 +1659,6 @@
9C49C36E1B853957000B0DD5 /* ASStackLayoutElement.h */,
ACF6ED161B17843500DA7C62 /* ASStackLayoutSpec.h */,
ACF6ED171B17843500DA7C62 /* ASStackLayoutSpec.mm */,
9019FBB91ED8061D00C45F72 /* ASYogaLayoutSpec.h */,
9019FBBA1ED8061D00C45F72 /* ASYogaLayoutSpec.mm */,
9019FBBB1ED8061D00C45F72 /* ASYogaUtilities.h */,
9019FBBC1ED8061D00C45F72 /* ASYogaUtilities.mm */,
);
@@ -1844,6 +1856,7 @@
69E0E8A71D356C9400627613 /* ASEqualityHelpers.h in Headers */,
698C8B621CAB49FC0052DC3F /* ASLayoutElementExtensibility.h in Headers */,
69F10C871C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */,
0FAFDF7520EC1C90003A51C0 /* ASLayout+IGListKit.h in Headers */,
B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */,
68355B411CB57A6C001D4E68 /* ASImageContainerProtocolCategories.h in Headers */,
7630FFA81C9E267E007A7C0E /* ASVideoNode.h in Headers */,
@@ -1915,6 +1928,8 @@
CC034A091E60BEB400626263 /* ASDisplayNode+Convenience.h in Headers */,
254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */,
B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */,
683F563720E409D700CEB7A3 /* ASDisplayNode+InterfaceState.h in Headers */,
690BC8C120F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.h in Headers */,
68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */,
CCCCCCE11EC3EF060087FE10 /* ASTextUtilities.h in Headers */,
B350624B1B010EFD0018CF92 /* _ASPendingState.h in Headers */,
@@ -1940,7 +1955,6 @@
E5775B021F16759300CAC9BC /* ASCollectionLayoutCache.h in Headers */,
E5775B001F13D25400CAC9BC /* ASCollectionLayoutState+Private.h in Headers */,
E5667E8C1F33871300FA6FC0 /* _ASCollectionGalleryLayoutInfo.h in Headers */,
E52AC9BB1FEA90EB00AA4040 /* ASRectMap.h in Headers */,
E5775AFC1F13CE9F00CAC9BC /* _ASCollectionGalleryLayoutItem.h in Headers */,
E5855DF01EBB4D83003639AE /* ASCollectionLayoutDefines.h in Headers */,
E5B5B9D11E9BAD9800A6B726 /* ASCollectionLayoutContext+Private.h in Headers */,
@@ -1979,7 +1993,6 @@
CCF18FF41D2575E300DF5895 /* NSIndexSet+ASHelpers.h in Headers */,
83A7D95C1D44548100BF333E /* ASWeakMap.h in Headers */,
E5711A2C1C840C81009619D4 /* ASCollectionElement.h in Headers */,
9019FBBD1ED8061D00C45F72 /* ASYogaLayoutSpec.h in Headers */,
6947B0BE1E36B4E30007C478 /* ASStackUnpositionedLayout.h in Headers */,
CC4C2A771D88E3BF0039ACAB /* ASTraceEvent.h in Headers */,
254C6B7B1BF94DF4003EC431 /* ASTextKitRenderer+Positioning.h in Headers */,
@@ -2019,6 +2032,7 @@
CCCCCCDB1EC3EF060087FE10 /* ASTextLine.h in Headers */,
9C70F20E1CDBE9E5007D6C76 /* NSArray+Diffing.h in Headers */,
CCCCCCE71EC3F0FC0087FE10 /* NSAttributedString+ASText.h in Headers */,
CC35CEC320DD7F600006448D /* ASCollections.h in Headers */,
CC7AF196200D9BD500A21BDE /* ASExperimentalFeatures.h in Headers */,
CCCCCCDF1EC3EF060087FE10 /* ASTextRunDelegate.h in Headers */,
9C49C3701B853961000B0DD5 /* ASStackLayoutElement.h in Headers */,
@@ -2114,7 +2128,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = AS;
LastUpgradeCheck = 0820;
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = Pinterest;
TargetAttributes = {
057D02BE1AC0A66700C7AC3C = {
@@ -2247,6 +2261,7 @@
buildActionMask = 2147483647;
files = (
CCEDDDD9200C518800FFCD0A /* ASConfigurationTests.m in Sources */,
AE440175210FB7CF00B36DA2 /* ASTextKitFontSizeAdjusterTests.mm in Sources */,
E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.m in Sources */,
4496D0731FA9EA6B001CC8D5 /* ASTraitCollectionTests.m in Sources */,
29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m in Sources */,
@@ -2277,6 +2292,7 @@
4E9127691F64157600499623 /* ASRunLoopQueueTests.m in Sources */,
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */,
CC54A81E1D7008B300296A24 /* ASDispatchTests.m in Sources */,
F3F698D2211CAD4600800CB1 /* ASDisplayViewAccessibilityTests.mm in Sources */,
CCE4F9B31F0D60AC00062E4E /* ASIntegerMapTests.m in Sources */,
058D0A3B195D057000B7D73C /* ASDisplayNodeTestsHelper.m in Sources */,
83A7D95E1D446A6E00BF333E /* ASWeakMapTests.m in Sources */,
@@ -2303,8 +2319,8 @@
1A6C00111FAB4EDD00D05926 /* ASCornerLayoutSpecSnapshotTests.mm in Sources */,
254C6B541BF8FF2A003EC431 /* ASTextKitTests.mm in Sources */,
05EA6FE71AC0966E00E35788 /* ASSnapshotTestCase.m in Sources */,
CC35CEC620DD87280006448D /* ASCollectionsTests.m in Sources */,
ACF6ED631B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm in Sources */,
E52AC9C01FEA916C00AA4040 /* ASRectMapTests.m in Sources */,
CCE4F9BA1F0DBB5000062E4E /* ASLayoutTestNode.mm in Sources */,
CCAA0B82206ADECB0057B336 /* ASRecursiveUnfairLockTests.m in Sources */,
81E95C141D62639600336598 /* ASTextNodeSnapshotTests.m in Sources */,
@@ -2334,7 +2350,6 @@
3917EBD51E9C2FC400D04A01 /* _ASCollectionReusableView.m in Sources */,
CCA282D11E9EBF6C0037E8B7 /* ASTipsWindow.m in Sources */,
CCCCCCE41EC3EF060087FE10 /* NSParagraphStyle+ASText.m in Sources */,
E52AC9BA1FEA90EB00AA4040 /* ASRectMap.mm in Sources */,
8BBBAB8D1CEBAF1E00107FC6 /* ASDefaultPlaybackButton.m in Sources */,
B30BF6541C59D889004FCD53 /* ASLayoutManager.m in Sources */,
92DD2FE71BF4D0850074C9DD /* ASMapNode.mm in Sources */,
@@ -2355,7 +2370,7 @@
DEFAD8131CC48914000527C4 /* ASVideoNode.mm in Sources */,
CCA282C11E9EAE010037E8B7 /* ASTip.m in Sources */,
B350624C1B010EFD0018CF92 /* _ASPendingState.mm in Sources */,
698371DC1E4379CD00437585 /* ASNodeController+Beta.m in Sources */,
698371DC1E4379CD00437585 /* ASNodeController+Beta.mm in Sources */,
CC6AA2DB1E9F03B900978E87 /* ASDisplayNode+Ancestry.m in Sources */,
509E68621B3AEDA5009B9150 /* ASAbstractLayoutController.mm in Sources */,
254C6B861BF94F8A003EC431 /* ASTextKitContext.mm in Sources */,
@@ -2363,6 +2378,7 @@
E5B078001E69F4EB00C24B5B /* ASElementMap.m in Sources */,
9C8898BC1C738BA800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */,
690ED59B1E36D118000627C0 /* ASImageNode+tvOS.m in Sources */,
0FAFDF7620EC1C90003A51C0 /* ASLayout+IGListKit.mm in Sources */,
CCDC9B4E200991D10063C1F8 /* ASGraphicsContext.m in Sources */,
CCCCCCD81EC3EF060087FE10 /* ASTextInput.m in Sources */,
34EFC7621B701CA400AD841F /* ASBackgroundLayoutSpec.mm in Sources */,
@@ -2397,7 +2413,7 @@
B350624E1B010EFD0018CF92 /* ASDisplayNode+AsyncDisplay.mm in Sources */,
E5667E8E1F33872700FA6FC0 /* _ASCollectionGalleryLayoutInfo.m in Sources */,
25E327591C16819500A2170C /* ASPagerNode.m in Sources */,
636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.m in Sources */,
636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.mm in Sources */,
B35062501B010EFD0018CF92 /* ASDisplayNode+DebugTiming.mm in Sources */,
DEC146B91C37A16A004A0EE7 /* ASCollectionInternal.m in Sources */,
254C6B891BF94F8A003EC431 /* ASTextKitRenderer+Positioning.mm in Sources */,
@@ -2421,6 +2437,7 @@
68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */,
E5855DEF1EBB4D83003639AE /* ASCollectionLayoutDefines.m in Sources */,
B35062031B010EFD0018CF92 /* ASImageNode.mm in Sources */,
690BC8C220F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m in Sources */,
254C6B821BF94F8A003EC431 /* ASTextKitComponents.mm in Sources */,
34EFC7601B701C8B00AD841F /* ASInsetLayoutSpec.mm in Sources */,
AC6145441D8AFD4F003D62A2 /* ASSection.m in Sources */,
@@ -2439,7 +2456,6 @@
6907C25A1DC4ECFE00374C66 /* ASObjectDescriptionHelpers.m in Sources */,
B35062051B010EFD0018CF92 /* ASMultiplexImageNode.mm in Sources */,
B35062251B010EFD0018CF92 /* ASMutableAttributedStringBuilder.m in Sources */,
9019FBBE1ED8061D00C45F72 /* ASYogaLayoutSpec.mm in Sources */,
B35062071B010EFD0018CF92 /* ASNetworkImageNode.mm in Sources */,
34EFC76D1B701CF100AD841F /* ASOverlayLayoutSpec.mm in Sources */,
044285101BAA64EC00D16268 /* ASTwoDimensionalArrayUtils.m in Sources */,
@@ -2447,6 +2463,7 @@
CCA282B51E9EA7310037E8B7 /* ASTipsController.m in Sources */,
B35062271B010EFD0018CF92 /* ASRangeController.mm in Sources */,
0442850A1BAA63FE00D16268 /* ASBatchFetching.m in Sources */,
CC35CEC420DD7F600006448D /* ASCollections.m in Sources */,
68FC85E61CE29B9400EDD713 /* ASNavigationController.m in Sources */,
CC4C2A791D88E3BF0039ACAB /* ASTraceEvent.m in Sources */,
34EFC76F1B701CF700AD841F /* ASRatioLayoutSpec.mm in Sources */,
@@ -2480,7 +2497,6 @@
DB78412E1C6BCE1600A9E2B4 /* _ASTransitionContext.m in Sources */,
B350620B1B010EFD0018CF92 /* ASTableView.mm in Sources */,
B350620E1B010EFD0018CF92 /* ASTextNode.mm in Sources */,
6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */,
68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */,
CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m in Sources */,
509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.m in Sources */,

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

2
BUCK
View File

@@ -4,6 +4,8 @@
COMMON_PREPROCESSOR_FLAGS = [
'-fobjc-arc',
'-DDEBUG=1',
'-fno-exceptions',
'-fno-objc-arc-exceptions'
]
COMMON_LANG_PREPROCESSOR_FLAGS = {

View File

@@ -1,5 +1,14 @@
## master
* Add your own contributions to the next release on the line below this with your name.
- [ASPhotosFrameworkImageRequestTests] Guard photo library with macro for tests. [Max Wang](https://github.com/wsdwsd0829). [#1147](https://github.com/TextureGroup/Texture/pull/1147)
- [ASDisplayNode] Do not cancel display when in exit hierarchy but let interface state changing to handle it. [Max Wang](https://github.com/wsdwsd0829). [#1110](https://github.com/TextureGroup/Texture/pull/1110)
- [Breaking][ASDisplayNode] Make interface state delegate protocol required. [Max Wang](https://github.com/wsdwsd0829). [#1112](https://github.com/TextureGroup/Texture/pull/1112)
- [ASCollectionView] Fix reording of cells manually for iOS 9 & 10. [Max Wang](https://github.com/wsdwsd0829). [#1081](https://github.com/TextureGroup/Texture/pull/1081)
- [ASDisplayNode] Allow add/remove interface state delegates on background thread. [Max Wang](https://github.com/wsdwsd0829). [#1090](https://github.com/TextureGroup/Texture/pull/1090)
- [License] Simplify the Texture license to be pure Apache 2 (removing ASDK-Licenses).[Scott Goodson](https://github.com/appleguy) [#1077](https://github.com/TextureGroup/Texture/pull/1077)
- [ASNetworkImageNode] Allow delegate methods to be called on background thread. [Max Wang](https://github.com/wsdwsd0829). [#1007](https://github.com/TextureGroup/Texture/pull/1007)
- [ASLayoutTransition] Add support for preserving order after node moves during transitions. (This order defines the z-order as well.) [Kevin Smith](https://github.com/wiseoldduck) [#1006]
- [ASDisplayNode] Adds support for multiple interface state delegates. [Garrett Moon](https://github.com/garrettmoon) [#979](https://github.com/TextureGroup/Texture/pull/979)
- [ASDataController] Add capability to renew supplementary views (update map) when size change from zero to non-zero.[Max Wang](https://github.com/wsdwsd0829) [#842](https://github.com/TextureGroup/Texture/pull/842)
- Make `ASPerformMainThreadDeallocation` visible in C. [Adlai Holler](https://github.com/Adlai-Holler)
- Add snapshot test for astextnode2. [Max Wang](https://github.com/wsdwsd0829) [#935](https://github.com/TextureGroup/Texture/pull/935)
@@ -9,6 +18,41 @@
- Reduce usage of autorelease pools. [Adlai Holler](https://github.com/Adlai-Holler) [#968](https://github.com/TextureGroup/Texture/pull/968)
- Clean up unused/unneeded header macros. [Adlai Holler](https://github.com/Adlai-Holler)
- Clean up C-function `extern` decorators. [Adlai Holler](https://github.com/Adlai-Holler)
- Add an experiment to reduce work involved in collection teardown. [Adlai Holler](https://github.com/Adlai-Holler)
- Optimize layout flattening, particularly reducing retain/release operations. [Adlai Holler](https://github.com/Adlai-Holler)
- Create a method to transfer strong C-arrays into immutable NSArrays, reducing retain/release traffic. [Adlai Holler](https://github.com/Adlai-Holler)
- Remove yoga layout spec, which has been superseded by tighter Yoga integration (`ASDisplayNode+Yoga.h`)
- Properly consider node for responder methods [Michael Schneider](https://github.com/maicki)
- Introduce let / var macros and some further cleanup. [Michael Schneider](https://github.com/maicki) [#1012](https://github.com/TextureGroup/Texture/pull/1012)
- [IGListKit] Adds missing UIScrollViewDelegate method to DataSource proxy [Sergey Pronin](https://github.com/wannabehero)
- Fix misleading/scary stack trace shown when an assertion occurs during node measurement [Huy Nguyen](https://github.com/nguyenhuy) [#1022](https://github.com/TextureGroup/Texture/pull/1022)
- Fix build on 32-bit simulator in Xcode 9.3 and later, caused by `Thread-local storage is not supported on this architecture.` [Adlai Holler](https://github.com/Adlai-Holler)
- Enable locking assertions (and add some more) to improve and enforce locking safety within the framework [Huy Nguyen](https://github.com/nguyenhuy) [#1024](https://github.com/TextureGroup/Texture/pull/1024)
- Split MapKit, Photos, and AssetsLibrary dependent code into separate subspecs to improve binary size and start time when they're not needed. The default subspec includes all three for backwards compatibility, but this **will change in 3.0**. When using non-Cocoapods build environments, define `AS_USE_PHOTOS, AS_USE_MAPKIT, AS_USE_ASSETS_LIBRARY` to 1 respectively to signal their use. [Adlai Holler](https://github.com/Adlai-Holler)
- Optimization: Removed an NSMutableArray in flattened layouts. [Adlai Holler](https://github.com/Adlai-Holler)
- Reduced binary size by disabling exception support (which we don't use.) [Adlai Holler](https://github.com/Adlai-Holler)
- Create and set delegate for clip corner layers within ASDisplayNode [Michael Schneider](https://github.com/maicki) [#1029](https://github.com/TextureGroup/Texture/pull/1029)
- Improve locking situation in ASVideoPlayerNode [Michael Schneider](https://github.com/maicki) [#1042](https://github.com/TextureGroup/Texture/pull/1042)
- Optimize ASDisplayNode -> ASNodeController reference by removing weak proxy and objc associated objects. [Adlai Holler](https://github.com/Adlai-Holler)
- Remove CA transaction signpost injection because it causes more transactions and is too chatty. [Adlai Holler](https://github.com/Adlai-Holler)
- Optimize display node accessibility by not creating attributed & non-attributed copies of hint, label, and value. [Adlai Holler](https://github.com/Adlai-Holler)
- Add an experimental feature that reuses CTFramesetter objects in ASTextNode2 to improve performance. [Adlai Holler](https://github.com/Adlai-Holler)
- Add NS_DESIGNATED_INITIALIZER to ASViewController initWithNode: [Michael Schneider](https://github.com/maicki) [#1054](https://github.com/TextureGroup/Texture/pull/1054)
- Optimize text stack by removing unneeded copying. [Adlai Holler](https://github.com/Adlai-Holler)
- Renamed `accessibleElements` to `accessibilityElements` and removed the re-definition of the property in ASDisplayView. [Jia Wern Lim](https://github.com/jiawernlim)
- Remove double scaling of lineHeightMultiple & paragraphSpacing attributes in ASTextKitFontSizeAdjuster. [Eric Jensen](https://github.com/ejensen)
- Add a delegate callback for when the framework has initialized. [Adlai Holler](https://github.com/Adlai-Holler)
- Improve TextNode2 by skipping an unneeded copy during measurement. [Adlai Holler](https://github.com/Adlai-Holler)
- Improve locking around clearContents [Michael Schneider](https://github.com/maicki)
- Unlock before cleanup and calling out to subclass hooks for animated images. [Michael Schneider](https://github.com/maicki) [#1087](https://github.com/TextureGroup/Texture/pull/1087)
- [ASDisplayNode] Fix interface state update for layer backed nodes when layer thrashes (interface coaleascing case).[Max Wang](https://github.com/wsdwsd0829). [#1111](https://github.com/TextureGroup/Texture/pull/1111)
- [ASPINRemoteImageManager] Add a new API for setting a preconfigured PINRemoteImageManager. [Ernest Ma](https://github.com/ernestmama) [#1124](https://github.com/TextureGroup/Texture/pull/1124)
- Small optimization to the layout spec & yoga layout systems by eliminating array copies. [Adlai Holler](https://github.com/Adlai-Holler)
- Optimize layout process by removing `ASRectMap`. [Adlai Holler](https://github.com/Adlai-Holler)
- Remove necessity to use view to access rangeController in ASTableNode, ASCollectionNode. [Michael Schneider](https://github.com/maicki)
- Remove display node's reliance on shared_ptr. [Adlai Holler](https://github.com/Adlai-Holler)
- [ASCollectionView] Fix a crash that is caused by clearing a collection view's data while it's still being used. [Huy Nguyen](https://github.com/nguyenhuy) [#1154](https://github.com/TextureGroup/Texture/pull/1154)
- Clean up timing of layout tree flattening/ copying of unflattened tree for Weaver. [Michael Zuccarino](https://github.com/mikezucc) [#1157](https://github.com/TextureGroup/Texture/pull/1157)
## 2.7
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)
@@ -49,7 +93,8 @@
- Optimized ASNetworkImageNode loading and resolved edge cases where the image provided to the delegate was not the image that was loaded. [Adlai Holler](https://github.com/Adlai-Holler) [#778](https://github.com/TextureGroup/Texture/pull/778/)
- Make `ASCellNode` tint color apply to table view cell accessories. [Vladyslav Chapaev](https://github.com/ShogunPhyched) [#764](https://github.com/TextureGroup/Texture/pull/764)
- Fix ASTextNode2 is accessing backgroundColor off main while sizing / layout is happening. [Michael Schneider](https://github.com/maicki) [#794](https://github.com/TextureGroup/Texture/pull/778/)
- Pass scrollViewWillEndDragging delegation through in ASIGListAdapterDataSource for IGListKit integration. [#796](https://github.com/TextureGroup/Texture/pull/796)
- Pass scrollViewWillEndDragging delegation through in ASIGListAdapterDataSource for IGListKit integration. [#796](https://github.com/TextureGro
- up/Texture/pull/796)
- Fix UIResponder handling with view backing ASDisplayNode. [Michael Schneider](https://github.com/maicki) [#789](https://github.com/TextureGroup/Texture/pull/789/)
- Optimized thread-local storage by replacing pthread_specific with C11 thread-local variables. [Adlai Holler](https://github.com/Adlai-Holler) [#811](https://github.com/TextureGroup/Texture/pull/811/)
- Fixed a thread-sanitizer warning in ASTextNode. [Adlai Holler](https://github.com/Adlai-Holler) [#830](https://github.com/TextureGroup/Texture/pull/830/)

View File

@@ -87,12 +87,8 @@ Copy and paste this to the top of your new file(s):
// ASDisplayNode.mm
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
```
@@ -102,17 +98,9 @@ If youve modified an existing file, change the header to:
// ASDisplayNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
```

View File

@@ -69,13 +69,8 @@ end
# Ensure new files have proper header
new_source_license_header = <<-HEREDOC
// 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
//
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
HEREDOC
if has_added_source_files
@@ -84,18 +79,9 @@ end
# Ensure modified files have proper header
modified_source_license_header = <<-HEREDOC
// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
HEREDOC
if has_modified_source_files

12
LICENSE
View File

@@ -1,13 +1,7 @@
The Texture project was created by Pinterest as a continuation, under a
different name and license, of the AsyncDisplayKit codebase originally developed
by Facebook. AsyncDisplayKit was originally released by Facebook under a BSD
license and additional patent grant. Those BSD and patent licenses govern use
of code in Texture contributed prior to 4/13/2017 (the original AsyncDisplayKit
code), and copies of the licenses are included in the /ASDK-Licenses directory
of this source tree for reference.
The Texture project was created by Pinterest as a continuation, under a different
name and license, of the AsyncDisplayKit codebase originally developed by Facebook.
All code contributed to Texture after 4/13/2017 is released by Pinterest under
the Apache License, Version 2.0.
All code in Texture is covered by the Apache License, Version 2.0.
Apache License
Version 2.0, January 2004

View File

@@ -3,7 +3,7 @@ source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
target :'AsyncDisplayKitTests' do
pod 'OCMock', '~> 3.4'
pod 'OCMock', '=3.4.1' # 3.4.2 currently has issues.
pod 'FBSnapshotTestCase/Core', '~> 2.1'
pod 'JGMethodSwizzler', :git => 'https://github.com/JonasGessner/JGMethodSwizzler', :branch => 'master'

62
Podfile.lock Normal file
View File

@@ -0,0 +1,62 @@
PODS:
- FBSnapshotTestCase/Core (2.1.4)
- FLAnimatedImage (1.0.12)
- JGMethodSwizzler (2.0.1)
- OCMock (3.4.1)
- PINCache (3.0.1-beta.6):
- PINCache/Arc-exception-safe (= 3.0.1-beta.6)
- PINCache/Core (= 3.0.1-beta.6)
- PINCache/Arc-exception-safe (3.0.1-beta.6):
- PINCache/Core
- PINCache/Core (3.0.1-beta.6):
- PINOperation (~> 1.1.0)
- PINOperation (1.1.1)
- PINRemoteImage (3.0.0-beta.13):
- PINRemoteImage/FLAnimatedImage (= 3.0.0-beta.13)
- PINRemoteImage/PINCache (= 3.0.0-beta.13)
- PINRemoteImage/Core (3.0.0-beta.13):
- PINOperation
- PINRemoteImage/FLAnimatedImage (3.0.0-beta.13):
- FLAnimatedImage (>= 1.0)
- PINRemoteImage/Core
- PINRemoteImage/PINCache (3.0.0-beta.13):
- PINCache (= 3.0.1-beta.6)
- PINRemoteImage/Core
DEPENDENCIES:
- FBSnapshotTestCase/Core (~> 2.1)
- JGMethodSwizzler (from `https://github.com/JonasGessner/JGMethodSwizzler`, branch `master`)
- OCMock (= 3.4.1)
- PINRemoteImage (= 3.0.0-beta.13)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- FBSnapshotTestCase
- FLAnimatedImage
- OCMock
- PINCache
- PINOperation
- PINRemoteImage
EXTERNAL SOURCES:
JGMethodSwizzler:
:branch: master
:git: https://github.com/JonasGessner/JGMethodSwizzler
CHECKOUT OPTIONS:
JGMethodSwizzler:
:commit: 8791eccc5342224bd293b5867348657e3a240c7f
:git: https://github.com/JonasGessner/JGMethodSwizzler
SPEC CHECKSUMS:
FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a
FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31
JGMethodSwizzler: 7328146117fffa8a4038c42eb7cd3d4c75006f97
OCMock: 2cd0716969bab32a2283ff3a46fd26a8c8b4c5e3
PINCache: d195fdba255283f7e9900a55e3cced377f431f9b
PINOperation: a6219e6fc9db9c269eb7a7b871ac193bcf400aac
PINRemoteImage: d6d51c5d2adda55f1ce30c96e850b6c4ebd2856a
PODFILE CHECKSUM: 42715d61f73cc22cc116bf80d7b268cb1f9e4742
COCOAPODS: 1.5.3

View File

@@ -44,4 +44,4 @@ We welcome any contributions. See the [CONTRIBUTING](https://github.com/textureg
## License
The Texture project was created by Pinterest as a continuation, under a different name and license, of the AsyncDisplayKit codebase originally developed by Facebook. AsyncDisplayKit was originally released by Facebook under a BSD license and additional patent grant. Those BSD and patent licenses govern use of code in Texture contributed prior to 4/13/2017 (the original AsyncDisplayKit code), and copies of the licenses are included in the root directory of this source tree for reference. All code contributed to Texture after 4/13/2017 is released by Pinterest under an Apache 2.0 license.
The Texture project is available for free use, as described by the [LICENSE](https://github.com/texturegroup/texture/blob/master/LICENSE) (Apache 2.0).

View File

@@ -19,7 +19,10 @@
"exp_unfair_lock",
"exp_infer_layer_defaults",
"exp_network_image_queue",
"exp_dealloc_queue_v2"
"exp_dealloc_queue_v2",
"exp_collection_teardown",
"exp_framesetter_cache",
"exp_clear_data_during_deallocation"
]
}
}

View File

@@ -2,17 +2,9 @@
// ASBlockTypes.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>

View File

@@ -2,17 +2,9 @@
// ASButtonNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASControlNode.h>

View File

@@ -2,17 +2,9 @@
// ASButtonNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASButtonNode.h>

View File

@@ -2,12 +2,8 @@
// ASCGImageBuffer.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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>
@@ -25,7 +21,7 @@ AS_SUBCLASSING_RESTRICTED
@property (readonly) void *mutableBytes NS_RETURNS_INNER_POINTER;
/// Don't do any drawing or call any methods after calling this.
- (CGDataProviderRef)createDataProviderAndInvalidate;
- (CGDataProviderRef)createDataProviderAndInvalidate CF_RETURNS_RETAINED;
@end

View File

@@ -2,12 +2,8 @@
// ASCGImageBuffer.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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import "ASCGImageBuffer.h"

View File

@@ -2,17 +2,9 @@
// ASCellNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASCellNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASCollectionNode+Beta.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASCollectionNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASCollectionNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
@@ -39,9 +31,12 @@
#pragma mark - _ASCollectionPendingState
@interface _ASCollectionPendingState : NSObject
@property (weak, nonatomic) id <ASCollectionDelegate> delegate;
@property (weak, nonatomic) id <ASCollectionDataSource> dataSource;
@interface _ASCollectionPendingState : NSObject {
@public
std::vector<std::vector<ASRangeTuningParameters>> _tuningParameters;
}
@property (nonatomic, weak) id <ASCollectionDelegate> delegate;
@property (nonatomic, weak) id <ASCollectionDataSource> dataSource;
@property (nonatomic) UICollectionViewLayout *collectionViewLayout;
@property (nonatomic) ASLayoutRangeMode rangeMode;
@property (nonatomic) BOOL allowsSelection; // default is YES
@@ -49,7 +44,7 @@
@property (nonatomic) BOOL inverted; //default is NO
@property (nonatomic) BOOL usesSynchronousDataLoading;
@property (nonatomic) CGFloat leadingScreensForBatching;
@property (weak, nonatomic) id <ASCollectionViewLayoutInspecting> layoutInspector;
@property (nonatomic, weak) id <ASCollectionViewLayoutInspecting> layoutInspector;
@property (nonatomic) BOOL alwaysBounceVertical;
@property (nonatomic) BOOL alwaysBounceHorizontal;
@property (nonatomic) UIEdgeInsets contentInset;
@@ -61,11 +56,14 @@
@implementation _ASCollectionPendingState
#pragma mark Lifecycle
- (instancetype)init
{
self = [super init];
if (self) {
_rangeMode = ASLayoutRangeModeUnspecified;
_tuningParameters = std::vector<std::vector<ASRangeTuningParameters>> (ASLayoutRangeModeCount, std::vector<ASRangeTuningParameters> (ASLayoutRangeTypeCount, ASRangeTuningParametersZero));
_allowsSelection = YES;
_allowsMultipleSelection = NO;
_inverted = NO;
@@ -75,23 +73,8 @@
}
return self;
}
@end
// TODO: Add support for tuning parameters in the pending state
#if 0 // This is not used yet, but will provide a way to avoid creating the view to set range values.
@implementation _ASCollectionPendingState {
std::vector<std::vector<ASRangeTuningParameters>> _tuningParameters;
}
- (instancetype)init
{
self = [super init];
if (self) {
_tuningParameters = std::vector<std::vector<ASRangeTuningParameters>> (ASLayoutRangeModeCount, std::vector<ASRangeTuningParameters> (ASLayoutRangeTypeCount));
_rangeMode = ASLayoutRangeModeUnspecified;
}
return self;
}
#pragma mark Tuning Parameters
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
{
@@ -116,7 +99,6 @@
}
@end
#endif
#pragma mark - ASCollectionNode
@@ -127,6 +109,7 @@
id<ASBatchFetchingDelegate> _batchFetchingDelegate;
}
@property (nonatomic) _ASCollectionPendingState *pendingState;
@property (nonatomic, weak) ASRangeController *rangeController;
@end
@implementation ASCollectionNode
@@ -198,16 +181,20 @@
ASCollectionView *view = self.view;
view.collectionNode = self;
_rangeController = view.rangeController;
if (_pendingState) {
_ASCollectionPendingState *pendingState = _pendingState;
self.pendingState = nil;
view.asyncDelegate = pendingState.delegate;
view.asyncDataSource = pendingState.dataSource;
view.inverted = pendingState.inverted;
view.allowsSelection = pendingState.allowsSelection;
view.allowsMultipleSelection = pendingState.allowsMultipleSelection;
view.usesSynchronousDataLoading = pendingState.usesSynchronousDataLoading;
view.layoutInspector = pendingState.layoutInspector;
self.pendingState = nil;
view.asyncDelegate = pendingState.delegate;
view.asyncDataSource = pendingState.dataSource;
view.inverted = pendingState.inverted;
view.allowsSelection = pendingState.allowsSelection;
view.allowsMultipleSelection = pendingState.allowsMultipleSelection;
view.usesSynchronousDataLoading = pendingState.usesSynchronousDataLoading;
view.layoutInspector = pendingState.layoutInspector;
view.showsVerticalScrollIndicator = pendingState.showsVerticalScrollIndicator;
view.showsHorizontalScrollIndicator = pendingState.showsHorizontalScrollIndicator;
// Only apply these flags if they're enabled; the view might come with them turned on.
if (pendingState.alwaysBounceVertical) {
@@ -227,8 +214,23 @@
[view setContentOffset:contentOffset animated:pendingState.animatesContentOffset];
}
let tuningParametersVector = pendingState->_tuningParameters;
let tuningParametersVectorSize = tuningParametersVector.size();
for (NSInteger rangeMode = 0; rangeMode < tuningParametersVectorSize; rangeMode++) {
let tuningparametersRangeModeVector = tuningParametersVector[rangeMode];
let tuningParametersVectorRangeModeSize = tuningparametersRangeModeVector.size();
for (NSInteger rangeType = 0; rangeType < tuningParametersVectorRangeModeSize; rangeType++) {
ASRangeTuningParameters tuningParameters = tuningparametersRangeModeVector[rangeType];
if (!ASRangeTuningParametersEqualToRangeTuningParameters(tuningParameters, ASRangeTuningParametersZero)) {
[_rangeController setTuningParameters:tuningParameters
forRangeMode:(ASLayoutRangeMode)rangeMode
rangeType:(ASLayoutRangeType)rangeType];
}
}
}
if (pendingState.rangeMode != ASLayoutRangeModeUnspecified) {
[view.rangeController updateCurrentRangeWithMode:pendingState.rangeMode];
[_rangeController updateCurrentRangeWithMode:pendingState.rangeMode];
}
// Don't need to set collectionViewLayout to the view as the layout was already used to init the view in view block.
@@ -260,7 +262,7 @@
// We can get rid of this call later when ASDataController, ASRangeController and ASCollectionLayout can operate without the view.
// TODO (ASCL) If this node supports async layout, kick off the initial data load without allocating the view
if (ASHierarchyStateIncludesRangeManaged(self.hierarchyState) && CGRectEqualToRect(self.bounds, CGRectZero) == NO) {
[[self view] layoutIfNeeded];
[self.view layoutIfNeeded];
}
}
@@ -292,12 +294,6 @@
return self.view.dataController;
}
// TODO: Implement this without the view.
- (ASRangeController *)rangeController
{
return self.view.rangeController;
}
- (_ASCollectionPendingState *)pendingState
{
if (!_pendingState && ![self isNodeLoaded]) {
@@ -654,22 +650,30 @@
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
{
return [self.rangeController tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
return [self tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
}
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
{
[self.rangeController setTuningParameters:tuningParameters forRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
[self setTuningParameters:tuningParameters forRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
}
- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
{
return [self.rangeController tuningParametersForRangeMode:rangeMode rangeType:rangeType];
if ([self pendingState]) {
return [_pendingState tuningParametersForRangeMode:rangeMode rangeType:rangeType];
} else {
return [self.rangeController tuningParametersForRangeMode:rangeMode rangeType:rangeType];
}
}
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
{
return [self.rangeController setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType];
if ([self pendingState]) {
[_pendingState setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType];
} else {
return [self.rangeController setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType];
}
}
#pragma mark - Selection
@@ -817,7 +821,7 @@
[self.view registerSupplementaryNodeOfKind:elementKind];
}
- (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completion:(void (^)(BOOL))completion
- (void)performBatchAnimated:(BOOL)animated updates:(NS_NOESCAPE void (^)())updates completion:(void (^)(BOOL))completion
{
ASDisplayNodeAssertMainThread();
if (self.nodeLoaded) {
@@ -832,7 +836,7 @@
}
}
- (void)performBatchUpdates:(void (^)())updates completion:(void (^)(BOOL))completion
- (void)performBatchUpdates:(NS_NOESCAPE void (^)())updates completion:(void (^)(BOOL))completion
{
[self performBatchAnimated:UIView.areAnimationsEnabled updates:updates completion:completion];
}

View File

@@ -2,17 +2,9 @@
// ASCollectionView.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASCollectionView.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
#import <AsyncDisplayKit/ASAssert.h>
@@ -23,6 +15,7 @@
#import <AsyncDisplayKit/ASCollectionInternal.h>
#import <AsyncDisplayKit/ASCollectionLayout.h>
#import <AsyncDisplayKit/ASCollectionNode+Beta.h>
#import <AsyncDisplayKit/ASCollections.h>
#import <AsyncDisplayKit/ASCollectionViewLayoutController.h>
#import <AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h>
#import <AsyncDisplayKit/ASCollectionViewFlowLayoutInspector.h>
@@ -147,6 +140,12 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
*/
BOOL _hasEverCheckedForBatchFetchingDueToUpdate;
/**
* Set during beginInteractiveMovementForItemAtIndexPath and UIGestureRecognizerStateEnded
* (or UIGestureRecognizerStateFailed, UIGestureRecognizerStateCancelled.
*/
BOOL _reordering;
/**
* Counter used to keep track of nested batch updates.
*/
@@ -324,8 +323,10 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
// Sometimes the UIKit classes can call back to their delegate even during deallocation, due to animation completion blocks etc.
_isDeallocating = YES;
[self setAsyncDelegate:nil];
[self setAsyncDataSource:nil];
if (!ASActivateExperimentalFeature(ASExperimentalCollectionTeardown)) {
[self setAsyncDelegate:nil];
[self setAsyncDataSource:nil];
}
// Data controller & range controller may own a ton of nodes, let's deallocate those off-main.
ASPerformBackgroundDeallocation(&_dataController);
@@ -575,7 +576,8 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
- (void)_asyncDelegateOrDataSourceDidChange
{
ASDisplayNodeAssertMainThread();
if (_asyncDataSource == nil && _asyncDelegate == nil) {
if (_asyncDataSource == nil && _asyncDelegate == nil && _isDeallocating && ASActivateExperimentalFeature(ASExperimentalClearDataDuringDeallocation)) {
[_dataController clearData];
}
}
@@ -749,19 +751,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
- (NSArray<NSIndexPath *> *)convertIndexPathsToCollectionNode:(NSArray<NSIndexPath *> *)indexPaths
{
if (indexPaths == nil) {
return nil;
}
NSMutableArray<NSIndexPath *> *indexPathsArray = [NSMutableArray arrayWithCapacity:indexPaths.count];
for (NSIndexPath *indexPathInView in indexPaths) {
NSIndexPath *indexPath = [self convertIndexPathToCollectionNode:indexPathInView];
if (indexPath != nil) {
[indexPathsArray addObject:indexPath];
}
}
return indexPathsArray;
return ASArrayByFlatMapping(indexPaths, NSIndexPath *viewIndexPath, [self convertIndexPathToCollectionNode:viewIndexPath]);
}
- (ASCellNode *)supplementaryNodeForElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
@@ -931,7 +921,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
}
}
- (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completion:(void (^)(BOOL))completion
- (void)performBatchAnimated:(BOOL)animated updates:(NS_NOESCAPE void (^)())updates completion:(void (^)(BOOL))completion
{
ASDisplayNodeAssertMainThread();
[self beginUpdates];
@@ -946,7 +936,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
[self endUpdatesAnimated:animated completion:completion];
}
- (void)performBatchUpdates:(void (^)())updates completion:(void (^)(BOOL))completion
- (void)performBatchUpdates:(NS_NOESCAPE void (^)())updates completion:(void (^)(BOOL))completion
{
// We capture the current state of whether animations are enabled if they don't provide us with one.
[self performBatchAnimated:[UIView areAnimationsEnabled] updates:updates completion:completion];
@@ -1030,9 +1020,29 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
ASDisplayNodeAssertMainThread();
[self performBatchUpdates:^{
[_changeSet moveItemAtIndexPath:indexPath toIndexPath:newIndexPath animationOptions:kASCollectionViewAnimationNone];
} completion:nil];
if (!_reordering) {
[self performBatchUpdates:^{
[_changeSet moveItemAtIndexPath:indexPath toIndexPath:newIndexPath animationOptions:kASCollectionViewAnimationNone];
} completion:nil];
} else {
[super moveItemAtIndexPath:indexPath toIndexPath:newIndexPath];
}
}
- (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath {
BOOL success = [super beginInteractiveMovementForItemAtIndexPath:indexPath];
_reordering = success;
return success;
}
- (void)endInteractiveMovement {
_reordering = NO;
[super endInteractiveMovement];
}
- (void)cancelInteractiveMovement {
_reordering = NO;
[super cancelInteractiveMovement];
}
#pragma mark -
@@ -1554,7 +1564,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
// If the data source implements canMoveItem, let them decide.
if (_asyncDataSourceFlags.collectionNodeCanMoveItem) {
if (auto cellNode = [self nodeForItemAtIndexPath:indexPath]) {
if (let cellNode = [self nodeForItemAtIndexPath:indexPath]) {
GET_COLLECTIONNODE_OR_RETURN(collectionNode, NO);
return [_asyncDataSource collectionNode:collectionNode canMoveItemWithNode:cellNode];
}
@@ -1570,7 +1580,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
// Inform the data source first, in case they call nodeForItemAtIndexPath:.
// We want to make sure we return them the node for the item they have in mind.
if (auto collectionNode = self.collectionNode) {
if (let collectionNode = self.collectionNode) {
[_asyncDataSource collectionNode:collectionNode moveItemAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
}
@@ -2005,7 +2015,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
- (NSArray<NSString *> *)dataController:(ASDataController *)dataController supplementaryNodeKindsInSections:(NSIndexSet *)sections
{
if (_asyncDataSourceFlags.collectionNodeSupplementaryElementKindsInSection) {
auto kinds = [[NSMutableSet<NSString *> alloc] init];
let kinds = [[NSMutableSet<NSString *> alloc] init];
GET_COLLECTIONNODE_OR_RETURN(collectionNode, @[]);
[sections enumerateIndexesUsingBlock:^(NSUInteger section, BOOL * _Nonnull stop) {
NSArray<NSString *> *kindsForSection = [_asyncDataSource collectionNode:collectionNode supplementaryElementKindsInSection:section];
@@ -2223,13 +2233,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
return;
}
NSMutableArray<NSIndexPath *> *uikitIndexPaths = [NSMutableArray arrayWithCapacity:nodes.count];
for (ASCellNode *node in nodes) {
NSIndexPath *uikitIndexPath = [self indexPathForNode:node];
if (uikitIndexPath != nil) {
[uikitIndexPaths addObject:uikitIndexPath];
}
}
let uikitIndexPaths = ASArrayByFlatMapping(nodes, ASCellNode *node, [self indexPathForNode:node]);
[_layoutFacilitator collectionViewWillEditCellsAtIndexPaths:uikitIndexPaths batched:NO];

View File

@@ -2,17 +2,9 @@
// ASCollectionViewLayoutFacilitatorProtocol.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASCollectionViewProtocols.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

38
Source/ASCollections.h Normal file
View File

@@ -0,0 +1,38 @@
//
// ASCollections.h
// Texture
//
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSArray<__covariant ObjectType> (ASCollections)
/**
* Create an immutable NSArray from a C-array of strong pointers.
*
* Note: The memory for the array you pass in will be zero'd (to prevent ARC from releasing
* the references when the array goes out of scope.)
*
* Can be combined with vector like:
* vector<NSString *> vec;
* vec.push_back(@"foo");
* vec.push_back(@"bar");
* NSArray *arr = [NSArray arrayTransferring:vec.data() count:vec.size()]
* ** vec is now { nil, nil } **
*
* Unfortunately making a convenience method to do this is currently impossible because
* vector<NSString *> can't be converted to vector<id> by the compiler (silly).
*
* See the private __CFArrayCreateTransfer function.
*/
+ (NSArray<ObjectType> *)arrayByTransferring:(ObjectType _Nonnull __strong * _Nonnull)pointers
count:(NSUInteger)count NS_RETURNS_RETAINED;
@end
NS_ASSUME_NONNULL_END

61
Source/ASCollections.m Normal file
View File

@@ -0,0 +1,61 @@
//
// ASCollections.m
// Texture
//
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import "ASCollections.h"
/**
* A private allocator that signals to our retain callback to skip the retain.
* It behaves the same as the default allocator, but acts as a signal that we
* are creating a transfer array so we should skip the retain.
*/
static CFAllocatorRef gTransferAllocator;
static const void *ASTransferRetain(CFAllocatorRef allocator, const void *val) {
if (allocator == gTransferAllocator) {
// Transfer allocator. Ignore retain and pass through.
return val;
} else {
// Other allocator. Retain like normal.
// This happens when they make a mutable copy.
return (&kCFTypeArrayCallBacks)->retain(allocator, val);
}
}
@implementation NSArray (ASCollections)
+ (NSArray *)arrayByTransferring:(__strong id *)pointers count:(NSUInteger)count NS_RETURNS_RETAINED
{
// Custom callbacks that point to our ASTransferRetain callback.
static CFArrayCallBacks callbacks;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
callbacks = kCFTypeArrayCallBacks;
callbacks.retain = ASTransferRetain;
CFAllocatorContext ctx;
CFAllocatorGetContext(NULL, &ctx);
gTransferAllocator = CFAllocatorCreate(NULL, &ctx);
});
// NSZeroArray fast path.
if (count == 0) {
return @[]; // Does not actually call +array when optimized.
}
// NSSingleObjectArray fast path. Retain/release here is worth it.
if (count == 1) {
NSArray *result = [[NSArray alloc] initWithObjects:pointers count:1];
pointers[0] = nil;
return result;
}
NSArray *result = (__bridge_transfer NSArray *)CFArrayCreate(gTransferAllocator, (const void **)(void *)pointers, count, &callbacks);
memset(pointers, 0, count * sizeof(id));
return result;
}
@end

View File

@@ -2,12 +2,8 @@
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>

View File

@@ -2,12 +2,8 @@
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASConfiguration.h>
@@ -15,20 +11,21 @@
/// 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);
if (dictionary != nil) {
let featureStrings = ASDynamicCast(dictionary[@"experimental_features"], NSArray);
let version = ASDynamicCast(dictionary[@"version"], NSNumber).integerValue;
if (version != ASConfigurationSchemaCurrentVersion) {
NSLog(@"Texture warning: configuration schema is old version (%ld vs %ld)", (long)version, (long)ASConfigurationSchemaCurrentVersion);
}
self.experimentalFeatures = ASExperimentalFeaturesFromArray(featureStrings);
} else {
self.experimentalFeatures = kNilOptions;
}
self.experimentalFeatures = ASExperimentalFeaturesFromArray(featureStrings);
}
return self;
}

View File

@@ -2,12 +2,8 @@
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>
@@ -26,6 +22,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)textureDidActivateExperimentalFeatures:(ASExperimentalFeatures)features;
@optional
/**
* Texture framework initialized. This method is called synchronously
* on the main thread from ASInitializeFrameworkMainThread if you defined
* AS_INITIALIZE_FRAMEWORK_MANUALLY or from the default initialization point
* (currently +load) otherwise.
*/
- (void)textureDidInitialize;
@end
NS_ASSUME_NONNULL_END

View File

@@ -2,12 +2,8 @@
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
/// Note this has to be public because it's imported by public header ASThread.h =/
@@ -26,6 +22,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
AS_EXTERN BOOL ASActivateExperimentalFeature(ASExperimentalFeatures option);
/**
* Notify the configuration delegate that the framework initialized, if needed.
*/
AS_EXTERN void ASNotifyInitialized(void);
AS_SUBCLASSING_RESTRICTED
@interface ASConfigurationManager : NSObject

View File

@@ -2,15 +2,12 @@
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import "ASConfigurationInternal.h"
#import <AsyncDisplayKit/ASAssert.h>
#import <AsyncDisplayKit/ASConfiguration.h>
#import <AsyncDisplayKit/ASConfigurationDelegate.h>
#import <stdatomic.h>
@@ -20,6 +17,7 @@
@implementation ASConfigurationManager {
ASConfiguration *_config;
dispatch_queue_t _delegateQueue;
BOOL _frameworkInitialized;
_Atomic(ASExperimentalFeatures) _activatedExperiments;
}
@@ -55,6 +53,21 @@
return self;
}
- (void)frameworkDidInitialize
{
ASDisplayNodeAssertMainThread();
if (_frameworkInitialized) {
ASDisplayNodeFailAssert(@"Framework initialized twice.");
return;
}
_frameworkInitialized = YES;
let delegate = _config.delegate;
if ([delegate respondsToSelector:@selector(textureDidInitialize)]) {
[delegate textureDidInitialize];
}
}
- (BOOL)activateExperimentalFeature:(ASExperimentalFeatures)requested
{
if (_config == nil) {
@@ -94,3 +107,8 @@ BOOL ASActivateExperimentalFeature(ASExperimentalFeatures feature)
{
return [ASGetSharedConfigMgr() activateExperimentalFeature:feature];
}
void ASNotifyInitialized()
{
[ASGetSharedConfigMgr() frameworkDidInitialize];
}

View File

@@ -2,17 +2,9 @@
// ASContextTransitioning.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDimension.h>

View File

@@ -2,17 +2,9 @@
// ASControlNode+Subclasses.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASControlNode.h>

View File

@@ -2,17 +2,9 @@
// ASControlNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNode.h>

View File

@@ -2,17 +2,9 @@
// ASControlNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASControlNode.h>
@@ -303,7 +295,9 @@ CGRect _ASControlNodeGetExpandedBounds(ASControlNode *controlNode);
// only show tap-able areas for views with 1 or more addTarget:action: pairs
if ([ASControlNode enableHitTestDebug] && _debugHighlightOverlay == nil) {
ASPerformBlockOnMainThread(^{
// do not use ASPerformBlockOnMainThread here, if it performs the block synchronously it will continue
// holding the lock while calling addSubnode.
dispatch_async(dispatch_get_main_queue(), ^{
// add a highlight overlay node with area of ASControlNode + UIEdgeInsets
self.clipsToBounds = NO;
_debugHighlightOverlay = [[ASImageNode alloc] init];

View File

@@ -2,17 +2,9 @@
// ASDisplayNode+Beta.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASAvailability.h>

View File

@@ -2,17 +2,9 @@
// ASDisplayNode+Convenience.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNode.h>

View File

@@ -2,17 +2,9 @@
// ASDisplayNode+Convenience.m
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import "ASDisplayNode+Convenience.h"

View File

@@ -0,0 +1,119 @@
//
// ASDisplayNode+InterfaceState.h
// Texture
//
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>
/**
* Interface state is available on ASDisplayNode and ASViewController, and
* allows checking whether a node is in an interface situation where it is prudent to trigger certain
* actions: measurement, data loading, display, and visibility (the latter for animations or other onscreen-only effects).
*
* The defualt state, ASInterfaceStateNone, means that the element is not predicted to be onscreen soon and
* preloading should not be performed. Swift: use [] for the default behavior.
*/
typedef NS_OPTIONS(NSUInteger, ASInterfaceState)
{
/** The element is not predicted to be onscreen soon and preloading should not be performed */
ASInterfaceStateNone = 0,
/** The element may be added to a view soon that could become visible. Measure the layout, including size calculation. */
ASInterfaceStateMeasureLayout = 1 << 0,
/** The element is likely enough to come onscreen that disk and/or network data required for display should be fetched. */
ASInterfaceStatePreload = 1 << 1,
/** The element is very likely to become visible, and concurrent rendering should be executed for any -setNeedsDisplay. */
ASInterfaceStateDisplay = 1 << 2,
/** The element is physically onscreen by at least 1 pixel.
In practice, all other bit fields should also be set when this flag is set. */
ASInterfaceStateVisible = 1 << 3,
/**
* The node is not contained in a cell but it is in a window.
*
* Currently we only set `interfaceState` to other values for
* nodes contained in table views or collection views.
*/
ASInterfaceStateInHierarchy = ASInterfaceStateMeasureLayout | ASInterfaceStatePreload | ASInterfaceStateDisplay | ASInterfaceStateVisible,
};
@protocol ASInterfaceStateDelegate <NSObject>
/**
* @abstract Called whenever any bit in the ASInterfaceState bitfield is changed.
* @discussion Subclasses may use this to monitor when they become visible, should free cached data, and much more.
* @see ASInterfaceState
*/
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState;
/**
* @abstract Called whenever the node becomes visible.
* @discussion Subclasses may use this to monitor when they become visible.
* @note This method is guaranteed to be called on main.
*/
- (void)didEnterVisibleState;
/**
* @abstract Called whenever the node is no longer visible.
* @discussion Subclasses may use this to monitor when they are no longer visible.
* @note This method is guaranteed to be called on main.
*/
- (void)didExitVisibleState;
/**
* @abstract Called whenever the the node has entered the display state.
* @discussion Subclasses may use this to monitor when a node should be rendering its content.
* @note This method is guaranteed to be called on main.
*/
- (void)didEnterDisplayState;
/**
* @abstract Called whenever the the node has exited the display state.
* @discussion Subclasses may use this to monitor when a node should no longer be rendering its content.
* @note This method is guaranteed to be called on main.
*/
- (void)didExitDisplayState;
/**
* @abstract Called whenever the the node has entered the preload state.
* @discussion Subclasses may use this to monitor data for a node should be preloaded, either from a local or remote source.
* @note This method is guaranteed to be called on main.
*/
- (void)didEnterPreloadState;
/**
* @abstract Called whenever the the node has exited the preload state.
* @discussion Subclasses may use this to monitor whether preloading data for a node should be canceled.
* @note This method is guaranteed to be called on main.
*/
- (void)didExitPreloadState;
/**
* @abstract Called when the node has completed applying the layout.
* @discussion Can be used for operations that are performed after layout has completed.
* @note This method is guaranteed to be called on main.
*/
- (void)nodeDidLayout;
/**
* @abstract Called when the node loads.
* @discussion Can be used for operations that are performed after the node's view is available.
* @note This method is guaranteed to be called on main.
*/
- (void)nodeDidLoad;
/**
* @abstract Indicates that the receiver and all subnodes have finished displaying.
* @discussion May be called more than once, for example if the receiver has a network image node.
* This is called after the first display pass even if network image nodes have not downloaded anything
* (text would be done, and other nodes that are ready to do their final display). Each render of
* every progressive jpeg network node would cause this to be called, so this hook could be called up to
* 1 + (pJPEGcount * pJPEGrenderCount) times. The render count depends on how many times the downloader calls
* the progressImage block.
* @note This method is guaranteed to be called on main.
*/
- (void)hierarchyDisplayDidFinish;
@end

View File

@@ -2,17 +2,9 @@
// ASDisplayNode+Layout.mm
// 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 /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
//
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
@@ -82,19 +74,19 @@
ASLayout *layout = nil;
NSUInteger version = _layoutVersion;
if (_calculatedDisplayNodeLayout->isValid(constrainedSize, parentSize, version)) {
ASDisplayNodeAssertNotNil(_calculatedDisplayNodeLayout->layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _calculatedDisplayNodeLayout->layout should not be nil! %@", self);
layout = _calculatedDisplayNodeLayout->layout;
} else if (_pendingDisplayNodeLayout != nullptr && _pendingDisplayNodeLayout->isValid(constrainedSize, parentSize, version)) {
ASDisplayNodeAssertNotNil(_pendingDisplayNodeLayout->layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _pendingDisplayNodeLayout->layout should not be nil! %@", self);
layout = _pendingDisplayNodeLayout->layout;
if (_calculatedDisplayNodeLayout.isValid(constrainedSize, parentSize, version)) {
ASDisplayNodeAssertNotNil(_calculatedDisplayNodeLayout.layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _calculatedDisplayNodeLayout.layout should not be nil! %@", self);
layout = _calculatedDisplayNodeLayout.layout;
} else if (_pendingDisplayNodeLayout.isValid(constrainedSize, parentSize, version)) {
ASDisplayNodeAssertNotNil(_pendingDisplayNodeLayout.layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _pendingDisplayNodeLayout.layout should not be nil! %@", self);
layout = _pendingDisplayNodeLayout.layout;
} else {
// Create a pending display node layout for the layout pass
layout = [self calculateLayoutThatFits:constrainedSize
restrictedToSize:self.style.size
relativeToParentSize:parentSize];
as_log_verbose(ASLayoutLog(), "Established pending layout for %@ in %s", self, sel_getName(_cmd));
_pendingDisplayNodeLayout = std::make_shared<ASDisplayNodeLayout>(layout, constrainedSize, parentSize, version);
_pendingDisplayNodeLayout = ASDisplayNodeLayout(layout, constrainedSize, parentSize,version);
ASDisplayNodeAssertNotNil(layout, @"-[ASDisplayNode layoutThatFits:parentSize:] newly calculated layout should not be nil! %@", self);
}
@@ -168,16 +160,16 @@ ASLayoutElementStyleExtensibilityForwarding
- (ASLayout *)calculatedLayout
{
ASDN::MutexLocker l(__instanceLock__);
return _calculatedDisplayNodeLayout->layout;
return _calculatedDisplayNodeLayout.layout;
}
- (CGSize)calculatedSize
{
ASDN::MutexLocker l(__instanceLock__);
if (_pendingDisplayNodeLayout != nullptr && _pendingDisplayNodeLayout->isValid(_layoutVersion)) {
return _pendingDisplayNodeLayout->layout.size;
if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) {
return _pendingDisplayNodeLayout.layout.size;
}
return _calculatedDisplayNodeLayout->layout.size;
return _calculatedDisplayNodeLayout.layout.size;
}
- (ASSizeRange)constrainedSizeForCalculatedLayout
@@ -188,10 +180,11 @@ ASLayoutElementStyleExtensibilityForwarding
- (ASSizeRange)_locked_constrainedSizeForCalculatedLayout
{
if (_pendingDisplayNodeLayout != nullptr && _pendingDisplayNodeLayout->isValid(_layoutVersion)) {
return _pendingDisplayNodeLayout->constrainedSize;
ASAssertLocked(__instanceLock__);
if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) {
return _pendingDisplayNodeLayout.constrainedSize;
}
return _calculatedDisplayNodeLayout->constrainedSize;
return _calculatedDisplayNodeLayout.constrainedSize;
}
@end
@@ -222,9 +215,10 @@ ASLayoutElementStyleExtensibilityForwarding
*/
- (void)_u_setNeedsLayoutFromAbove
{
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock);
as_activity_create_for_scope("Set needs layout from above");
ASDisplayNodeAssertThreadAffinity(self);
ASAssertUnlocked(__instanceLock__);
as_activity_create_for_scope("Set needs layout from above");
// Mark the node for layout in the next layout pass
[self setNeedsLayout];
@@ -247,7 +241,7 @@ ASLayoutElementStyleExtensibilityForwarding
- (void)_rootNodeDidInvalidateSize
{
ASDisplayNodeAssertThreadAffinity(self);
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
__instanceLock__.lock();
@@ -256,10 +250,10 @@ ASLayoutElementStyleExtensibilityForwarding
// Figure out constrainedSize to use
ASSizeRange constrainedSize = ASSizeRangeMake(boundsSizeForLayout);
if (_pendingDisplayNodeLayout != nullptr) {
constrainedSize = _pendingDisplayNodeLayout->constrainedSize;
} else if (_calculatedDisplayNodeLayout->layout != nil) {
constrainedSize = _calculatedDisplayNodeLayout->constrainedSize;
if (_pendingDisplayNodeLayout.layout != nil) {
constrainedSize = _pendingDisplayNodeLayout.constrainedSize;
} else if (_calculatedDisplayNodeLayout.layout != nil) {
constrainedSize = _calculatedDisplayNodeLayout.constrainedSize;
}
__instanceLock__.unlock();
@@ -277,7 +271,7 @@ ASLayoutElementStyleExtensibilityForwarding
- (void)displayNodeDidInvalidateSizeNewSize:(CGSize)size
{
ASDisplayNodeAssertThreadAffinity(self);
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
// The default implementation of display node changes the size of itself to the new size
CGRect oldBounds = self.bounds;
@@ -299,139 +293,158 @@ ASLayoutElementStyleExtensibilityForwarding
- (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds
{
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock);
ASDN::MutexLocker l(__instanceLock__);
// Check if we are a subnode in a layout transition.
// In this case no measurement is needed as it's part of the layout transition
if ([self _isLayoutTransitionInvalid]) {
return;
}
ASAssertUnlocked(__instanceLock__);
CGSize boundsSizeForLayout = ASCeilSizeValues(bounds.size);
// Prefer a newer and not yet applied _pendingDisplayNodeLayout over _calculatedDisplayNodeLayout
// If there is no such _pending, check if _calculated is valid to reuse (avoiding recalculation below).
BOOL pendingLayoutIsPreferred = NO;
if (_pendingDisplayNodeLayout != nullptr && _pendingDisplayNodeLayout->isValid(_layoutVersion)) {
NSUInteger calculatedVersion = _calculatedDisplayNodeLayout->version;
NSUInteger pendingVersion = _pendingDisplayNodeLayout->version;
if (pendingVersion > calculatedVersion) {
pendingLayoutIsPreferred = YES; // Newer _pending
} else if (pendingVersion == calculatedVersion
&& !ASSizeRangeEqualToSizeRange(_pendingDisplayNodeLayout->constrainedSize,
_calculatedDisplayNodeLayout->constrainedSize)) {
pendingLayoutIsPreferred = YES; // _pending with a different constrained size
BOOL isInLayoutPendingState = NO;
{
ASDN::MutexLocker l(__instanceLock__);
// Check if we are a subnode in a layout transition.
// In this case no measurement is needed as it's part of the layout transition
if ([self _locked_isLayoutTransitionInvalid]) {
return;
}
CGSize boundsSizeForLayout = ASCeilSizeValues(bounds.size);
// Prefer a newer and not yet applied _pendingDisplayNodeLayout over _calculatedDisplayNodeLayout
// If there is no such _pending, check if _calculated is valid to reuse (avoiding recalculation below).
BOOL pendingLayoutIsPreferred = NO;
if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) {
NSUInteger calculatedVersion = _calculatedDisplayNodeLayout.version;
NSUInteger pendingVersion = _pendingDisplayNodeLayout.version;
if (pendingVersion > calculatedVersion) {
pendingLayoutIsPreferred = YES; // Newer _pending
} else if (pendingVersion == calculatedVersion
&& !ASSizeRangeEqualToSizeRange(_pendingDisplayNodeLayout.constrainedSize,
_calculatedDisplayNodeLayout.constrainedSize)) {
pendingLayoutIsPreferred = YES; // _pending with a different constrained size
}
}
BOOL calculatedLayoutIsReusable = (_calculatedDisplayNodeLayout.isValid(_layoutVersion)
&& (_calculatedDisplayNodeLayout.requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout.layout.size, boundsSizeForLayout)));
if (!pendingLayoutIsPreferred && calculatedLayoutIsReusable) {
return;
}
as_activity_create_for_scope("Update node layout for current bounds");
as_log_verbose(ASLayoutLog(), "Node %@, bounds size %@, calculatedSize %@, calculatedIsDirty %d",
self,
NSStringFromCGSize(boundsSizeForLayout),
NSStringFromCGSize(_calculatedDisplayNodeLayout->layout.size),
_calculatedDisplayNodeLayout->version < _layoutVersion);
// _calculatedDisplayNodeLayout is not reusable we need to transition to a new one
[self cancelLayoutTransition];
BOOL didCreateNewContext = NO;
ASLayoutElementContext *context = ASLayoutElementGetCurrentContext();
if (context == nil) {
context = [[ASLayoutElementContext alloc] init];
ASLayoutElementPushContext(context);
didCreateNewContext = YES;
}
// Figure out previous and pending layouts for layout transition
ASDisplayNodeLayout nextLayout = _pendingDisplayNodeLayout;
#define layoutSizeDifferentFromBounds !CGSizeEqualToSize(nextLayout.layout.size, boundsSizeForLayout)
// nextLayout was likely created by a call to layoutThatFits:, check if it is valid and can be applied.
// If our bounds size is different than it, or invalid, recalculate. Use #define to avoid nullptr->
BOOL pendingLayoutApplicable = NO;
if (nextLayout.layout == nil) {
as_log_verbose(ASLayoutLog(), "No pending layout.");
} else if (!nextLayout.isValid(_layoutVersion)) {
as_log_verbose(ASLayoutLog(), "Pending layout is stale.");
} else if (layoutSizeDifferentFromBounds) {
as_log_verbose(ASLayoutLog(), "Pending layout size %@ doesn't match bounds size.", NSStringFromCGSize(nextLayout->layout.size));
} else {
as_log_verbose(ASLayoutLog(), "Using pending layout %@.", nextLayout->layout);
pendingLayoutApplicable = YES;
}
if (!pendingLayoutApplicable) {
as_log_verbose(ASLayoutLog(), "Measuring with previous constrained size.");
// Use the last known constrainedSize passed from a parent during layout (if never, use bounds).
NSUInteger version = _layoutVersion;
ASSizeRange constrainedSize = [self _locked_constrainedSizeForLayoutPass];
ASLayout *layout = [self calculateLayoutThatFits:constrainedSize
restrictedToSize:self.style.size
relativeToParentSize:boundsSizeForLayout];
nextLayout = ASDisplayNodeLayout(layout, constrainedSize, boundsSizeForLayout, version);
// Now that the constrained size of pending layout might have been reused, the layout is useless
// Release it and any orphaned subnodes it retains
_pendingDisplayNodeLayout.layout = nil;
}
if (didCreateNewContext) {
ASLayoutElementPopContext();
}
// If our new layout's desired size for self doesn't match current size, ask our parent to update it.
// This can occur for either pre-calculated or newly-calculated layouts.
if (nextLayout.requestedLayoutFromAbove == NO
&& CGSizeEqualToSize(boundsSizeForLayout, nextLayout.layout.size) == NO) {
as_log_verbose(ASLayoutLog(), "Layout size doesn't match bounds size. Requesting layout from above.");
// The layout that we have specifies that this node (self) would like to be a different size
// than it currently is. Because that size has been computed within the constrainedSize, we
// expect that calling setNeedsLayoutFromAbove will result in our parent resizing us to this.
// However, in some cases apps may manually interfere with this (setting a different bounds).
// In this case, we need to detect that we've already asked to be resized to match this
// particular ASLayout object, and shouldn't loop asking again unless we have a different ASLayout.
nextLayout.requestedLayoutFromAbove = YES;
{
ASDN::MutexUnlocker u(__instanceLock__);
[self _u_setNeedsLayoutFromAbove];
}
// Update the layout's version here because _u_setNeedsLayoutFromAbove calls __setNeedsLayout which in turn increases _layoutVersion
// Failing to do this will cause the layout to be invalid immediately
nextLayout.version = _layoutVersion;
}
// Prepare to transition to nextLayout
ASDisplayNodeAssertNotNil(nextLayout.layout, @"nextLayout->layout should not be nil! %@", self);
_pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self
pendingLayout:nextLayout
previousLayout:_calculatedDisplayNodeLayout];
isInLayoutPendingState = ASHierarchyStateIncludesLayoutPending(_hierarchyState);
}
BOOL calculatedLayoutIsReusable = (_calculatedDisplayNodeLayout->isValid(_layoutVersion)
&& (_calculatedDisplayNodeLayout->requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout->layout.size, boundsSizeForLayout)));
if (!pendingLayoutIsPreferred && calculatedLayoutIsReusable) {
return;
}
as_activity_create_for_scope("Update node layout for current bounds");
as_log_verbose(ASLayoutLog(), "Node %@, bounds size %@, calculatedSize %@, calculatedIsDirty %d", self, NSStringFromCGSize(boundsSizeForLayout), NSStringFromCGSize(_calculatedDisplayNodeLayout->layout.size), _calculatedDisplayNodeLayout->version < _layoutVersion.load());
// _calculatedDisplayNodeLayout is not reusable we need to transition to a new one
[self cancelLayoutTransition];
BOOL didCreateNewContext = NO;
ASLayoutElementContext *context = ASLayoutElementGetCurrentContext();
if (context == nil) {
context = [[ASLayoutElementContext alloc] init];
ASLayoutElementPushContext(context);
didCreateNewContext = YES;
}
// Figure out previous and pending layouts for layout transition
std::shared_ptr<ASDisplayNodeLayout> nextLayout = _pendingDisplayNodeLayout;
#define layoutSizeDifferentFromBounds !CGSizeEqualToSize(nextLayout->layout.size, boundsSizeForLayout)
// nextLayout was likely created by a call to layoutThatFits:, check if it is valid and can be applied.
// If our bounds size is different than it, or invalid, recalculate. Use #define to avoid nullptr->
BOOL pendingLayoutApplicable = NO;
if (nextLayout == nullptr) {
as_log_verbose(ASLayoutLog(), "No pending layout.");
} else if (nextLayout->version < _layoutVersion) {
as_log_verbose(ASLayoutLog(), "Pending layout is stale.");
} else if (layoutSizeDifferentFromBounds) {
as_log_verbose(ASLayoutLog(), "Pending layout size %@ doesn't match bounds size.", NSStringFromCGSize(nextLayout->layout.size));
} else {
as_log_verbose(ASLayoutLog(), "Using pending layout %@.", nextLayout->layout);
pendingLayoutApplicable = YES;
}
if (!pendingLayoutApplicable) {
as_log_verbose(ASLayoutLog(), "Measuring with previous constrained size.");
// Use the last known constrainedSize passed from a parent during layout (if never, use bounds).
NSUInteger version = _layoutVersion;
ASSizeRange constrainedSize = [self _locked_constrainedSizeForLayoutPass];
ASLayout *layout = [self calculateLayoutThatFits:constrainedSize
restrictedToSize:self.style.size
relativeToParentSize:boundsSizeForLayout];
nextLayout = std::make_shared<ASDisplayNodeLayout>(layout, constrainedSize, boundsSizeForLayout, version);
// Now that the constrained size of pending layout might have been reused, the layout is useless
// Release it and any orphaned subnodes it retains
_pendingDisplayNodeLayout = nullptr;
}
if (didCreateNewContext) {
ASLayoutElementPopContext();
}
// If our new layout's desired size for self doesn't match current size, ask our parent to update it.
// This can occur for either pre-calculated or newly-calculated layouts.
if (nextLayout->requestedLayoutFromAbove == NO
&& CGSizeEqualToSize(boundsSizeForLayout, nextLayout->layout.size) == NO) {
as_log_verbose(ASLayoutLog(), "Layout size doesn't match bounds size. Requesting layout from above.");
// The layout that we have specifies that this node (self) would like to be a different size
// than it currently is. Because that size has been computed within the constrainedSize, we
// expect that calling setNeedsLayoutFromAbove will result in our parent resizing us to this.
// However, in some cases apps may manually interfere with this (setting a different bounds).
// In this case, we need to detect that we've already asked to be resized to match this
// particular ASLayout object, and shouldn't loop asking again unless we have a different ASLayout.
nextLayout->requestedLayoutFromAbove = YES;
__instanceLock__.unlock();
[self _u_setNeedsLayoutFromAbove];
__instanceLock__.lock();
// Update the layout's version here because _u_setNeedsLayoutFromAbove calls __setNeedsLayout which in turn increases _layoutVersion
// Failing to do this will cause the layout to be invalid immediately
nextLayout->version = _layoutVersion;
}
// Prepare to transition to nextLayout
ASDisplayNodeAssertNotNil(nextLayout->layout, @"nextLayout->layout should not be nil! %@", self);
_pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self
pendingLayout:nextLayout
previousLayout:_calculatedDisplayNodeLayout];
// If a parent is currently executing a layout transition, perform our layout application after it.
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState) == NO) {
if (isInLayoutPendingState == NO) {
// If no transition, apply our new layout immediately (common case).
[self _completePendingLayoutTransition];
}
}
- (ASSizeRange)_constrainedSizeForLayoutPass
{
ASDN::MutexLocker l(__instanceLock__);
return [self _locked_constrainedSizeForLayoutPass];
}
- (ASSizeRange)_locked_constrainedSizeForLayoutPass
{
// TODO: The logic in -_u_setNeedsLayoutFromAbove seems correct and doesn't use this method.
// logic seems correct. For what case does -this method need to do the CGSizeEqual checks?
// IF WE CAN REMOVE BOUNDS CHECKS HERE, THEN WE CAN ALSO REMOVE "REQUESTED FROM ABOVE" CHECK
ASAssertLocked(__instanceLock__);
CGSize boundsSizeForLayout = ASCeilSizeValues(self.threadSafeBounds.size);
// Checkout if constrained size of pending or calculated display node layout can be used
if (_pendingDisplayNodeLayout != nullptr
&& (_pendingDisplayNodeLayout->requestedLayoutFromAbove
|| CGSizeEqualToSize(_pendingDisplayNodeLayout->layout.size, boundsSizeForLayout))) {
if (_pendingDisplayNodeLayout.requestedLayoutFromAbove
|| CGSizeEqualToSize(_pendingDisplayNodeLayout.layout.size, boundsSizeForLayout)) {
// We assume the size from the last returned layoutThatFits: layout was applied so use the pending display node
// layout constrained size
return _pendingDisplayNodeLayout->constrainedSize;
} else if (_calculatedDisplayNodeLayout->layout != nil
&& (_calculatedDisplayNodeLayout->requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout->layout.size, boundsSizeForLayout))) {
return _pendingDisplayNodeLayout.constrainedSize;
} else if (_calculatedDisplayNodeLayout.layout != nil
&& (_calculatedDisplayNodeLayout.requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout.layout.size, boundsSizeForLayout))) {
// We assume the _calculatedDisplayNodeLayout is still valid and the frame is not different
return _calculatedDisplayNodeLayout->constrainedSize;
return _calculatedDisplayNodeLayout.constrainedSize;
} else {
// In this case neither the _pendingDisplayNodeLayout or the _calculatedDisplayNodeLayout constrained size can
// be reused, so the current bounds is used. This is usual the case if a frame was set manually that differs to
@@ -443,15 +456,15 @@ ASLayoutElementStyleExtensibilityForwarding
- (void)_layoutSublayouts
{
ASDisplayNodeAssertThreadAffinity(self);
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
ASLayout *layout;
{
ASDN::MutexLocker l(__instanceLock__);
if (_calculatedDisplayNodeLayout->version < _layoutVersion) {
if (_calculatedDisplayNodeLayout.version < _layoutVersion) {
return;
}
layout = _calculatedDisplayNodeLayout->layout;
layout = _calculatedDisplayNodeLayout.layout;
}
for (ASDisplayNode *node in self.subnodes) {
@@ -502,6 +515,7 @@ ASLayoutElementStyleExtensibilityForwarding
- (BOOL)_locked_isLayoutTransitionInvalid
{
ASAssertLocked(__instanceLock__);
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState)) {
ASLayoutElementContext *context = ASLayoutElementGetCurrentContext();
if (context == nil || _pendingTransitionID != context.transitionID) {
@@ -534,18 +548,10 @@ ASLayoutElementStyleExtensibilityForwarding
measurementCompletion:(void(^)())completion
{
ASDisplayNodeAssertMainThread();
ASSizeRange sizeRange;
{
ASDN::MutexLocker l(__instanceLock__);
sizeRange = [self _locked_constrainedSizeForLayoutPass];
}
[self transitionLayoutWithSizeRange:sizeRange
[self transitionLayoutWithSizeRange:[self _constrainedSizeForLayoutPass]
animated:animated
shouldMeasureAsync:shouldMeasureAsync
measurementCompletion:completion];
}
- (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
@@ -650,11 +656,11 @@ ASLayoutElementStyleExtensibilityForwarding
ASDN::MutexLocker l(__instanceLock__);
// Update calculated layout
auto previousLayout = _calculatedDisplayNodeLayout;
auto pendingLayout = std::make_shared<ASDisplayNodeLayout>(newLayout,
constrainedSize,
constrainedSize.max,
newLayoutVersion);
let previousLayout = _calculatedDisplayNodeLayout;
let pendingLayout = ASDisplayNodeLayout(newLayout,
constrainedSize,
constrainedSize.max,
newLayoutVersion);
[self _locked_setCalculatedDisplayNodeLayout:pendingLayout];
// Setup pending layout transition for animation
@@ -684,7 +690,7 @@ ASLayoutElementStyleExtensibilityForwarding
}
// Apply the subnode insertion immediately to be able to animate the nodes
[pendingLayoutTransition applySubnodeInsertions];
[pendingLayoutTransition applySubnodeInsertionsAndMoves];
// Kick off animating the layout transition
{
@@ -771,10 +777,10 @@ ASLayoutElementStyleExtensibilityForwarding
NSArray<ASDisplayNode *> *removedSubnodes = [context removedSubnodes];
NSMutableArray<ASDisplayNode *> *insertedSubnodes = [[context insertedSubnodes] mutableCopy];
auto movedSubnodes = [[NSMutableArray<ASDisplayNode *> alloc] init];
let movedSubnodes = [[NSMutableArray<ASDisplayNode *> alloc] init];
auto insertedSubnodeContexts = [[NSMutableArray<_ASAnimatedTransitionContext *> alloc] init];
auto removedSubnodeContexts = [[NSMutableArray<_ASAnimatedTransitionContext *> alloc] init];
let insertedSubnodeContexts = [[NSMutableArray<_ASAnimatedTransitionContext *> alloc] init];
let removedSubnodeContexts = [[NSMutableArray<_ASAnimatedTransitionContext *> alloc] init];
for (ASDisplayNode *subnode in [context subnodesForKey:ASTransitionContextToLayoutKey]) {
if ([insertedSubnodes containsObject:subnode] == NO) {
@@ -864,12 +870,18 @@ ASLayoutElementStyleExtensibilityForwarding
*/
- (void)_completePendingLayoutTransition
{
__instanceLock__.lock();
ASLayoutTransition *pendingLayoutTransition = _pendingLayoutTransition;
__instanceLock__.unlock();
ASAssertUnlocked(__instanceLock__);
ASLayoutTransition *pendingLayoutTransition;
{
ASDN::MutexLocker l(__instanceLock__);
pendingLayoutTransition = _pendingLayoutTransition;
if (pendingLayoutTransition != nil) {
[self _locked_setCalculatedDisplayNodeLayout:pendingLayoutTransition.pendingLayout];
}
}
if (pendingLayoutTransition != nil) {
[self _setCalculatedDisplayNodeLayout:pendingLayoutTransition.pendingLayout];
[self _completeLayoutTransition:pendingLayoutTransition];
[self _pendingLayoutTransitionDidComplete];
}
@@ -888,6 +900,8 @@ ASLayoutElementStyleExtensibilityForwarding
// Trampoline to the main thread if necessary
if (ASDisplayNodeThreadIsMain() || layoutTransition.isSynchronous == NO) {
// Committing the layout transition will result in subnode insertions and removals, both of which must be called without the lock held
ASAssertUnlocked(__instanceLock__);
[layoutTransition commitTransition];
} else {
// Subnode insertions and removals need to happen always on the main thread if at least one subnode is already loaded
@@ -907,11 +921,11 @@ ASLayoutElementStyleExtensibilityForwarding
}
NSArray *subnodes = [self subnodes];
NSArray *sublayouts = _calculatedDisplayNodeLayout->layout.sublayouts;
NSArray *sublayouts = _calculatedDisplayNodeLayout.layout.sublayouts;
auto currentSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality
let currentSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality
capacity:subnodes.count];
auto layoutSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality
let layoutSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality
capacity:sublayouts.count];;
for (ASDisplayNode *subnode in subnodes) {
[currentSubnodes addObject:subnode];
@@ -941,12 +955,13 @@ ASLayoutElementStyleExtensibilityForwarding
- (void)_pendingLayoutTransitionDidComplete
{
// This assertion introduces a breaking behavior for nodes that has ASM enabled but also manually manage some subnodes.
// Let's gate it behind YOGA flag and remove it right after a branch cut.
// Let's gate it behind YOGA flag.
#if YOGA
[self _assertSubnodeState];
#endif
// Subclass hook
ASAssertUnlocked(__instanceLock__);
[self calculatedLayoutDidChange];
// Grab lock after calling out to subclass
@@ -958,8 +973,7 @@ ASLayoutElementStyleExtensibilityForwarding
if (_placeholderEnabled && !_placeholderImage && [self _locked_displaysAsynchronously]) {
// Zero-sized nodes do not require a placeholder.
ASLayout *layout = _calculatedDisplayNodeLayout->layout;
CGSize layoutSize = (layout ? layout.size : CGSizeZero);
CGSize layoutSize = _calculatedDisplayNodeLayout.layout.size;
if (layoutSize.width * layoutSize.height <= 0.0) {
return;
}
@@ -983,23 +997,12 @@ ASLayoutElementStyleExtensibilityForwarding
_pendingLayoutTransition = nil;
}
- (void)_setCalculatedDisplayNodeLayout:(std::shared_ptr<ASDisplayNodeLayout>)displayNodeLayout
- (void)_locked_setCalculatedDisplayNodeLayout:(const ASDisplayNodeLayout &)displayNodeLayout
{
ASDN::MutexLocker l(__instanceLock__);
[self _locked_setCalculatedDisplayNodeLayout:displayNodeLayout];
}
- (void)_locked_setCalculatedDisplayNodeLayout:(std::shared_ptr<ASDisplayNodeLayout>)displayNodeLayout
{
ASDisplayNodeAssertTrue(displayNodeLayout->layout.layoutElement == self);
ASDisplayNodeAssertTrue(displayNodeLayout->layout.size.width >= 0.0);
ASDisplayNodeAssertTrue(displayNodeLayout->layout.size.height >= 0.0);
// Flatten the layout if it wasn't done before (@see -calculateLayoutThatFits:).
if ([ASDisplayNode shouldStoreUnflattenedLayouts]) {
_unflattenedLayout = displayNodeLayout->layout;
displayNodeLayout->layout = [_unflattenedLayout filteredNodeLayoutTree];
}
ASAssertLocked(__instanceLock__);
ASDisplayNodeAssertTrue(displayNodeLayout.layout.layoutElement == self);
ASDisplayNodeAssertTrue(displayNodeLayout.layout.size.width >= 0.0);
ASDisplayNodeAssertTrue(displayNodeLayout.layout.size.height >= 0.0);
_calculatedDisplayNodeLayout = displayNodeLayout;
}

View File

@@ -2,17 +2,9 @@
// ASDisplayNode+Subclasses.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASBlockTypes.h>
@@ -42,74 +34,6 @@ NS_ASSUME_NONNULL_BEGIN
* variables.
*/
@protocol ASInterfaceStateDelegate <NSObject>
@required
/**
* @abstract Called whenever any bit in the ASInterfaceState bitfield is changed.
* @discussion Subclasses may use this to monitor when they become visible, should free cached data, and much more.
* @see ASInterfaceState
*/
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState;
/**
* @abstract Called whenever the node becomes visible.
* @discussion Subclasses may use this to monitor when they become visible.
* @note This method is guaranteed to be called on main.
*/
- (void)didEnterVisibleState;
/**
* @abstract Called whenever the node is no longer visible.
* @discussion Subclasses may use this to monitor when they are no longer visible.
* @note This method is guaranteed to be called on main.
*/
- (void)didExitVisibleState;
/**
* @abstract Called whenever the the node has entered the display state.
* @discussion Subclasses may use this to monitor when a node should be rendering its content.
* @note This method is guaranteed to be called on main.
*/
- (void)didEnterDisplayState;
/**
* @abstract Called whenever the the node has exited the display state.
* @discussion Subclasses may use this to monitor when a node should no longer be rendering its content.
* @note This method is guaranteed to be called on main.
*/
- (void)didExitDisplayState;
/**
* @abstract Called whenever the the node has entered the preload state.
* @discussion Subclasses may use this to monitor data for a node should be preloaded, either from a local or remote source.
* @note This method is guaranteed to be called on main.
*/
- (void)didEnterPreloadState;
/**
* @abstract Called whenever the the node has exited the preload state.
* @discussion Subclasses may use this to monitor whether preloading data for a node should be canceled.
* @note This method is guaranteed to be called on main.
*/
- (void)didExitPreloadState;
/**
* @abstract Called when the node has completed applying the layout.
* @discussion Can be used for operations that are performed after layout has completed.
* @note This method is guaranteed to be called on main.
*/
- (void)nodeDidLayout;
/**
* @abstract Called when the node loads.
* @discussion Can be used for operations that are performed after the node's view is available.
* @note This method is guaranteed to be called on main.
*/
- (void)nodeDidLoad;
@end
@interface ASDisplayNode (Subclassing) <ASInterfaceStateDelegate>
#pragma mark - Properties

View File

@@ -2,17 +2,9 @@
// ASDisplayNode+Yoga.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASAvailability.h>
@@ -20,8 +12,8 @@
#if YOGA /* YOGA */
#import <AsyncDisplayKit/_ASDisplayViewAccessiblity.h>
#import <AsyncDisplayKit/ASYogaLayoutSpec.h>
#import <AsyncDisplayKit/ASYogaUtilities.h>
#import <AsyncDisplayKit/ASCollections.h>
#import <AsyncDisplayKit/ASDisplayNode+Beta.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
@@ -164,10 +156,12 @@
ASDisplayNodeAssert(childCount == self.yogaChildren.count,
@"Yoga tree should always be in sync with .yogaNodes array! %@", self.yogaChildren);
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:childCount];
ASLayout *rawSublayouts[childCount];
int i = 0;
for (ASDisplayNode *subnode in self.yogaChildren) {
[sublayouts addObject:[subnode layoutForYogaNode]];
rawSublayouts[i++] = [subnode layoutForYogaNode];
}
let sublayouts = [NSArray<ASLayout *> arrayByTransferring:rawSublayouts count:childCount];
// The layout for self should have position CGPointNull, but include the calculated size.
CGSize size = CGSizeMake(YGNodeLayoutGetWidth(yogaNode), YGNodeLayoutGetHeight(yogaNode));
@@ -215,7 +209,7 @@
// For the root node in a Yoga tree, make sure to preserve the constrainedSize originally provided.
// This will be used for all relayouts triggered by children, since they escalate to root.
ASSizeRange range = parentNode ? ASSizeRangeUnconstrained : self.constrainedSizeForCalculatedLayout;
_pendingDisplayNodeLayout = std::make_shared<ASDisplayNodeLayout>(layout, range, parentSize, _layoutVersion);
_pendingDisplayNodeLayout = ASDisplayNodeLayout(layout, range, parentSize, _layoutVersion);
}
}
@@ -299,7 +293,7 @@
// Reset accessible elements, since layout may have changed.
ASPerformBlockOnMainThread(^{
[(_ASDisplayView *)self.view setAccessibleElements:nil];
[(_ASDisplayView *)self.view setAccessibilityElements:nil];
});
ASDisplayNodePerformBlockOnEveryYogaChild(self, ^(ASDisplayNode * _Nonnull node) {

View File

@@ -2,17 +2,9 @@
// ASDisplayNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#pragma once
@@ -22,6 +14,7 @@
#import <AsyncDisplayKit/_ASAsyncTransactionContainer.h>
#import <AsyncDisplayKit/ASBaseDefines.h>
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASDisplayNode+InterfaceState.h>
#import <AsyncDisplayKit/ASAsciiArtBoxCreator.h>
#import <AsyncDisplayKit/ASObjectDescriptionHelpers.h>
#import <AsyncDisplayKit/ASLayoutElement.h>
@@ -32,6 +25,10 @@ NS_ASSUME_NONNULL_BEGIN
#define ASDisplayNodeLoggingEnabled 0
#ifndef AS_MAX_INTERFACE_STATE_DELEGATES
#define AS_MAX_INTERFACE_STATE_DELEGATES 4
#endif
@class ASDisplayNode;
@protocol ASContextTransitioning;
@@ -71,37 +68,6 @@ typedef ASLayoutSpec * _Nonnull(^ASLayoutSpecBlock)(__kindof ASDisplayNode *node
*/
typedef void (^ASDisplayNodeNonFatalErrorBlock)(NSError *error);
/**
* Interface state is available on ASDisplayNode and ASViewController, and
* allows checking whether a node is in an interface situation where it is prudent to trigger certain
* actions: measurement, data loading, display, and visibility (the latter for animations or other onscreen-only effects).
*
* The defualt state, ASInterfaceStateNone, means that the element is not predicted to be onscreen soon and
* preloading should not be performed. Swift: use [] for the default behavior.
*/
typedef NS_OPTIONS(NSUInteger, ASInterfaceState)
{
/** The element is not predicted to be onscreen soon and preloading should not be performed */
ASInterfaceStateNone = 0,
/** The element may be added to a view soon that could become visible. Measure the layout, including size calculation. */
ASInterfaceStateMeasureLayout = 1 << 0,
/** The element is likely enough to come onscreen that disk and/or network data required for display should be fetched. */
ASInterfaceStatePreload = 1 << 1,
/** The element is very likely to become visible, and concurrent rendering should be executed for any -setNeedsDisplay. */
ASInterfaceStateDisplay = 1 << 2,
/** The element is physically onscreen by at least 1 pixel.
In practice, all other bit fields should also be set when this flag is set. */
ASInterfaceStateVisible = 1 << 3,
/**
* The node is not contained in a cell but it is in a window.
*
* Currently we only set `interfaceState` to other values for
* nodes contained in table views or collection views.
*/
ASInterfaceStateInHierarchy = ASInterfaceStateMeasureLayout | ASInterfaceStatePreload | ASInterfaceStateDisplay | ASInterfaceStateVisible,
};
typedef NS_ENUM(NSInteger, ASCornerRoundingType) {
ASCornerRoundingTypeDefaultSlowCALayer,
ASCornerRoundingTypePrecomposited,
@@ -299,6 +265,26 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority;
*/
@property (readonly) ASInterfaceState interfaceState;
/**
* @abstract Adds a delegate to receive notifications on interfaceState changes.
*
* @warning This must be called from the main thread.
* There is a hard limit on the number of delegates a node can have; see
* AS_MAX_INTERFACE_STATE_DELEGATES above.
*
* @see ASInterfaceState
*/
- (void)addInterfaceStateDelegate:(id <ASInterfaceStateDelegate>)interfaceStateDelegate;
/**
* @abstract Removes a delegate from receiving notifications on interfaceState changes.
*
* @warning This must be called from the main thread.
*
* @see ASInterfaceState
*/
- (void)removeInterfaceStateDelegate:(id <ASInterfaceStateDelegate>)interfaceStateDelegate;
/**
* @abstract Class property that allows to set a block that can be called on non-fatal errors. This
* property can be useful for cases when Async Display Kit can recover from an abnormal behavior, but
@@ -643,10 +629,10 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority;
*/
- (void)layoutIfNeeded;
@property CGRect frame; // default=CGRectZero
@property CGRect bounds; // default=CGRectZero
@property CGPoint position; // default=CGPointZero
@property CGFloat alpha; // default=1.0f
@property CGRect frame; // default=CGRectZero
@property CGRect bounds; // default=CGRectZero
@property CGPoint position; // default=CGPointZero
@property CGFloat alpha; // default=1.0f
/* @abstract Sets the corner rounding method to use on the ASDisplayNode.
* There are three types of corner rounding provided by Texture: CALayer, Precomposited, and Clipping.
@@ -670,7 +656,7 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority;
*
* @default ASCornerRoundingTypeDefaultSlowCALayer
*/
@property ASCornerRoundingType cornerRoundingType; // default=Slow CALayer .cornerRadius (offscreen rendering)
@property ASCornerRoundingType cornerRoundingType; // default=ASCornerRoundingTypeDefaultSlowCALayer .cornerRadius (offscreen rendering)
/** @abstract The radius to use when rounding corners of the ASDisplayNode.
*
@@ -679,24 +665,24 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority;
*/
@property CGFloat cornerRadius; // default=0.0
@property BOOL clipsToBounds; // default==NO
@property (getter=isHidden) BOOL hidden; // default==NO
@property (getter=isOpaque) BOOL opaque; // default==YES
@property BOOL clipsToBounds; // default==NO
@property (getter=isHidden) BOOL hidden; // default==NO
@property (getter=isOpaque) BOOL opaque; // default==YES
@property (nullable) id contents; // default=nil
@property CGRect contentsRect; // default={0,0,1,1}. @see CALayer.h for details.
@property CGRect contentsCenter; // default={0,0,1,1}. @see CALayer.h for details.
@property CGFloat contentsScale; // default=1.0f. See @contentsScaleForDisplay for details.
@property CGFloat rasterizationScale; // default=1.0f.
@property (nullable) id contents; // default=nil
@property CGRect contentsRect; // default={0,0,1,1}. @see CALayer.h for details.
@property CGRect contentsCenter; // default={0,0,1,1}. @see CALayer.h for details.
@property CGFloat contentsScale; // default=1.0f. See @contentsScaleForDisplay for details.
@property CGFloat rasterizationScale; // default=1.0f.
@property CGPoint anchorPoint; // default={0.5, 0.5}
@property CGFloat zPosition; // default=0.0
@property CATransform3D transform; // default=CATransform3DIdentity
@property CATransform3D subnodeTransform; // default=CATransform3DIdentity
@property CGPoint anchorPoint; // default={0.5, 0.5}
@property CGFloat zPosition; // default=0.0
@property CATransform3D transform; // default=CATransform3DIdentity
@property CATransform3D subnodeTransform; // default=CATransform3DIdentity
@property (getter=isUserInteractionEnabled) BOOL userInteractionEnabled; // default=YES (NO for layer-backed nodes)
#if TARGET_OS_IOS
@property (getter=isExclusiveTouch) BOOL exclusiveTouch; // default=NO
@property (getter=isExclusiveTouch) BOOL exclusiveTouch; // default=NO
#endif
/**
@@ -705,10 +691,10 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority;
* @discussion In contrast to UIView, setting a transparent color will not set opaque = NO.
* This only affects nodes that implement +drawRect like ASTextNode.
*/
@property (nullable, copy) UIColor *backgroundColor; // default=nil
@property (nullable, copy) UIColor *backgroundColor; // default=nil
@property (null_resettable, copy) UIColor *tintColor; // default=Blue
- (void)tintColorDidChange; // Notifies the node when the tintColor has changed.
@property (null_resettable, copy) UIColor *tintColor; // default=Blue
- (void)tintColorDidChange; // Notifies the node when the tintColor has changed.
/**
* @abstract A flag used to determine how a node lays out its content when its bounds change.
@@ -718,24 +704,24 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority;
* Thus, UIViewContentModeRedraw is not allowed; use needsDisplayOnBoundsChange = YES instead, and pick an appropriate
* contentMode for your content while it's being re-rendered.
*/
@property UIViewContentMode contentMode; // default=UIViewContentModeScaleToFill
@property (copy) NSString *contentsGravity; // Use .contentMode in preference when possible.
@property UISemanticContentAttribute semanticContentAttribute;
@property UIViewContentMode contentMode; // default=UIViewContentModeScaleToFill
@property (copy) NSString *contentsGravity; // Use .contentMode in preference when possible.
@property UISemanticContentAttribute semanticContentAttribute;
@property (nullable) CGColorRef shadowColor; // default=opaque rgb black
@property CGFloat shadowOpacity; // default=0.0
@property CGSize shadowOffset; // default=(0, -3)
@property CGFloat shadowRadius; // default=3
@property CGFloat borderWidth; // default=0
@property (nullable) CGColorRef borderColor; // default=opaque rgb black
@property (nullable) CGColorRef shadowColor; // default=opaque rgb black
@property CGFloat shadowOpacity; // default=0.0
@property CGSize shadowOffset; // default=(0, -3)
@property CGFloat shadowRadius; // default=3
@property CGFloat borderWidth; // default=0
@property (nullable) CGColorRef borderColor; // default=opaque rgb black
@property BOOL allowsGroupOpacity;
@property BOOL allowsEdgeAntialiasing;
@property unsigned int edgeAntialiasingMask; // default==all values from CAEdgeAntialiasingMask
@property BOOL allowsGroupOpacity;
@property BOOL allowsEdgeAntialiasing;
@property unsigned int edgeAntialiasingMask; // default==all values from CAEdgeAntialiasingMask
@property BOOL needsDisplayOnBoundsChange; // default==NO
@property BOOL autoresizesSubviews; // default==YES (undefined for layer-backed nodes)
@property UIViewAutoresizing autoresizingMask; // default==UIViewAutoresizingNone (undefined for layer-backed nodes)
@property BOOL needsDisplayOnBoundsChange; // default==NO
@property BOOL autoresizesSubviews; // default==YES (undefined for layer-backed nodes)
@property UIViewAutoresizing autoresizingMask; // default==UIViewAutoresizingNone (undefined for layer-backed nodes)
/**
* @abstract Content margins

View File

@@ -2,17 +2,9 @@
// ASDisplayNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
@@ -35,7 +27,9 @@
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
#import <AsyncDisplayKit/ASDisplayNodeCornerLayerDelegate.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASDisplayNode+InterfaceState.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASEqualityHelpers.h>
#import <AsyncDisplayKit/ASGraphicsContext.h>
@@ -45,6 +39,7 @@
#import <AsyncDisplayKit/ASLayoutSpecPrivate.h>
#import <AsyncDisplayKit/ASLog.h>
#import <AsyncDisplayKit/ASMainThreadDeallocation.h>
#import <AsyncDisplayKit/ASNodeController+Beta.h>
#import <AsyncDisplayKit/ASRunLoopQueue.h>
#import <AsyncDisplayKit/ASSignpost.h>
#import <AsyncDisplayKit/ASTraitCollection.h>
@@ -71,7 +66,6 @@ NSInteger const ASDefaultDrawingPriority = ASDefaultTransactionPriority;
@protocol CALayerDelegate;
@interface ASDisplayNode () <UIGestureRecognizerDelegate, CALayerDelegate, _ASDisplayLayerDelegate, ASCATransactionQueueObserving>
/**
* See ASDisplayNodeInternal.h for ivars
*/
@@ -154,6 +148,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
ASDisplayNodeCAssertNotNil(c, @"class is required");
ASDisplayNodeMethodOverrides overrides = ASDisplayNodeMethodOverrideNone;
// Handling touches
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(touchesBegan:withEvent:))) {
overrides |= ASDisplayNodeMethodOverrideTouchesBegan;
}
@@ -166,13 +162,32 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(touchesEnded:withEvent:))) {
overrides |= ASDisplayNodeMethodOverrideTouchesEnded;
}
// Responder chain
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(canBecomeFirstResponder))) {
overrides |= ASDisplayNodeMethodOverrideCanBecomeFirstResponder;
}
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(becomeFirstResponder))) {
overrides |= ASDisplayNodeMethodOverrideBecomeFirstResponder;
}
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(canResignFirstResponder))) {
overrides |= ASDisplayNodeMethodOverrideCanResignFirstResponder;
}
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(resignFirstResponder))) {
overrides |= ASDisplayNodeMethodOverrideResignFirstResponder;
}
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(isFirstResponder))) {
overrides |= ASDisplayNodeMethodOverrideIsFirstResponder;
}
// Layout related methods
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(layoutSpecThatFits:))) {
overrides |= ASDisplayNodeMethodOverrideLayoutSpecThatFits;
}
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(calculateLayoutThatFits:)) ||
ASDisplayNodeSubclassOverridesSelector(c, @selector(calculateLayoutThatFits:
restrictedToSize:
relativeToParentSize:))) {
restrictedToSize:
relativeToParentSize:))) {
overrides |= ASDisplayNodeMethodOverrideCalcLayoutThatFits;
}
if (ASDisplayNodeSubclassOverridesSelector(c, @selector(calculateSizeThatFits:))) {
@@ -277,8 +292,6 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
_primitiveTraitCollection = ASPrimitiveTraitCollectionMakeDefault();
_calculatedDisplayNodeLayout = std::make_shared<ASDisplayNodeLayout>();
_pendingDisplayNodeLayout = nullptr;
_layoutVersion = 1;
_defaultLayoutTransitionDuration = 0.2;
@@ -395,6 +408,11 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
setFlag(Synchronous, YES);
}
- (ASDisplayNodeMethodOverrides)methodOverrides
{
return _methodOverrides;
}
- (void)onDidLoad:(ASDisplayNodeDidLoadBlock)body
{
ASDN::MutexLocker l(__instanceLock__);
@@ -439,11 +457,14 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (BOOL)_locked_shouldLoadViewOrLayer
{
ASAssertLocked(__instanceLock__);
return !_flags.isDeallocating && !(_hierarchyState & ASHierarchyStateRasterized);
}
- (UIView *)_locked_viewToLoad
{
ASAssertLocked(__instanceLock__);
UIView *view = nil;
if (_viewBlock) {
view = _viewBlock();
@@ -482,6 +503,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (CALayer *)_locked_layerToLoad
{
ASAssertLocked(__instanceLock__);
ASDisplayNodeAssert(_flags.layerBacked, @"_layerToLoad is only for layer-backed nodes");
CALayer *layer = nil;
@@ -500,6 +522,8 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (void)_locked_loadViewOrLayer
{
ASAssertLocked(__instanceLock__);
if (_flags.layerBacked) {
TIME_SCOPED(_debugTimeToCreateView);
_layer = [self _locked_layerToLoad];
@@ -528,7 +552,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (void)_didLoad
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
ASDisplayNodeLogEvent(self, @"didLoad");
as_log_verbose(ASNodeLog(), "didLoad %@", self);
TIME_SCOPED(_debugTimeForDidLoad);
@@ -536,15 +560,15 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
[self didLoad];
__instanceLock__.lock();
NSArray *onDidLoadBlocks = [_onDidLoadBlocks copy];
_onDidLoadBlocks = nil;
let onDidLoadBlocks = ASTransferStrong(_onDidLoadBlocks);
__instanceLock__.unlock();
for (ASDisplayNodeDidLoadBlock block in onDidLoadBlocks) {
block(self);
}
[_interfaceStateDelegate nodeDidLoad];
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del nodeDidLoad];
}];
}
- (void)didLoad
@@ -559,7 +583,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
if (ASDisplayNodeThreadIsMain()) {
// Because the view and layer can only be created and destroyed on Main, that is also the only thread
// where the state of this property can change. As an optimization, we can avoid locking.
return [self _locked_isNodeLoaded];
return _loaded(self);
} else {
ASDN::MutexLocker l(__instanceLock__);
return [self _locked_isNodeLoaded];
@@ -568,7 +592,8 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (BOOL)_locked_isNodeLoaded
{
return (_view != nil || (_layer != nil && _flags.layerBacked));
ASAssertLocked(__instanceLock__);
return _loaded(self);
}
#pragma mark - Misc Setter / Getter
@@ -671,6 +696,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (_ASDisplayLayer *)_locked_asyncLayer
{
ASAssertLocked(__instanceLock__);
return [_layer isKindOfClass:[_ASDisplayLayer class]] ? (_ASDisplayLayer *)_layer : nil;
}
@@ -729,6 +755,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (CGRect)_locked_threadSafeBounds
{
ASAssertLocked(__instanceLock__);
return _threadSafeBounds;
}
@@ -841,6 +868,18 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
_automaticallyRelayoutOnLayoutMarginsChanges = flag;
}
- (void)__setNodeController:(ASNodeController *)controller
{
// See docs for why we don't lock.
if (controller.shouldInvertStrongReference) {
_strongNodeController = controller;
_weakNodeController = nil;
} else {
_weakNodeController = controller;
_strongNodeController = nil;
}
}
#pragma mark - UIResponder
#define HANDLE_NODE_RESPONDER_METHOD(__sel) \
@@ -989,7 +1028,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (void)__layout
{
ASDisplayNodeAssertThreadAffinity(self);
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
BOOL loaded = NO;
{
@@ -1015,9 +1054,10 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
// This method will confirm that the layout is up to date (and update if needed).
// Importantly, it will also APPLY the layout to all of our subnodes if (unless parent is transitioning).
__instanceLock__.unlock();
[self _u_measureNodeWithBoundsIfNecessary:bounds];
__instanceLock__.lock();
{
ASDN::MutexUnlocker u(__instanceLock__);
[self _u_measureNodeWithBoundsIfNecessary:bounds];
}
[self _locked_layoutPlaceholderIfNecessary];
}
@@ -1040,7 +1080,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
{
// Hook for subclasses
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
ASDisplayNodeAssertTrue(self.isNodeLoaded);
}
@@ -1050,11 +1090,13 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
restrictedToSize:(ASLayoutElementSize)size
relativeToParentSize:(CGSize)parentSize
{
// We only want one calculateLayout signpost interval per thread.
#ifndef MINIMAL_ASDK
static _Thread_local NSInteger tls_callDepth;
as_activity_scope_verbose(as_activity_create("Calculate node layout", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT));
as_log_verbose(ASLayoutLog(), "Calculating layout for %@ sizeRange %@", self, NSStringFromASSizeRange(constrainedSize));
#if AS_KDEBUG_ENABLE
// We only want one calculateLayout signpost interval per thread.
// Currently there is no fallback for profiling i386, since it's not useful.
static _Thread_local NSInteger tls_callDepth;
if (tls_callDepth++ == 0) {
ASSignpostStart(ASSignpostCalculateLayout);
}
@@ -1063,13 +1105,14 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
ASSizeRange styleAndParentSize = ASLayoutElementSizeResolve(self.style.size, parentSize);
const ASSizeRange resolvedRange = ASSizeRangeIntersect(constrainedSize, styleAndParentSize);
ASLayout *result = [self calculateLayoutThatFits:resolvedRange];
#ifndef MINIMAL_ASDK
as_log_verbose(ASLayoutLog(), "Calculated layout %@", result);
#if AS_KDEBUG_ENABLE
if (--tls_callDepth == 0) {
ASSignpostEnd(ASSignpostCalculateLayout);
}
#endif
return result;
}
@@ -1177,11 +1220,11 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
}
ASDisplayNodeLogEvent(self, @"computedLayout: %@", layout);
// Return the (original) unflattened layout if it needs to be stored. The layout will be flattened later on (@see _locked_setCalculatedDisplayNodeLayout:).
// Otherwise, flatten it right away.
if (! [ASDisplayNode shouldStoreUnflattenedLayouts]) {
layout = [layout filteredNodeLayoutTree];
// PR #1157: Reduces accuracy of _unflattenedLayout for debugging/Weaver
if ([ASDisplayNode shouldStoreUnflattenedLayouts]) {
_unflattenedLayout = layout;
}
layout = [layout filteredNodeLayoutTree];
return layout;
}
@@ -1197,6 +1240,7 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
- (id<ASLayoutElement>)_locked_layoutElementThatFits:(ASSizeRange)constrainedSize
{
ASAssertLocked(__instanceLock__);
__ASDisplayNodeCheckForLayoutMethodOverrides;
BOOL measureLayoutSpec = _measurementOptions & ASDisplayNodePerformanceMeasurementOptionLayoutSpec;
@@ -1227,9 +1271,11 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
{
// Hook for subclasses
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
ASDisplayNodeAssertTrue(self.isNodeLoaded);
[_interfaceStateDelegate nodeDidLayout];
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del nodeDidLayout];
}];
}
#pragma mark Layout Transition
@@ -1277,6 +1323,7 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
*/
- (BOOL)_locked_displaysAsynchronously
{
ASAssertLocked(__instanceLock__);
return checkFlag(Synchronous) == NO && _flags.displaysAsynchronously;
}
@@ -1451,6 +1498,10 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
if (_pendingDisplayNodes.isEmpty) {
[self hierarchyDisplayDidFinish];
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> delegate) {
[delegate hierarchyDisplayDidFinish];
}];
BOOL placeholderShouldPersist = [self placeholderShouldPersist];
__instanceLock__.lock();
@@ -1591,7 +1642,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
}
CGSize boundsSize = self.bounds.size;
for (int idx = 0; idx < 4; idx++) {
for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) {
BOOL isTop = (idx == 0 || idx == 1);
BOOL isRight = (idx == 1 || idx == 2);
if (_clipCornerLayers[idx]) {
@@ -1605,7 +1656,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
- (void)_updateClipCornerLayerContentsWithRadius:(CGFloat)radius backgroundColor:(UIColor *)backgroundColor
{
ASPerformBlockOnMainThread(^{
for (int idx = 0; idx < 4; idx++) {
for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) {
// Layers are, in order: Top Left, Top Right, Bottom Right, Bottom Left.
// anchorPoint is Bottom Left at 0,0 and Top Right at 1,1.
BOOL isTop = (idx == 0 || idx == 1);
@@ -1642,16 +1693,21 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
ASPerformBlockOnMainThread(^{
ASDisplayNodeAssertMainThread();
if (visible) {
for (int idx = 0; idx < 4; idx++) {
for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) {
if (_clipCornerLayers[idx] == nil) {
static ASDisplayNodeCornerLayerDelegate *clipCornerLayers;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
clipCornerLayers = [[ASDisplayNodeCornerLayerDelegate alloc] init];
});
_clipCornerLayers[idx] = [[CALayer alloc] init];
_clipCornerLayers[idx].zPosition = 99999;
_clipCornerLayers[idx].delegate = self;
_clipCornerLayers[idx].delegate = clipCornerLayers;
}
}
[self _updateClipCornerLayerContentsWithRadius:_cornerRadius backgroundColor:self.backgroundColor];
} else {
for (int idx = 0; idx < 4; idx++) {
for (int idx = 0; idx < NUM_CLIP_CORNER_LAYERS; idx++) {
[_clipCornerLayers[idx] removeFromSuperlayer];
_clipCornerLayers[idx] = nil;
}
@@ -2053,7 +2109,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (ASDisplayNode *)supernode
{
#if CHECK_LOCKING_SAFETY
if (__instanceLock__.ownedByCurrentThread()) {
if (__instanceLock__.locked()) {
NSLog(@"WARNING: Accessing supernode while holding recursive instance lock of this node is worrisome. It's likely that you will soon try to acquire the supernode's lock, and this can easily cause deadlocks.");
}
#endif
@@ -2147,7 +2203,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
/*
* Central private helper method that should eventually be called if submethods add, insert or replace subnodes
* This method is called with thread affinity.
* This method is called with thread affinity and without lock held.
*
* @param subnode The subnode to insert
* @param subnodeIndex The index in _subnodes to insert it
@@ -2157,7 +2213,9 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
*/
- (void)_insertSubnode:(ASDisplayNode *)subnode atSubnodeIndex:(NSInteger)subnodeIndex sublayerIndex:(NSInteger)sublayerIndex andRemoveSubnode:(ASDisplayNode *)oldSubnode
{
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASDisplayNodeAssertThreadAffinity(self);
ASAssertUnlocked(__instanceLock__);
as_log_verbose(ASNodeLog(), "Insert subnode %@ at index %zd of %@ and remove subnode %@", subnode, subnodeIndex, self, oldSubnode);
if (subnode == nil || subnode == self) {
@@ -2185,7 +2243,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
NSUInteger subnodesCount = _subnodes.count;
__instanceLock__.unlock();
if (subnodeIndex > subnodesCount || subnodeIndex < 0) {
ASDisplayNodeFailAssert(@"Cannot insert a subnode at index %zd. Count is %zd", subnodeIndex, subnodesCount);
ASDisplayNodeFailAssert(@"Cannot insert a subnode at index %ld. Count is %ld", (long)subnodeIndex, (long)subnodesCount);
return;
}
@@ -2365,6 +2423,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)below
{
ASDisplayNodeAssertThreadAffinity(self);
ASAssertUnlocked(__instanceLock__);
if (subnode == nil) {
ASDisplayNodeFailAssert(@"Cannot insert a nil subnode");
@@ -2428,6 +2487,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)above
{
ASDisplayNodeAssertThreadAffinity(self);
ASAssertUnlocked(__instanceLock__);
if (subnode == nil) {
ASDisplayNodeFailAssert(@"Cannot insert a nil subnode");
@@ -2489,6 +2549,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_insertSubnode:(ASDisplayNode *)subnode atIndex:(NSInteger)idx
{
ASDisplayNodeAssertThreadAffinity(self);
ASAssertUnlocked(__instanceLock__);
if (subnode == nil) {
ASDisplayNodeFailAssert(@"Cannot insert a nil subnode");
@@ -2500,7 +2561,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
ASDN::MutexLocker l(__instanceLock__);
if (idx > _subnodes.count || idx < 0) {
ASDisplayNodeFailAssert(@"Cannot insert a subnode at index %zd. Count is %zd", idx, _subnodes.count);
ASDisplayNodeFailAssert(@"Cannot insert a subnode at index %ld. Count is %ld", (long)idx, (long)_subnodes.count);
return;
}
@@ -2525,7 +2586,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_removeSubnode:(ASDisplayNode *)subnode
{
ASDisplayNodeAssertThreadAffinity(self);
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
// Don't call self.supernode here because that will retain/autorelease the supernode. This method -_removeSupernode: is often called while tearing down a node hierarchy, and the supernode in question might be in the middle of its -dealloc. The supernode is never messaged, only compared by value, so this is safe.
// The particular issue that triggers this edge case is when a node calls -removeFromSupernode on a subnode from within its own -dealloc method.
@@ -2551,7 +2612,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_removeFromSupernode
{
ASDisplayNodeAssertThreadAffinity(self);
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
__instanceLock__.lock();
__weak ASDisplayNode *supernode = _supernode;
@@ -2565,7 +2626,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_removeFromSupernodeIfEqualTo:(ASDisplayNode *)supernode
{
ASDisplayNodeAssertThreadAffinity(self);
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
__instanceLock__.lock();
@@ -2658,6 +2719,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_locked_layoutPlaceholderIfNecessary
{
ASAssertLocked(__instanceLock__);
if ([self _locked_shouldHavePlaceholderLayer]) {
[self _locked_setupPlaceholderLayerIfNeeded];
}
@@ -2667,12 +2729,14 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (BOOL)_locked_shouldHavePlaceholderLayer
{
ASAssertLocked(__instanceLock__);
return (_placeholderEnabled && [self _implementsDisplay]);
}
- (void)_locked_setupPlaceholderLayerIfNeeded
{
ASDisplayNodeAssertMainThread();
ASAssertLocked(__instanceLock__);
if (!_placeholderLayer) {
_placeholderLayer = [CALayer layer];
@@ -2720,7 +2784,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"Should not cause recursive __enterHierarchy");
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
ASDisplayNodeLogEvent(self, @"enterHierarchy");
// Profiling has shown that locking this method is beneficial, so each of the property accesses don't have to lock and unlock.
@@ -2769,7 +2833,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"Should not cause recursive __exitHierarchy");
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
ASDisplayNodeLogEvent(self, @"exitHierarchy");
// Profiling has shown that locking this method is beneficial, so each of the property accesses don't have to lock and unlock.
@@ -2779,8 +2843,6 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
_flags.isExitingHierarchy = YES;
_flags.isInHierarchy = NO;
[self._locked_asyncLayer cancelAsyncDisplay];
// Don't call -didExitHierarchy while holding __instanceLock__.
// This method and subsequent ones (i.e -interfaceState and didExit(.*)State)
// don't expect that they are called while the lock is being held.
@@ -2876,10 +2938,19 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(_flags.isEnteringHierarchy, @"You should never call -willEnterHierarchy directly. Appearance is automatically managed by ASDisplayNode");
ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
if (![self supportsRangeManagedInterfaceState]) {
self.interfaceState = ASInterfaceStateInHierarchy;
} else if (ASCATransactionQueue.sharedQueue.isEnabled) {
__instanceLock__.lock();
ASInterfaceState state = _preExitingInterfaceState;
_preExitingInterfaceState = ASInterfaceStateNone;
__instanceLock__.unlock();
// Layer thrash happened, revert to before exiting.
if (state != ASInterfaceStateNone) {
self.interfaceState = state;
}
}
}
@@ -2888,7 +2959,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"You should never call -didEnterHierarchy directly. Appearance is automatically managed by ASDisplayNode");
ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
ASDisplayNodeAssert(_flags.isInHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
}
- (void)didExitHierarchy
@@ -2896,7 +2967,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(_flags.isExitingHierarchy, @"You should never call -didExitHierarchy directly. Appearance is automatically managed by ASDisplayNode");
ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
// This case is important when tearing down hierarchies. We must deliver a visibileStateDidChange:NO callback, as part our API guarantee that this method can be used for
// things like data analytics about user content viewing. We cannot call the method in the dealloc as any incidental retain operations in client code would fail.
@@ -2918,6 +2989,8 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
unsigned isStillInHierarchy = _flags.isInHierarchy;
BOOL isVisible = ASInterfaceStateIncludesVisible(_pendingInterfaceState);
ASInterfaceState newState = (_pendingInterfaceState & ~ASInterfaceStateVisible);
// layer may be thrashed, we need to remember the state so we can reset if it enters in same runloop later.
_preExitingInterfaceState = _pendingInterfaceState;
__instanceLock__.unlock();
if (!isStillInHierarchy && isVisible) {
#if ENABLE_NEW_EXIT_HIERARCHY_BEHAVIOR
@@ -3018,7 +3091,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
ASDisplayNodeAssertMainThread();
// This method manages __instanceLock__ itself, to ensure the lock is not held while didEnter/Exit(.*)State methods are called, thus avoid potential deadlocks
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
ASInterfaceState oldState = ASInterfaceStateNone;
ASInterfaceState newState = ASInterfaceStateNone;
@@ -3035,6 +3108,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
return;
}
_interfaceState = newState;
_preExitingInterfaceState = ASInterfaceStateNone;
}
// It should never be possible for a node to be visible but not be allowed / expected to display.
@@ -3077,8 +3151,10 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
[self setDisplaySuspended:YES];
//schedule clear contents on next runloop
dispatch_async(dispatch_get_main_queue(), ^{
ASDN::MutexLocker l(__instanceLock__);
if (ASInterfaceStateIncludesDisplay(_interfaceState) == NO) {
__instanceLock__.lock();
ASInterfaceState interfaceState = _interfaceState;
__instanceLock__.unlock();
if (ASInterfaceStateIncludesDisplay(interfaceState) == NO) {
[self clearContents];
}
});
@@ -3095,8 +3171,10 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
[[self asyncLayer] cancelAsyncDisplay];
//schedule clear contents on next runloop
dispatch_async(dispatch_get_main_queue(), ^{
ASDN::MutexLocker l(__instanceLock__);
if (ASInterfaceStateIncludesDisplay(_interfaceState) == NO) {
__instanceLock__.lock();
ASInterfaceState interfaceState = _interfaceState;
__instanceLock__.unlock();
if (ASInterfaceStateIncludesDisplay(interfaceState) == NO) {
[self clearContents];
}
});
@@ -3145,8 +3223,11 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState
{
// Subclass hook
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
[_interfaceStateDelegate interfaceStateDidChange:newState fromState:oldState];
ASAssertUnlocked(__instanceLock__);
ASDisplayNodeAssertMainThread();
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del interfaceStateDidChange:newState fromState:oldState];
}];
}
- (BOOL)shouldScheduleDisplayWithNewInterfaceState:(ASInterfaceState)newInterfaceState
@@ -3156,6 +3237,30 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
return willDisplay && (willDisplay != nowDisplay);
}
- (void)addInterfaceStateDelegate:(id <ASInterfaceStateDelegate>)interfaceStateDelegate
{
ASDN::MutexLocker l(__instanceLock__);
_hasHadInterfaceStateDelegates = YES;
for (int i = 0; i < AS_MAX_INTERFACE_STATE_DELEGATES; i++) {
if (_interfaceStateDelegates[i] == nil) {
_interfaceStateDelegates[i] = interfaceStateDelegate;
return;
}
}
ASDisplayNodeFailAssert(@"Exceeded interface state delegate limit: %d", AS_MAX_INTERFACE_STATE_DELEGATES);
}
- (void)removeInterfaceStateDelegate:(id <ASInterfaceStateDelegate>)interfaceStateDelegate
{
ASDN::MutexLocker l(__instanceLock__);
for (int i = 0; i < AS_MAX_INTERFACE_STATE_DELEGATES; i++) {
if (_interfaceStateDelegates[i] == interfaceStateDelegate) {
_interfaceStateDelegates[i] = nil;
break;
}
}
}
- (BOOL)isVisible
{
ASDN::MutexLocker l(__instanceLock__);
@@ -3166,8 +3271,10 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
{
// subclass override
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
[_interfaceStateDelegate didEnterVisibleState];
ASAssertUnlocked(__instanceLock__);
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del didEnterVisibleState];
}];
#if AS_ENABLE_TIPS
[ASTipsController.shared nodeDidAppear:self];
#endif
@@ -3177,8 +3284,10 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
{
// subclass override
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
[_interfaceStateDelegate didExitVisibleState];
ASAssertUnlocked(__instanceLock__);
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del didExitVisibleState];
}];
}
- (BOOL)isInDisplayState
@@ -3191,16 +3300,20 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
{
// subclass override
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
[_interfaceStateDelegate didEnterDisplayState];
ASAssertUnlocked(__instanceLock__);
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del didEnterDisplayState];
}];
}
- (void)didExitDisplayState
{
// subclass override
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
[_interfaceStateDelegate didExitDisplayState];
ASAssertUnlocked(__instanceLock__);
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del didExitDisplayState];
}];
}
- (BOOL)isInPreloadState
@@ -3237,7 +3350,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)didEnterPreloadState
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
// If this node has ASM enabled and is not yet visible, force a layout pass to apply its applicable pending layout, if any,
// so that its subnodes are inserted/deleted and start preloading right away.
@@ -3250,20 +3363,26 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
if (self.automaticallyManagesSubnodes) {
[self layoutIfNeeded];
}
[_interfaceStateDelegate didEnterPreloadState];
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del didEnterPreloadState];
}];
}
- (void)didExitPreloadState
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
[_interfaceStateDelegate didExitPreloadState];
ASAssertUnlocked(__instanceLock__);
[self enumerateInterfaceStateDelegates:^(id<ASInterfaceStateDelegate> del) {
[del didExitPreloadState];
}];
}
- (void)clearContents
{
ASDisplayNodeAssertMainThread();
ASAssertUnlocked(__instanceLock__);
ASDN::MutexLocker l(__instanceLock__);
if (_flags.canClearContentsOfLayer) {
// No-op if these haven't been created yet, as that guarantees they don't have contents that needs to be released.
_layer.contents = nil;
@@ -3282,7 +3401,29 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
});
}
- (void)enumerateInterfaceStateDelegates:(void (NS_NOESCAPE ^)(id<ASInterfaceStateDelegate>))block
{
ASAssertUnlocked(__instanceLock__);
id dels[AS_MAX_INTERFACE_STATE_DELEGATES];
int count = 0;
{
ASLockScopeSelf();
// Fast path for non-delegating nodes.
if (!_hasHadInterfaceStateDelegates) {
return;
}
for (int i = 0; i < AS_MAX_INTERFACE_STATE_DELEGATES; i++) {
if ((dels[count] = _interfaceStateDelegates[i])) {
count++;
}
}
}
for (int i = 0; i < count; i++) {
block(dels[i]);
}
}
#pragma mark - Gesture Recognizing
@@ -3358,6 +3499,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_locked_applyPendingStateToViewOrLayer
{
ASDisplayNodeAssertMainThread();
ASAssertLocked(__instanceLock__);
ASDisplayNodeAssert(self.nodeLoaded, @"must have a view or layer");
TIME_SCOPED(_debugTimeToApplyPendingState);
@@ -3377,7 +3519,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)applyPendingViewState
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
ASAssertUnlocked(__instanceLock__);
ASDN::MutexLocker l(__instanceLock__);
// FIXME: Ideally we'd call this as soon as the node receives -setNeedsLayout
@@ -3396,6 +3538,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (void)_locked_applyPendingViewState
{
ASDisplayNodeAssertMainThread();
ASAssertLocked(__instanceLock__);
ASDisplayNodeAssert([self _locked_isNodeLoaded], @"Expected node to be loaded before applying pending state.");
if (_flags.layerBacked) {
@@ -3596,7 +3739,7 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
- (NSString *)debugDescription
{
ASPushMainThreadAssertionsDisabled();
auto result = ASObjectDescriptionMake(self, [self propertiesForDebugDescription]);
let result = ASObjectDescriptionMake(self, [self propertiesForDebugDescription]);
ASPopMainThreadAssertionsDisabled();
return result;
}
@@ -3668,26 +3811,24 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
{
ASPushMainThreadAssertionsDisabled();
ASDN::MutexLocker l(__instanceLock__);
auto props = [NSMutableArray<NSDictionary *> array];
let props = [[NSMutableArray<NSDictionary *> alloc] init];
[props addObject:@{ @"layoutVersion": @(_layoutVersion.load()) }];
[props addObject:@{ @"bounds": [NSValue valueWithCGRect:self.bounds] }];
if (_calculatedDisplayNodeLayout != nullptr) {
ASDisplayNodeLayout c = *_calculatedDisplayNodeLayout;
[props addObject:@{ @"calculatedLayout": c.layout }];
[props addObject:@{ @"calculatedVersion": @(c.version) }];
[props addObject:@{ @"calculatedConstrainedSize" : NSStringFromASSizeRange(c.constrainedSize) }];
if (c.requestedLayoutFromAbove) {
if (_calculatedDisplayNodeLayout.layout) {
[props addObject:@{ @"calculatedLayout": _calculatedDisplayNodeLayout.layout }];
[props addObject:@{ @"calculatedVersion": @(_calculatedDisplayNodeLayout.version) }];
[props addObject:@{ @"calculatedConstrainedSize" : NSStringFromASSizeRange(_calculatedDisplayNodeLayout.constrainedSize) }];
if (_calculatedDisplayNodeLayout.requestedLayoutFromAbove) {
[props addObject:@{ @"calculatedRequestedLayoutFromAbove": @"YES" }];
}
}
if (_pendingDisplayNodeLayout != nullptr) {
ASDisplayNodeLayout p = *_pendingDisplayNodeLayout;
[props addObject:@{ @"pendingLayout": p.layout }];
[props addObject:@{ @"pendingVersion": @(p.version) }];
[props addObject:@{ @"pendingConstrainedSize" : NSStringFromASSizeRange(p.constrainedSize) }];
if (p.requestedLayoutFromAbove) {
if (_pendingDisplayNodeLayout.layout) {
[props addObject:@{ @"pendingLayout": _pendingDisplayNodeLayout.layout }];
[props addObject:@{ @"pendingVersion": @(_pendingDisplayNodeLayout.version) }];
[props addObject:@{ @"pendingConstrainedSize" : NSStringFromASSizeRange(_pendingDisplayNodeLayout.constrainedSize) }];
if (_pendingDisplayNodeLayout.requestedLayoutFromAbove) {
[props addObject:@{ @"pendingRequestedLayoutFromAbove": (id)kCFNull }];
}
}

View File

@@ -2,17 +2,9 @@
// ASDisplayNodeExtras.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <QuartzCore/QuartzCore.h>
@@ -30,7 +22,7 @@
#define ASSetDebugName(node, format, ...) node.debugName = [NSString stringWithFormat:format, __VA_ARGS__]
#define ASSetDebugNames(...) _ASSetDebugNames(self.class, @"" # __VA_ARGS__, __VA_ARGS__, nil)
#else
#define ASSetDebugName(node, name)
#define ASSetDebugName(node, format, ...)
#define ASSetDebugNames(...)
#endif
@@ -216,6 +208,6 @@ AS_EXTERN void ASDisplayNodeDisableHierarchyNotifications(ASDisplayNode *node);
AS_EXTERN void ASDisplayNodeEnableHierarchyNotifications(ASDisplayNode *node);
// Not to be called directly.
AS_EXTERN void _ASSetDebugNames(Class owningClass, NSString *names, ASDisplayNode *object, ...);
AS_EXTERN void _ASSetDebugNames(Class owningClass, NSString *names, ASDisplayNode * _Nullable object, ...);
NS_ASSUME_NONNULL_END

View File

@@ -2,17 +2,9 @@
// ASDisplayNodeExtras.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>

View File

@@ -2,17 +2,9 @@
// ASEditableTextNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNode.h>
@@ -211,7 +203,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)editableTextNodeDidUpdateText:(ASEditableTextNode *)editableTextNode;
/**
@abstract Indicates to the delegate that teh text node has finished editing.
@abstract Indicates to the delegate that the text node has finished editing.
@param editableTextNode An editable text node.
@discussion The invocation of this method coincides with the keyboard animating to become hidden.
*/

View File

@@ -2,17 +2,9 @@
// ASEditableTextNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASEditableTextNode.h>

View File

@@ -2,12 +2,8 @@
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>
@@ -25,7 +21,9 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) {
ASExperimentalUnfairLock = 1 << 3, // exp_unfair_lock
ASExperimentalLayerDefaults = 1 << 4, // exp_infer_layer_defaults
ASExperimentalNetworkImageQueue = 1 << 5, // exp_network_image_queue
ASExperimentalDeallocQueue = 1 << 6, // exp_dealloc_queue_v2
ASExperimentalCollectionTeardown = 1 << 6, // exp_collection_teardown
ASExperimentalFramesetterCache = 1 << 7, // exp_framesetter_cache
ASExperimentalClearDataDuringDeallocation = 1 << 8, // exp_clear_data_during_deallocation
ASExperimentalFeatureAll = 0xFFFFFFFF
};

View File

@@ -2,16 +2,14 @@
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASExperimentalFeatures.h>
#import <AsyncDisplayKit/ASCollections.h>
NSArray<NSString *> *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags)
{
NSArray *allNames = ASCreateOnce((@[@"exp_graphics_contexts",
@@ -20,7 +18,10 @@ NSArray<NSString *> *ASExperimentalFeaturesGetNames(ASExperimentalFeatures flags
@"exp_unfair_lock",
@"exp_infer_layer_defaults",
@"exp_network_image_queue",
@"exp_dealloc_queue_v2"]));
@"exp_dealloc_queue_v2",
@"exp_collection_teardown",
@"exp_framesetter_cache",
@"exp_clear_data_during_deallocation"]));
if (flags == ASExperimentalFeatureAll) {
return allNames;

View File

@@ -2,17 +2,9 @@
// ASImageNode+AnimatedImage.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
@@ -23,6 +15,7 @@
#import <AsyncDisplayKit/ASBaseDefines.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
#import <AsyncDisplayKit/ASEqualityHelpers.h>
#import <AsyncDisplayKit/ASImageNode+Private.h>
#import <AsyncDisplayKit/ASImageNode+AnimatedImagePrivate.h>
@@ -54,11 +47,13 @@ NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes;
- (void)_locked_setAnimatedImage:(id <ASAnimatedImageProtocol>)animatedImage
{
ASAssertLocked(__instanceLock__);
if (ASObjectIsEqual(_animatedImage, animatedImage) && (animatedImage == nil || animatedImage.playbackReady)) {
return;
}
id <ASAnimatedImageProtocol> previousAnimatedImage = _animatedImage;
__block id <ASAnimatedImageProtocol> previousAnimatedImage = _animatedImage;
_animatedImage = animatedImage;
@@ -79,22 +74,35 @@ NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes;
[self _locked_setShouldAnimate:YES];
}
} else {
// Clean up after ourselves.
self.contents = nil;
[self setCoverImage:nil];
// Clean up after ourselves.
// Don't bother using a `_locked` version for setting contnst as it should be pretty safe calling it with
// reaquire the lock and would add overhead to introduce this version
self.contents = nil;
[self _locked_setCoverImage:nil];
}
[self animatedImageSet:_animatedImage previousAnimatedImage:previousAnimatedImage];
// Push calling subclass to the next runloop cycle
// We have to schedule the block on the common modes otherwise the tracking mode will not be included and it will
// not fire e.g. while scrolling down
CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^(void) {
[self animatedImageSet:animatedImage previousAnimatedImage:previousAnimatedImage];
// Animated image can take while to dealloc, do it off the main queue
if (previousAnimatedImage != nil) {
ASPerformBackgroundDeallocation(&previousAnimatedImage);
}
// Animated image can take while to dealloc, do it off the main queue
if (previousAnimatedImage != nil) {
ASPerformBackgroundDeallocation(&previousAnimatedImage);
}
});
// Don't need to wakeup the runloop as the current is already running
// CFRunLoopWakeUp(runLoop); // Should not be necessary
}
- (void)animatedImageSet:(id <ASAnimatedImageProtocol>)newAnimatedImage previousAnimatedImage:(id <ASAnimatedImageProtocol>)previousAnimatedImage
{
//Subclasses may override
// Subclass hook should not be called with the lock held
ASAssertUnlocked(__instanceLock__);
// Subclasses may override
}
- (id <ASAnimatedImageProtocol>)animatedImage
@@ -128,6 +136,8 @@ NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes;
- (void)_locked_setCoverImageCompleted:(UIImage *)coverImage
{
ASAssertLocked(__instanceLock__);
_displayLinkLock.lock();
BOOL setCoverImage = (_displayLink == nil) || _displayLink.paused;
_displayLinkLock.unlock();
@@ -145,6 +155,8 @@ NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes;
- (void)_locked_setCoverImage:(UIImage *)coverImage
{
ASAssertLocked(__instanceLock__);
//If we're a network image node, we want to set the default image so
//that it will correctly be restored if it exits the range.
#ifndef MINIMAL_ASDK
@@ -185,6 +197,8 @@ NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes;
- (void)_locked_setShouldAnimate:(BOOL)shouldAnimate
{
ASAssertLocked(__instanceLock__);
// This test is explicitly done and not ASPerformBlockOnMainThread as this would perform the block immediately
// on main if called on main thread and we have to call methods locked or unlocked based on which thread we are on
if (ASDisplayNodeThreadIsMain()) {
@@ -218,6 +232,8 @@ NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes;
- (void)_locked_startAnimating
{
ASAssertLocked(__instanceLock__);
// It should be safe to call self.interfaceState in this case as it will only grab the lock of the superclass
if (!ASInterfaceStateIncludesVisible(self.interfaceState)) {
return;
@@ -261,6 +277,7 @@ NSString *const ASAnimatedImageDefaultRunLoopMode = NSRunLoopCommonModes;
- (void)_locked_stopAnimating
{
ASDisplayNodeAssertMainThread();
ASAssertLocked(__instanceLock__);
#if ASAnimatedImageDebug
NSLog(@"stopping animation: %p", self);

View File

@@ -2,17 +2,9 @@
// ASImageNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <UIKit/UIKit.h>
@@ -186,9 +178,8 @@ typedef UIImage * _Nullable (^asimagenode_modification_block_t)(UIImage *image);
*
* @discussion This method is for subclasses to override so they can know if an animated image
* has been set on the node.
* @warning this method is called with the node's lock held.
*/
- (void)animatedImageSet:(id <ASAnimatedImageProtocol>)newAnimatedImage previousAnimatedImage:(id <ASAnimatedImageProtocol>)previousAnimatedImage;
- (void)animatedImageSet:(nullable id <ASAnimatedImageProtocol>)newAnimatedImage previousAnimatedImage:(nullable id <ASAnimatedImageProtocol>)previousAnimatedImage ASDISPLAYNODE_REQUIRES_SUPER;
@end
#endif

View File

@@ -2,17 +2,9 @@
// ASImageNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASImageNode.h>
@@ -230,7 +222,7 @@ typedef void (^ASImageNodeDrawParametersBlock)(ASWeakMapEntry *entry);
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
{
auto image = ASLockedSelf(_image);
let image = ASLockedSelf(_image);
if (image == nil) {
return [super calculateSizeThatFits:constrainedSize];
@@ -249,6 +241,7 @@ typedef void (^ASImageNodeDrawParametersBlock)(ASWeakMapEntry *entry);
- (void)_locked_setImage:(UIImage *)image
{
ASAssertLocked(__instanceLock__);
if (ASObjectIsEqual(_image, image)) {
return;
}
@@ -334,7 +327,7 @@ typedef void (^ASImageNodeDrawParametersBlock)(ASWeakMapEntry *entry);
return drawParameters;
}
+ (UIImage *)displayWithParameters:(id<NSObject>)parameter isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled
+ (UIImage *)displayWithParameters:(id<NSObject>)parameter isCancelled:(NS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelled
{
ASImageNodeDrawParameters *drawParameter = (ASImageNodeDrawParameters *)parameter;
@@ -606,9 +599,8 @@ static ASDN::StaticMutex& cacheLock = *new ASDN::StaticMutex;
{
[super clearContents];
__instanceLock__.lock();
_weakCacheEntry = nil; // release contents from the cache.
__instanceLock__.unlock();
ASDN::MutexLocker l(__instanceLock__);
_weakCacheEntry = nil; // release contents from the cache.
}
#pragma mark - Cropping

View File

@@ -2,12 +2,8 @@
// ASLocking.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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>
@@ -107,7 +103,7 @@ NS_INLINE void ASUnlockSet(ASLockSet *lockSet) {
*/
NS_INLINE ASLockSet ASLockSequence(NS_NOESCAPE ASLockSequenceBlock body)
{
__block ASLockSet locks = (ASLockSet){0};
__block ASLockSet locks = (ASLockSet){0, {}};
BOOL (^addLock)(id<ASLocking>) = ^(id<ASLocking> obj) {
// nil lock = ignore.

View File

@@ -2,12 +2,8 @@
// ASMainThreadDeallocation.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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>

View File

@@ -2,12 +2,8 @@
// ASMainThreadDeallocation.mm
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASMainThreadDeallocation.h>
@@ -146,7 +142,7 @@
+ (BOOL)needsMainThreadDeallocation
{
auto name = class_getName(self);
let name = class_getName(self);
if (0 == strncmp(name, "AV", 2) || 0 == strncmp(name, "UI", 2) || 0 == strncmp(name, "CA", 2)) {
return YES;
}

View File

@@ -2,23 +2,16 @@
// ASMapNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASAvailability.h>
#if TARGET_OS_IOS && AS_USE_MAPKIT
#import <AsyncDisplayKit/ASImageNode.h>
#if TARGET_OS_IOS
#import <MapKit/MapKit.h>
NS_ASSUME_NONNULL_BEGIN
@@ -97,5 +90,3 @@ typedef NS_OPTIONS(NSUInteger, ASMapNodeShowAnnotationsOptions)
NS_ASSUME_NONNULL_END
#endif
#endif

View File

@@ -2,26 +2,15 @@
// ASMapNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
#import <Foundation/Foundation.h>
#if TARGET_OS_IOS
#import <AsyncDisplayKit/ASMapNode.h>
#if TARGET_OS_IOS && AS_USE_MAPKIT
#import <tgmath.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
@@ -450,6 +439,4 @@
}
@end
#endif
#endif
#endif // TARGET_OS_IOS && AS_USE_MAPKIT

View File

@@ -2,17 +2,9 @@
// ASMultiplexImageNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,22 +2,14 @@
// ASMultiplexImageNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
#import <AsyncDisplayKit/ASMultiplexImageNode.h>
#if TARGET_OS_IOS
#if TARGET_OS_IOS && AS_USE_ASSETS_LIBRARY
#import <AssetsLibrary/AssetsLibrary.h>
#endif
@@ -25,12 +17,15 @@
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASPhotosFrameworkImageRequest.h>
#import <AsyncDisplayKit/ASEqualityHelpers.h>
#import <AsyncDisplayKit/ASInternalHelpers.h>
#import <AsyncDisplayKit/ASLog.h>
#import <AsyncDisplayKit/ASThread.h>
#if AS_USE_PHOTOS
#import <AsyncDisplayKit/ASPhotosFrameworkImageRequest.h>
#endif
#if AS_PIN_REMOTE_IMAGE
#import <AsyncDisplayKit/ASPINRemoteImageDownloader.h>
#else
@@ -39,7 +34,9 @@
NSString *const ASMultiplexImageNodeErrorDomain = @"ASMultiplexImageNodeErrorDomain";
#if AS_USE_ASSETS_LIBRARY
static NSString *const kAssetsLibraryURLScheme = @"assets-library";
#endif
static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
@@ -133,7 +130,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
*/
- (void)_fetchImageWithIdentifierFromCache:(id)imageIdentifier URL:(NSURL *)imageURL completion:(void (^)(UIImage *image))completionBlock;
#if TARGET_OS_IOS
#if TARGET_OS_IOS && AS_USE_ASSETS_LIBRARY
/**
@abstract Loads the image corresponding to the given assetURL from the device's Assets Library.
@param imageIdentifier The identifier for the image to be loaded. May not be nil.
@@ -143,6 +140,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
- (void)_loadALAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock;
#endif
#if AS_USE_PHOTOS
/**
@abstract Loads the image corresponding to the given image request from the Photos framework.
@param imageIdentifier The identifier for the image to be loaded. May not be nil.
@@ -150,6 +148,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
@param completionBlock The block to be performed when the image has been loaded, if possible. May not be nil.
*/
- (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock API_AVAILABLE(ios(8.0), tvos(10.0));
#endif
/**
@abstract Downloads the image corresponding to the given imageIdentifier from the given URL.
@@ -413,8 +412,11 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
#pragma mark - Core Internal
- (void)_setDisplayedImageIdentifier:(id)displayedImageIdentifier withImage:(UIImage *)image
{
if (ASObjectIsEqual(displayedImageIdentifier, _displayedImageIdentifier))
ASDisplayNodeAssertMainThread();
if (ASObjectIsEqual(_displayedImageIdentifier, displayedImageIdentifier)) {
return;
}
_displayedImageIdentifier = displayedImageIdentifier;
@@ -620,7 +622,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
return;
}
#if TARGET_OS_IOS
#if TARGET_OS_IOS && AS_USE_ASSETS_LIBRARY
// If it's an assets-library URL, we need to fetch it from the assets library.
if ([[nextImageURL scheme] isEqualToString:kAssetsLibraryURLScheme]) {
// Load the asset.
@@ -633,6 +635,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
}
#endif
#if AS_USE_PHOTOS
if (AS_AVAILABLE_IOS_TVOS(9, 10)) {
// Likewise, if it's a Photos asset, we need to fetch it accordingly.
if (ASPhotosFrameworkImageRequest *request = [ASPhotosFrameworkImageRequest requestWithURL:nextImageURL]) {
@@ -644,6 +647,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
return;
}
}
#endif
// Otherwise, it's a web URL that we can download.
// First, check the cache.
@@ -677,7 +681,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
}];
}];
}
#if TARGET_OS_IOS
#if TARGET_OS_IOS && AS_USE_ASSETS_LIBRARY
- (void)_loadALAssetWithIdentifier:(id)imageIdentifier URL:(NSURL *)assetURL completion:(void (^)(UIImage *image, NSError *error))completionBlock
{
ASDisplayNodeAssertNotNil(imageIdentifier, @"imageIdentifier is required");
@@ -702,6 +706,8 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
#pragma clang diagnostic pop
}
#endif
#if AS_USE_PHOTOS
- (void)_loadPHAssetWithRequest:(ASPhotosFrameworkImageRequest *)request identifier:(id)imageIdentifier completion:(void (^)(UIImage *image, NSError *error))completionBlock
{
ASDisplayNodeAssertNotNil(imageIdentifier, @"imageIdentifier is required");
@@ -789,6 +795,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
_phImageRequestOperation = newImageRequestOp;
[phImageRequestQueue addOperation:newImageRequestOp];
}
#endif
- (void)_fetchImageWithIdentifierFromCache:(id)imageIdentifier URL:(NSURL *)imageURL completion:(void (^)(UIImage *image))completionBlock
{
@@ -892,6 +899,7 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
@end
#if AS_USE_PHOTOS
@implementation NSURL (ASPhotosFrameworkURLs)
+ (NSURL *)URLWithAssetLocalIdentifier:(NSString *)assetLocalIdentifier targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(PHImageRequestOptions *)options NS_RETURNS_RETAINED

View File

@@ -2,17 +2,9 @@
// ASNavigationController.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASNavigationController.m
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
#import <AsyncDisplayKit/ASNavigationController.h>

View File

@@ -2,12 +2,8 @@
// ASNetworkImageLoadInfo.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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>

View File

@@ -2,12 +2,8 @@
// ASNetworkImageLoadInfo.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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASNetworkImageLoadInfo.h>

View File

@@ -2,17 +2,9 @@
// ASNetworkImageNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
@@ -58,6 +50,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nullable, weak) id<ASNetworkImageNodeDelegate> delegate;
/**
* The delegate will receive callbacks on main thread. Default to YES.
*/
@property (class) BOOL useMainThreadDelegateCallbacks;
/**
* The image to display.
*
@@ -158,7 +155,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param image The newly-loaded image.
* @param info Additional information about the image load.
*
* @discussion Called on a background queue.
* @discussion Called on the main thread if useMainThreadDelegateCallbacks=YES (the default), otherwise on a background thread.
*/
- (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image info:(ASNetworkImageLoadInfo *)info;
@@ -168,7 +165,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param imageNode The sender.
* @param image The newly-loaded image.
*
* @discussion Called on a background queue.
* @discussion Called on the main thread if useMainThreadDelegateCallbacks=YES (the default), otherwise on a background thread.
*/
- (void)imageNode:(ASNetworkImageNode *)imageNode didLoadImage:(UIImage *)image;
@@ -187,7 +184,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param imageNode The sender.
* @param error The error with details.
*
* @discussion Called on a background queue.
* @discussion Called on the main thread if useMainThreadDelegateCallbacks=YES (the default), otherwise on a background thread.
*/
- (void)imageNode:(ASNetworkImageNode *)imageNode didFailWithError:(NSError *)error;

60
Source/ASNetworkImageNode.mm Executable file → Normal file
View File

@@ -2,17 +2,9 @@
// ASNetworkImageNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
@@ -21,6 +13,7 @@
#import <AsyncDisplayKit/ASAvailability.h>
#import <AsyncDisplayKit/ASBasicImageDownloader.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASEqualityHelpers.h>
@@ -86,6 +79,8 @@
@implementation ASNetworkImageNode
static std::atomic_bool _useMainThreadDelegateCallbacks(true);
@dynamic image;
- (instancetype)initWithCache:(id<ASImageCacheProtocol>)cache downloader:(id<ASImageDownloaderProtocol>)downloader
@@ -150,6 +145,8 @@
- (void)_locked_setImage:(UIImage *)image
{
ASAssertLocked(__instanceLock__);
BOOL imageWasSetExternally = (image != nil);
BOOL shouldCancelAndClear = imageWasSetExternally && (imageWasSetExternally != _imageWasSetExternally);
_imageWasSetExternally = imageWasSetExternally;
@@ -176,6 +173,7 @@
- (void)_locked__setImage:(UIImage *)image
{
ASAssertLocked(__instanceLock__);
[super _locked_setImage:image];
}
@@ -352,7 +350,7 @@
// Call out to the delegate.
if (_delegateFlags.delegateDidLoadImageWithInfo) {
ASUnlockScope(self);
auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:url sourceType:ASNetworkImageSourceSynchronousCache downloadIdentifier:nil userInfo:nil];
let info = [[ASNetworkImageLoadInfo alloc] initWithURL:url sourceType:ASNetworkImageSourceSynchronousCache downloadIdentifier:nil userInfo:nil];
[_delegate imageNode:self didLoadImage:result info:info];
} else if (_delegateFlags.delegateDidLoadImage) {
ASUnlockScope(self);
@@ -427,6 +425,16 @@
[self _lazilyLoadImageIfNecessary];
}
+ (void)setUseMainThreadDelegateCallbacks:(BOOL)useMainThreadDelegateCallbacks
{
_useMainThreadDelegateCallbacks = useMainThreadDelegateCallbacks;
}
+ (BOOL)useMainThreadDelegateCallbacks
{
return _useMainThreadDelegateCallbacks;
}
#pragma mark - Progress
- (void)handleProgressImage:(UIImage *)progressImage progress:(CGFloat)progress downloadIdentifier:(nullable id)downloadIdentifier
@@ -509,6 +517,8 @@
- (void)_locked_cancelDownloadAndClearImageWithResumePossibility:(BOOL)storeResume
{
ASAssertLocked(__instanceLock__);
[self _locked_cancelImageDownloadWithResumePossibility:storeResume];
[self _locked_setAnimatedImage:nil];
@@ -533,6 +543,8 @@
- (void)_locked_cancelImageDownloadWithResumePossibility:(BOOL)storeResume
{
ASAssertLocked(__instanceLock__);
if (!_downloadIdentifier) {
return;
}
@@ -630,7 +642,7 @@
} else {
// First try to load the path directly, for efficiency assuming a developer who
// doesn't want caching is trying to be as minimal as possible.
auto nonAnimatedImage = [[UIImage alloc] initWithContentsOfFile:URL.path];
var nonAnimatedImage = [[UIImage alloc] initWithContentsOfFile:URL.path];
if (nonAnimatedImage == nil) {
// If we couldn't find it, execute an -imageNamed:-like search so we can find resources even if the
// extension is not provided in the path. This allows the same path to work regardless of shouldCacheImage.
@@ -643,7 +655,7 @@
// If the file may be an animated gif and then created an animated image.
id<ASAnimatedImageProtocol> animatedImage = nil;
if (_downloaderFlags.downloaderImplementsAnimatedImage) {
auto data = [[NSData alloc] initWithContentsOfURL:URL];
let data = [[NSData alloc] initWithContentsOfURL:URL];
if (data != nil) {
animatedImage = [_downloader animatedImageWithData:data];
@@ -666,7 +678,7 @@
if (_delegateFlags.delegateDidLoadImageWithInfo) {
ASUnlockScope(self);
auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:ASNetworkImageSourceFileURL downloadIdentifier:nil userInfo:nil];
let info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:ASNetworkImageSourceFileURL downloadIdentifier:nil userInfo:nil];
[delegate imageNode:self didLoadImage:self.image info:info];
} else if (_delegateFlags.delegateDidLoadImage) {
ASUnlockScope(self);
@@ -675,7 +687,7 @@
});
} else {
__weak __typeof__(self) weakSelf = self;
auto finished = ^(id <ASImageContainerProtocol>imageContainer, NSError *error, id downloadIdentifier, ASNetworkImageSourceType imageSource, id userInfo) {
let finished = ^(id <ASImageContainerProtocol>imageContainer, NSError *error, id downloadIdentifier, ASNetworkImageSourceType imageSource, id userInfo) {
ASPerformBlockOnBackgroundThread(^{
__typeof__(self) strongSelf = weakSelf;
if (strongSelf == nil) {
@@ -721,7 +733,7 @@
if (newImage) {
if (_delegateFlags.delegateDidLoadImageWithInfo) {
calloutBlock = ^(ASNetworkImageNode *strongSelf) {
auto info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:imageSource downloadIdentifier:downloadIdentifier userInfo:userInfo];
let info = [[ASNetworkImageLoadInfo alloc] initWithURL:URL sourceType:imageSource downloadIdentifier:downloadIdentifier userInfo:userInfo];
[delegate imageNode:strongSelf didLoadImage:newImage info:info];
};
} else if (_delegateFlags.delegateDidLoadImage) {
@@ -736,11 +748,15 @@
}
if (calloutBlock) {
ASPerformBlockOnMainThread(^{
if (auto strongSelf = weakSelf) {
calloutBlock(strongSelf);
}
});
if (ASNetworkImageNode.useMainThreadDelegateCallbacks) {
ASPerformBlockOnMainThread(^{
if (auto strongSelf = weakSelf) {
calloutBlock(strongSelf);
}
});
} else {
calloutBlock(self);
}
}
});
};

View File

@@ -2,17 +2,9 @@
// ASNodeController+Beta.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNode.h>
@@ -46,6 +38,8 @@
- (void)interfaceStateDidChange:(ASInterfaceState)newState
fromState:(ASInterfaceState)oldState ASDISPLAYNODE_REQUIRES_SUPER;
- (void)hierarchyDisplayDidFinish ASDISPLAYNODE_REQUIRES_SUPER;
@end
@interface ASDisplayNode (ASNodeController)

View File

@@ -1,149 +0,0 @@
//
// ASNodeController+Beta.m
// 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 /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,
// 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 <AsyncDisplayKit/ASWeakProxy.h>
#import <AsyncDisplayKit/ASNodeController+Beta.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#define _node (_shouldInvertStrongReference ? _weakNode : _strongNode)
@interface ASDisplayNode (ASNodeControllerOwnership)
// This property exists for debugging purposes. Don't use __nodeController in production code.
@property (nonatomic, readonly) ASNodeController *__nodeController;
// These setters are mutually exclusive. Setting one will clear the relationship of the other.
- (void)__setNodeControllerStrong:(ASNodeController *)nodeController;
- (void)__setNodeControllerWeak:(ASNodeController *)nodeController;
@end
@implementation ASNodeController
{
ASDisplayNode *_strongNode;
__weak ASDisplayNode *_weakNode;
}
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
- (void)loadNode
{
self.node = [[ASDisplayNode alloc] init];
}
- (ASDisplayNode *)node
{
if (_node == nil) {
[self loadNode];
}
return _node;
}
- (void)setupReferencesWithNode:(ASDisplayNode *)node
{
if (_shouldInvertStrongReference) {
// The node should own the controller; weak reference from controller to node.
_weakNode = node;
[node __setNodeControllerStrong:self];
_strongNode = nil;
} else {
// The controller should own the node; weak reference from node to controller.
_strongNode = node;
[node __setNodeControllerWeak:self];
_weakNode = nil;
}
node.interfaceStateDelegate = self;
}
- (void)setNode:(ASDisplayNode *)node
{
[self setupReferencesWithNode:node];
}
- (void)setShouldInvertStrongReference:(BOOL)shouldInvertStrongReference
{
if (_shouldInvertStrongReference != shouldInvertStrongReference) {
// Because the BOOL controls which ivar we access, get the node before toggling.
ASDisplayNode *node = _node;
_shouldInvertStrongReference = shouldInvertStrongReference;
[self setupReferencesWithNode:node];
}
}
// subclass overrides
- (void)nodeDidLoad {}
- (void)nodeDidLayout {}
- (void)didEnterVisibleState {}
- (void)didExitVisibleState {}
- (void)didEnterDisplayState {}
- (void)didExitDisplayState {}
- (void)didEnterPreloadState {}
- (void)didExitPreloadState {}
- (void)interfaceStateDidChange:(ASInterfaceState)newState
fromState:(ASInterfaceState)oldState {}
@end
@implementation ASDisplayNode (ASNodeControllerOwnership)
- (ASNodeController *)__nodeController
{
ASNodeController *nodeController = nil;
id object = objc_getAssociatedObject(self, @selector(__nodeController));
if ([object isKindOfClass:[ASWeakProxy class]]) {
nodeController = (ASNodeController *)[(ASWeakProxy *)object target];
} else {
nodeController = (ASNodeController *)object;
}
return nodeController;
}
- (void)__setNodeControllerStrong:(ASNodeController *)nodeController
{
objc_setAssociatedObject(self, @selector(__nodeController), nodeController, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)__setNodeControllerWeak:(ASNodeController *)nodeController
{
// Associated objects don't support weak references. Since assign can become a dangling pointer, use ASWeakProxy.
ASWeakProxy *nodeControllerProxy = [ASWeakProxy weakProxyWithTarget:nodeController];
objc_setAssociatedObject(self, @selector(__nodeController), nodeControllerProxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
@implementation ASDisplayNode (ASNodeController)
- (ASNodeController *)nodeController {
return self.__nodeController;
}
@end

View File

@@ -0,0 +1,93 @@
//
// ASNodeController+Beta.mm
// Texture
//
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASInternalHelpers.h>
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASNodeController+Beta.h>
#define _node (_shouldInvertStrongReference ? _weakNode : _strongNode)
@implementation ASNodeController
{
ASDisplayNode *_strongNode;
__weak ASDisplayNode *_weakNode;
}
- (void)loadNode
{
self.node = [[ASDisplayNode alloc] init];
}
- (ASDisplayNode *)node
{
if (_node == nil) {
[self loadNode];
}
return _node;
}
- (void)setupReferencesWithNode:(ASDisplayNode *)node
{
if (_shouldInvertStrongReference) {
// The node should own the controller; weak reference from controller to node.
_weakNode = node;
_strongNode = nil;
} else {
// The controller should own the node; weak reference from node to controller.
_strongNode = node;
_weakNode = nil;
}
[node __setNodeController:self];
[node addInterfaceStateDelegate:self];
}
- (void)setNode:(ASDisplayNode *)node
{
[self setupReferencesWithNode:node];
}
- (void)setShouldInvertStrongReference:(BOOL)shouldInvertStrongReference
{
if (_shouldInvertStrongReference != shouldInvertStrongReference) {
// Because the BOOL controls which ivar we access, get the node before toggling.
ASDisplayNode *node = _node;
_shouldInvertStrongReference = shouldInvertStrongReference;
[self setupReferencesWithNode:node];
}
}
// subclass overrides
- (void)nodeDidLoad {}
- (void)nodeDidLayout {}
- (void)didEnterVisibleState {}
- (void)didExitVisibleState {}
- (void)didEnterDisplayState {}
- (void)didExitDisplayState {}
- (void)didEnterPreloadState {}
- (void)didExitPreloadState {}
- (void)interfaceStateDidChange:(ASInterfaceState)newState
fromState:(ASInterfaceState)oldState {}
- (void)hierarchyDisplayDidFinish {}
@end
@implementation ASDisplayNode (ASNodeController)
- (ASNodeController *)nodeController {
return _weakNodeController ?: _strongNodeController;
}
@end

View File

@@ -2,17 +2,9 @@
// ASPagerFlowLayout.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASPagerFlowLayout.m
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,12 +2,8 @@
// ASPagerNode+Beta.h
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASPagerNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASPagerNode.m
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,12 +2,8 @@
// ASRangeManagingNode.h
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>

View File

@@ -2,17 +2,9 @@
// ASRunLoopQueue.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>

View File

@@ -2,17 +2,9 @@
// ASRunLoopQueue.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASAvailability.h>
@@ -39,172 +31,21 @@ static void runLoopSourceCallback(void *info) {
#pragma mark - ASDeallocQueue
@interface ASDeallocQueueV1 : ASDeallocQueue
@end
@interface ASDeallocQueueV2 : ASDeallocQueue
@end
@implementation ASDeallocQueue
@implementation ASDeallocQueue {
std::vector<CFTypeRef> _queue;
ASDN::Mutex _lock;
}
+ (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED
{
static ASDeallocQueue *deallocQueue = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (ASActivateExperimentalFeature(ASExperimentalDeallocQueue)) {
deallocQueue = [[ASDeallocQueueV2 alloc] init];
} else {
deallocQueue = [[ASDeallocQueueV1 alloc] init];
}
deallocQueue = [[ASDeallocQueue alloc] init];
});
return deallocQueue;
}
- (void)releaseObjectInBackground:(id _Nullable __strong *)objectPtr
{
ASDisplayNodeFailAssert(@"Abstract method.");
}
@end
@implementation ASDeallocQueueV1 {
NSThread *_thread;
NSCondition *_condition;
std::deque<id> _queue;
ASDN::RecursiveMutex _queueLock;
}
- (void)releaseObjectInBackground:(id _Nullable __strong *)objectPtr
{
if (objectPtr != NULL && *objectPtr != nil) {
ASDN::MutexLocker l(_queueLock);
_queue.push_back(*objectPtr);
*objectPtr = nil;
}
}
- (void)threadMain
{
@autoreleasepool {
__unsafe_unretained __typeof__(self) weakSelf = self;
// 100ms timer. No resources are wasted in between, as the thread sleeps, and each check is fast.
// This time is fast enough for most use cases without excessive churn.
CFRunLoopTimerRef timer = CFRunLoopTimerCreateWithHandler(NULL, -1, 0.1, 0, 0, ^(CFRunLoopTimerRef timer) {
weakSelf->_queueLock.lock();
if (weakSelf->_queue.size() == 0) {
weakSelf->_queueLock.unlock();
return;
}
// The scope below is entered while already locked. @autorelease is crucial here; see PR 2890.
NSInteger count;
@autoreleasepool {
#if ASRunLoopQueueLoggingEnabled
NSLog(@"ASDeallocQueue Processing: %lu objects destroyed", weakSelf->_queue.size());
#endif
// Sometimes we release 10,000 objects at a time. Don't hold the lock while releasing.
std::deque<id> currentQueue = weakSelf->_queue;
count = currentQueue.size();
ASSignpostStartCustom(ASSignpostDeallocQueueDrain, self, count);
weakSelf->_queue = std::deque<id>();
weakSelf->_queueLock.unlock();
currentQueue.clear();
}
ASSignpostEndCustom(ASSignpostDeallocQueueDrain, self, count, ASSignpostColorDefault);
});
CFRunLoopRef runloop = CFRunLoopGetCurrent();
CFRunLoopAddTimer(runloop, timer, kCFRunLoopCommonModes);
[_condition lock];
[_condition signal];
// At this moment, -init is signalled that the thread is guaranteed to be finished starting.
[_condition unlock];
// Keep processing events until the runloop is stopped.
CFRunLoopRun();
CFRunLoopTimerInvalidate(timer);
CFRunLoopRemoveTimer(runloop, timer, kCFRunLoopCommonModes);
CFRelease(timer);
[_condition lock];
[_condition signal];
// At this moment, -stop is signalled that the thread is guaranteed to be finished exiting.
[_condition unlock];
}
}
- (instancetype)init
{
if ((self = [super init])) {
_condition = [[NSCondition alloc] init];
_thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadMain) object:nil];
_thread.name = @"ASDeallocQueue";
// Use condition to ensure NSThread has finished starting.
[_condition lock];
[_thread start];
[_condition wait];
[_condition unlock];
}
return self;
}
- (void)stop
{
if (!_thread) {
return;
}
[_condition lock];
[self performSelector:@selector(_stop) onThread:_thread withObject:nil waitUntilDone:NO];
[_condition wait];
// At this moment, the thread is guaranteed to be finished running.
[_condition unlock];
_thread = nil;
}
- (void)drain
{
[self performSelector:@selector(_drain) onThread:_thread withObject:nil waitUntilDone:YES];
}
- (void)_drain
{
while (true) {
@autoreleasepool {
_queueLock.lock();
std::deque<id> currentQueue = _queue;
_queue = std::deque<id>();
_queueLock.unlock();
if (currentQueue.empty()) {
return;
} else {
currentQueue.clear();
}
}
}
}
- (void)_stop
{
CFRunLoopStop(CFRunLoopGetCurrent());
}
- (void)dealloc
{
[self stop];
}
@end
@implementation ASDeallocQueueV2 {
std::vector<CFTypeRef> _queue;
ASDN::Mutex _lock;
}
- (void)dealloc
{
ASDisplayNodeFailAssert(@"Singleton should not dealloc.");
@@ -215,13 +56,13 @@ static void runLoopSourceCallback(void *info) {
NSParameterAssert(objectPtr != NULL);
// Cast to CFType so we can manipulate retain count manually.
auto cfPtr = (CFTypeRef *)(void *)objectPtr;
let cfPtr = (CFTypeRef *)(void *)objectPtr;
if (!cfPtr || !*cfPtr) {
return;
}
_lock.lock();
auto isFirstEntry = _queue.empty();
let isFirstEntry = _queue.empty();
// Push the pointer into our queue and clear their pointer.
// This "steals" the +1 from ARC and nils their pointer so they can't
// access or release the object.
@@ -239,9 +80,9 @@ static void runLoopSourceCallback(void *info) {
- (void)drain
{
_lock.lock();
auto q = std::move(_queue);
let q = std::move(_queue);
_lock.unlock();
for (auto ref : q) {
for (let ref : q) {
// NOTE: Could check that retain count is 1 and retry later if not.
CFRelease(ref);
}
@@ -249,85 +90,18 @@ static void runLoopSourceCallback(void *info) {
@end
#if AS_KDEBUG_ENABLE
/**
* This is real, private CA API. Valid as of iOS 10.
*/
typedef enum {
kCATransactionPhasePreLayout,
kCATransactionPhasePreCommit,
kCATransactionPhasePostCommit,
} CATransactionPhase;
@interface CATransaction (Private)
+ (void)addCommitHandler:(void(^)(void))block forPhase:(CATransactionPhase)phase;
+ (int)currentState;
@end
#endif
#pragma mark - ASAbstractRunLoopQueue
@interface ASAbstractRunLoopQueue (Private)
+ (void)load;
+ (void)registerCATransactionObservers;
@end
@implementation ASAbstractRunLoopQueue
- (instancetype)init
{
if (self != [super init]) {
self = [super init];
if (self == nil) {
return nil;
}
ASDisplayNodeAssert(self.class != [ASAbstractRunLoopQueue class], @"Should never create instances of abstract class ASAbstractRunLoopQueue.");
return self;
}
#if AS_KDEBUG_ENABLE
+ (void)load
{
[self registerCATransactionObservers];
}
+ (void)registerCATransactionObservers
{
static BOOL privateCAMethodsExist;
static dispatch_block_t preLayoutHandler;
static dispatch_block_t preCommitHandler;
static dispatch_block_t postCommitHandler;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
privateCAMethodsExist = [CATransaction respondsToSelector:@selector(addCommitHandler:forPhase:)];
privateCAMethodsExist &= [CATransaction respondsToSelector:@selector(currentState)];
if (!privateCAMethodsExist) {
NSLog(@"Private CA methods are gone.");
}
preLayoutHandler = ^{
ASSignpostStartCustom(ASSignpostCATransactionLayout, 0, [CATransaction currentState]);
};
preCommitHandler = ^{
int state = [CATransaction currentState];
ASSignpostEndCustom(ASSignpostCATransactionLayout, 0, state, ASSignpostColorDefault);
ASSignpostStartCustom(ASSignpostCATransactionCommit, 0, state);
};
postCommitHandler = ^{
ASSignpostEndCustom(ASSignpostCATransactionCommit, 0, [CATransaction currentState], ASSignpostColorDefault);
// Can't add new observers inside an observer. rdar://problem/31253952
dispatch_async(dispatch_get_main_queue(), ^{
[self registerCATransactionObservers];
});
};
});
if (privateCAMethodsExist) {
[CATransaction addCommitHandler:preLayoutHandler forPhase:kCATransactionPhasePreLayout];
[CATransaction addCommitHandler:preCommitHandler forPhase:kCATransactionPhasePreCommit];
[CATransaction addCommitHandler:postCommitHandler forPhase:kCATransactionPhasePostCommit];
}
}
#endif // AS_KDEBUG_ENABLE
@end
#pragma mark - ASRunLoopQueue
@@ -482,11 +256,11 @@ typedef enum {
}
// itemsToProcess will be empty if _queueConsumer == nil so no need to check again.
auto count = itemsToProcess.size();
let count = itemsToProcess.size();
if (count > 0) {
as_activity_scope_verbose(as_activity_create("Process run loop queue batch", _rootActivity, OS_ACTIVITY_FLAG_DEFAULT));
auto itemsEnd = itemsToProcess.cend();
for (auto iterator = itemsToProcess.begin(); iterator < itemsEnd; iterator++) {
let itemsEnd = itemsToProcess.cend();
for (var iterator = itemsToProcess.begin(); iterator < itemsEnd; iterator++) {
__unsafe_unretained id value = *iterator;
_queueConsumer(value, isQueueDrained && iterator == itemsEnd - 1);
as_log_verbose(ASDisplayLog(), "processed %@", value);
@@ -705,11 +479,11 @@ static int const kASASCATransactionQueuePostOrder = 3000000;
}
// itemsToProcess will be empty if _queueConsumer == nil so no need to check again.
auto count = itemsToProcess.size();
let count = itemsToProcess.size();
if (count > 0) {
as_activity_scope_verbose(as_activity_create("Process run loop queue batch", _rootActivity, OS_ACTIVITY_FLAG_DEFAULT));
auto itemsEnd = itemsToProcess.cend();
for (auto iterator = itemsToProcess.begin(); iterator < itemsEnd; iterator++) {
let itemsEnd = itemsToProcess.cend();
for (var iterator = itemsToProcess.begin(); iterator < itemsEnd; iterator++) {
__unsafe_unretained id value = *iterator;
[value prepareForCATransactionCommit];
as_log_verbose(ASDisplayLog(), "processed %@", value);

View File

@@ -2,17 +2,9 @@
// ASScrollNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNode.h>

View File

@@ -2,17 +2,9 @@
// ASScrollNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASScrollNode.h>

View File

@@ -2,17 +2,9 @@
// ASSectionController.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASSupplementaryNodeSource.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASTabBarController.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASTabBarController.m
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,12 +2,8 @@
// ASTableNode+Beta.h
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASTableNode.h>

View File

@@ -2,17 +2,9 @@
// ASTableNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
#import <AsyncDisplayKit/ASBlockTypes.h>
@@ -39,8 +31,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (readonly) ASTableView *view;
// These properties can be set without triggering the view to be created, so it's fine to set them in -init.
@property (nullable, weak, nonatomic) id <ASTableDelegate> delegate;
@property (nullable, weak, nonatomic) id <ASTableDataSource> dataSource;
@property (nonatomic, weak) id <ASTableDelegate> delegate;
@property (nonatomic, weak) id <ASTableDataSource> dataSource;
/**
* The number of screens left to scroll before the delegate -tableNode:beginBatchFetchingWithContext: is called.

View File

@@ -2,17 +2,9 @@
// ASTableNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
@@ -34,9 +26,12 @@
#pragma mark - _ASTablePendingState
@interface _ASTablePendingState : NSObject
@property (weak, nonatomic) id <ASTableDelegate> delegate;
@property (weak, nonatomic) id <ASTableDataSource> dataSource;
@interface _ASTablePendingState : NSObject {
@public
std::vector<std::vector<ASRangeTuningParameters>> _tuningParameters;
}
@property (nonatomic, weak) id <ASTableDelegate> delegate;
@property (nonatomic, weak) id <ASTableDataSource> dataSource;
@property (nonatomic) ASLayoutRangeMode rangeMode;
@property (nonatomic) BOOL allowsSelection;
@property (nonatomic) BOOL allowsSelectionDuringEditing;
@@ -48,14 +43,19 @@
@property (nonatomic) CGPoint contentOffset;
@property (nonatomic) BOOL animatesContentOffset;
@property (nonatomic) BOOL automaticallyAdjustsContentOffset;
@end
@implementation _ASTablePendingState
#pragma mark - Lifecycle
- (instancetype)init
{
self = [super init];
if (self) {
_rangeMode = ASLayoutRangeModeUnspecified;
_tuningParameters = std::vector<std::vector<ASRangeTuningParameters>> (ASLayoutRangeModeCount, std::vector<ASRangeTuningParameters> (ASLayoutRangeTypeCount, ASRangeTuningParametersZero));
_allowsSelection = YES;
_allowsSelectionDuringEditing = NO;
_allowsMultipleSelection = NO;
@@ -70,6 +70,30 @@
return self;
}
#pragma mark Tuning Parameters
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
{
return [self tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
}
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
{
return [self setTuningParameters:tuningParameters forRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
}
- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
{
ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(), @"Requesting a range that is OOB for the configured tuning parameters");
return _tuningParameters[rangeMode][rangeType];
}
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
{
ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(), @"Setting a range that is OOB for the configured tuning parameters");
_tuningParameters[rangeMode][rangeType] = tuningParameters;
}
@end
#pragma mark - ASTableView
@@ -81,6 +105,7 @@
}
@property (nonatomic) _ASTablePendingState *pendingState;
@property (nonatomic, weak) ASRangeController *rangeController;
@end
@implementation ASTableNode
@@ -126,8 +151,10 @@
ASTableView *view = self.view;
view.tableNode = self;
_rangeController = view.rangeController;
if (_pendingState) {
_ASTablePendingState *pendingState = _pendingState;
_ASTablePendingState *pendingState = _pendingState;
view.asyncDelegate = pendingState.delegate;
view.asyncDataSource = pendingState.dataSource;
view.inverted = pendingState.inverted;
@@ -138,8 +165,23 @@
view.contentInset = pendingState.contentInset;
self.pendingState = nil;
let tuningParametersVector = pendingState->_tuningParameters;
let tuningParametersVectorSize = tuningParametersVector.size();
for (NSInteger rangeMode = 0; rangeMode < tuningParametersVectorSize; rangeMode++) {
let tuningparametersRangeModeVector = tuningParametersVector[rangeMode];
let tuningParametersVectorRangeModeSize = tuningparametersRangeModeVector.size();
for (NSInteger rangeType = 0; rangeType < tuningParametersVectorRangeModeSize; rangeType++) {
ASRangeTuningParameters tuningParameters = tuningparametersRangeModeVector[rangeType];
if (!ASRangeTuningParametersEqualToRangeTuningParameters(tuningParameters, ASRangeTuningParametersZero)) {
[_rangeController setTuningParameters:tuningParameters
forRangeMode:(ASLayoutRangeMode)rangeMode
rangeType:(ASLayoutRangeType)rangeType];
}
}
}
if (pendingState.rangeMode != ASLayoutRangeModeUnspecified) {
[view.rangeController updateCurrentRangeWithMode:pendingState.rangeMode];
[_rangeController updateCurrentRangeWithMode:pendingState.rangeMode];
}
[view setContentOffset:pendingState.contentOffset animated:pendingState.animatesContentOffset];
@@ -168,7 +210,7 @@
[super didEnterPreloadState];
// Intentionally allocate the view here and trigger a layout pass on it, which in turn will trigger the intial data load.
// We can get rid of this call later when ASDataController, ASRangeController and ASCollectionLayout can operate without the view.
[[self view] layoutIfNeeded];
[self.view layoutIfNeeded];
}
#if ASRangeControllerLoggingEnabled
@@ -199,12 +241,6 @@
return self.view.dataController;
}
// TODO: Implement this without the view.
- (ASRangeController *)rangeController
{
return self.view.rangeController;
}
- (_ASTablePendingState *)pendingState
{
if (!_pendingState && ![self isNodeLoaded]) {
@@ -485,22 +521,30 @@ ASLayoutElementCollectionTableSetTraitCollection(_environmentStateLock)
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
{
return [self.rangeController tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
return [self tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
}
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
{
[self.rangeController setTuningParameters:tuningParameters forRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
[self setTuningParameters:tuningParameters forRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
}
- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
{
return [self.rangeController tuningParametersForRangeMode:rangeMode rangeType:rangeType];
if ([self pendingState]) {
return [_pendingState tuningParametersForRangeMode:rangeMode rangeType:rangeType];
} else {
return [self.rangeController tuningParametersForRangeMode:rangeMode rangeType:rangeType];
}
}
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
{
return [self.rangeController setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType];
if ([self pendingState]) {
[_pendingState setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType];
} else {
return [self.rangeController setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType];
}
}
#pragma mark - Selection
@@ -686,7 +730,7 @@ ASLayoutElementCollectionTableSetTraitCollection(_environmentStateLock)
[self.view relayoutItems];
}
- (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completion:(void (^)(BOOL))completion
- (void)performBatchAnimated:(BOOL)animated updates:(NS_NOESCAPE void (^)())updates completion:(void (^)(BOOL))completion
{
ASDisplayNodeAssertMainThread();
if (self.nodeLoaded) {
@@ -703,7 +747,7 @@ ASLayoutElementCollectionTableSetTraitCollection(_environmentStateLock)
}
}
- (void)performBatchUpdates:(void (^)())updates completion:(void (^)(BOOL))completion
- (void)performBatchUpdates:(NS_NOESCAPE void (^)())updates completion:(void (^)(BOOL))completion
{
[self performBatchAnimated:YES updates:updates completion:completion];
}

View File

@@ -2,17 +2,9 @@
// ASTableView.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASTableView.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK
@@ -25,6 +17,8 @@
#import <AsyncDisplayKit/ASBatchFetching.h>
#import <AsyncDisplayKit/ASCellNode+Internal.h>
#import <AsyncDisplayKit/ASCollectionElement.h>
#import <AsyncDisplayKit/ASCollections.h>
#import <AsyncDisplayKit/ASConfigurationInternal.h>
#import <AsyncDisplayKit/ASDelegateProxy.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
@@ -372,8 +366,10 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
// Sometimes the UIKit classes can call back to their delegate even during deallocation.
_isDeallocating = YES;
[self setAsyncDelegate:nil];
[self setAsyncDataSource:nil];
if (!ASActivateExperimentalFeature(ASExperimentalCollectionTeardown)) {
[self setAsyncDelegate:nil];
[self setAsyncDataSource:nil];
}
// Data controller & range controller may own a ton of nodes, let's deallocate those off-main
ASPerformBackgroundDeallocation(&_dataController);
@@ -673,7 +669,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
- (NSArray<ASCellNode *> *)visibleNodes
{
auto elements = [self visibleElementsForRangeController:_rangeController];
let elements = [self visibleElementsForRangeController:_rangeController];
return ASArrayByFlatMapping(elements, ASCollectionElement *e, e.node);
}
@@ -759,7 +755,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
NSArray<ASCellNode *> *nodes = [_cellsForLayoutUpdates allObjects];
[_cellsForLayoutUpdates removeAllObjects];
auto nodesSizeChanged = [[NSMutableArray<ASCellNode *> alloc] init];
let nodesSizeChanged = [[NSMutableArray<ASCellNode *> alloc] init];
[_dataController relayoutNodes:nodes nodesSizeChanged:nodesSizeChanged];
if (nodesSizeChanged.count > 0) {
[self requeryNodeHeights];

View File

@@ -2,17 +2,9 @@
// ASTableViewInternal.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASTableViewProtocols.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef MINIMAL_ASDK

View File

@@ -2,17 +2,9 @@
// ASTextNode+Beta.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <UIKit/UIKit.h>

View File

@@ -2,17 +2,9 @@
// ASTextNode.h
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASAvailability.h>

View File

@@ -2,17 +2,9 @@
// ASTextNode.mm
// 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 /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,
// 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
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASTextNode.h>
@@ -26,9 +18,10 @@
#import <AsyncDisplayKit/_ASDisplayLayer.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
#import <AsyncDisplayKit/ASConfigurationInternal.h>
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import <AsyncDisplayKit/ASGraphicsContext.h>
#import <AsyncDisplayKit/ASTextKitCoreTextAdditions.h>
@@ -191,7 +184,12 @@ static ASTextKitRenderer *rendererForAttributes(ASTextKitAttributes attributes,
NSAttributedString *_attributedText;
NSAttributedString *_truncationAttributedText;
NSAttributedString *_additionalTruncationMessage;
NSAttributedString *_composedTruncationText;
NSArray<NSNumber *> *_pointSizeScaleFactors;
NSLineBreakMode _truncationMode;
NSUInteger _maximumNumberOfLines;
NSString *_highlightedLinkAttributeName;
id _highlightedLinkAttributeValue;
@@ -338,17 +336,20 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
- (ASTextKitRenderer *)_locked_renderer
{
ASAssertLocked(__instanceLock__);
return [self _locked_rendererWithBounds:[self _locked_threadSafeBounds]];
}
- (ASTextKitRenderer *)_locked_rendererWithBounds:(CGRect)bounds
{
ASAssertLocked(__instanceLock__);
bounds = UIEdgeInsetsInsetRect(bounds, _textContainerInset);
return rendererForAttributes([self _locked_rendererAttributes], bounds.size);
}
- (ASTextKitAttributes)_locked_rendererAttributes
{
ASAssertLocked(__instanceLock__);
return {
.attributedString = _attributedText,
.truncationAttributedString = [self _locked_composedTruncationText],
@@ -500,7 +501,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
textContainerInsets:_textContainerInset];
}
+ (void)drawRect:(CGRect)bounds withParameters:(id)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
+ (void)drawRect:(CGRect)bounds withParameters:(id)parameters isCancelled:(NS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
{
ASTextNodeDrawParameter *drawParameter = (ASTextNodeDrawParameter *)parameters;
UIColor *backgroundColor = (isRasterizing || drawParameter == nil) ? nil : drawParameter->_backgroundColor;
@@ -648,7 +649,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
}
// Ask our delegate if a long-press on an attribute is relevant
if ([_delegate respondsToSelector:@selector(textNode:shouldLongPressLinkAttribute:value:atPoint:)]) {
if ([self _pendingLinkTap] && [_delegate respondsToSelector:@selector(textNode:shouldLongPressLinkAttribute:value:atPoint:)]) {
return [_delegate textNode:self
shouldLongPressLinkAttribute:_highlightedLinkAttributeName
value:_highlightedLinkAttributeValue
@@ -854,7 +855,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
ASLockScopeSelf();
NSArray *rects = [[self _locked_renderer] rectsForTextRange:textRange measureOption:measureOption];
auto adjustedRects = [[NSMutableArray<NSValue *> alloc] init];
let adjustedRects = [[NSMutableArray<NSValue *> alloc] init];
for (NSValue *rectValue in rects) {
CGRect rect = [rectValue CGRectValue];
@@ -1175,6 +1176,11 @@ static NSAttributedString *DefaultTruncationAttributedString()
}
}
- (NSAttributedString *)additionalTruncationMessage
{
return ASLockedSelf(_additionalTruncationMessage);
}
- (void)setTruncationMode:(NSLineBreakMode)truncationMode
{
if (ASLockedSelfCompareAssign(_truncationMode, truncationMode)) {
@@ -1182,18 +1188,28 @@ static NSAttributedString *DefaultTruncationAttributedString()
}
}
- (NSLineBreakMode)truncationMode
{
return ASLockedSelf(_truncationMode);
}
- (BOOL)isTruncated
{
return ASLockedSelf([[self _locked_renderer] isTruncated]);
}
- (void)setPointSizeScaleFactors:(NSArray *)pointSizeScaleFactors
- (void)setPointSizeScaleFactors:(NSArray<NSNumber *> *)pointSizeScaleFactors
{
if (ASLockedSelfCompareAssignCopy(_pointSizeScaleFactors, pointSizeScaleFactors)) {
[self setNeedsDisplay];
}
}
- (NSArray<NSNumber *> *)pointSizeScaleFactors
{
return ASLockedSelf(_pointSizeScaleFactors);
}
- (void)setMaximumNumberOfLines:(NSUInteger)maximumNumberOfLines
{
if (ASLockedSelfCompareAssign(_maximumNumberOfLines, maximumNumberOfLines)) {
@@ -1201,6 +1217,11 @@ static NSAttributedString *DefaultTruncationAttributedString()
}
}
- (NSUInteger)maximumNumberOfLines
{
return ASLockedSelf(_maximumNumberOfLines);
}
- (NSUInteger)lineCount
{
return ASLockedSelf([[self _locked_renderer] lineCount]);
@@ -1247,6 +1268,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
*/
- (NSAttributedString *)_locked_composedTruncationText
{
ASAssertLocked(__instanceLock__);
if (_composedTruncationText == nil) {
if (_truncationAttributedText != nil && _additionalTruncationMessage != nil) {
NSMutableAttributedString *newComposedTruncationString = [[NSMutableAttributedString alloc] initWithAttributedString:_truncationAttributedText];
@@ -1272,6 +1294,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
*/
- (NSAttributedString *)_locked_prepareTruncationStringForDrawing:(NSAttributedString *)truncationString
{
ASAssertLocked(__instanceLock__);
truncationString = ASCleanseAttributedStringOfCoreTextAttributes(truncationString);
NSMutableAttributedString *truncationMutableString = [truncationString mutableCopy];
// Grab the attributes from the full string
@@ -1283,7 +1306,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
NSDictionary *originalStringAttributes = [originalString attributesAtIndex:originalStringLength-1 effectiveRange:NULL];
[truncationString enumerateAttributesInRange:NSMakeRange(0, truncationString.length) options:0 usingBlock:
^(NSDictionary *attributes, NSRange range, BOOL *stop) {
NSMutableDictionary *futureTruncationAttributes = [NSMutableDictionary dictionaryWithDictionary:originalStringAttributes];
NSMutableDictionary *futureTruncationAttributes = [originalStringAttributes mutableCopy];
[futureTruncationAttributes addEntriesFromDictionary:attributes];
[truncationMutableString setAttributes:futureTruncationAttributes range:range];
}];
@@ -1315,36 +1338,29 @@ static NSAttributedString *DefaultTruncationAttributedString()
}
#endif
+ (id)allocWithZone:(struct _NSZone *)zone
// All direct descendants of ASTextNode get their superclass replaced by ASTextNode2.
+ (void)initialize
{
// If they're not experimenting, just forward.
if (!ASActivateExperimentalFeature(ASExperimentalTextNode)) {
return [super allocWithZone:zone];
}
// Texture requires that node subclasses call [super initialize]
[super initialize];
// 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.
// Note: This may be called on multiple threads simultaneously.
Class s;
for (Class c = self; c != Nil && c != [ASTextNode class]; c = s) {
s = class_getSuperclass(c);
if (s == [ASTextNode class]) {
if (class_getSuperclass(self) == [ASTextNode class]
&& ASActivateExperimentalFeature(ASExperimentalTextNode)) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// Direct descendent. Update superclass of c and end.
class_setSuperclass(c, [ASTextNode2 class]);
class_setSuperclass(self, [ASTextNode2 class]);
#pragma clang diagnostic pop
break;
}
}
}
return [super allocWithZone:zone];
// For direct allocations of ASTextNode itself, we override allocWithZone:
+ (id)allocWithZone:(struct _NSZone *)zone
{
if (ASActivateExperimentalFeature(ASExperimentalTextNode)) {
return (ASTextNode *)[ASTextNode2 allocWithZone:zone];
} else {
return [super allocWithZone:zone];
}
}
@end

View File

@@ -2,12 +2,8 @@
// ASTextNode2.h
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASControlNode.h>

View File

@@ -2,12 +2,8 @@
// ASTextNode2.mm
// Texture
//
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASTextNode2.h>
@@ -19,8 +15,9 @@
#import <AsyncDisplayKit/_ASDisplayLayer.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
#import <AsyncDisplayKit/ASTextKitRenderer+Positioning.h>
#import <AsyncDisplayKit/ASTextKitShadower.h>
@@ -235,16 +232,12 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
ASLockScopeSelf();
ASTextContainer *container = [_textContainer copy];
NSAttributedString *attributedText = self.attributedText;
container.size = constrainedSize;
_textContainer.size = constrainedSize;
[self _ensureTruncationText];
NSMutableAttributedString *mutableText = [attributedText mutableCopy];
NSMutableAttributedString *mutableText = [_attributedText mutableCopy];
[self prepareAttributedString:mutableText];
ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:container text:mutableText];
[self setNeedsDisplay];
ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:_textContainer text:mutableText];
return layout.textBoundingSize;
}
@@ -346,7 +339,9 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
if (_shadowOpacity > 0 && (_shadowRadius != 0 || !CGSizeEqualToSize(_shadowOffset, CGSizeZero)) && CGColorGetAlpha(_shadowColor) > 0) {
NSShadow *shadow = [[NSShadow alloc] init];
if (_shadowOpacity != 1) {
shadow.shadowColor = [UIColor colorWithCGColor:CGColorCreateCopyWithAlpha(_shadowColor, _shadowOpacity * CGColorGetAlpha(_shadowColor))];
CGColorRef shadowColorRef = CGColorCreateCopyWithAlpha(_shadowColor, _shadowOpacity * CGColorGetAlpha(_shadowColor));
shadow.shadowColor = [UIColor colorWithCGColor:shadowColorRef];
CGColorRelease(shadowColorRef);
} else {
shadow.shadowColor = [UIColor colorWithCGColor:_shadowColor];
}
@@ -362,9 +357,12 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
{
ASLockScopeSelf();
[self _ensureTruncationText];
// Unlike layout, here we must copy the container since drawing is asynchronous.
ASTextContainer *copiedContainer = [_textContainer copy];
copiedContainer.size = self.bounds.size;
NSMutableAttributedString *mutableText = [self.attributedText mutableCopy] ?: [[NSMutableAttributedString alloc] init];
[copiedContainer makeImmutable];
NSMutableAttributedString *mutableText = [_attributedText mutableCopy] ?: [[NSMutableAttributedString alloc] init];
[self prepareAttributedString:mutableText];
@@ -406,7 +404,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
CGRect containerBounds = (CGRect){ .size = container.size };
{
for (auto &t : cacheValue->_layouts) {
for (let &t : cacheValue->_layouts) {
CGSize constrainedSize = std::get<0>(t);
ASTextLayout *layout = std::get<1>(t);
@@ -467,7 +465,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
return layout;
}
+ (void)drawRect:(CGRect)bounds withParameters:(NSDictionary *)layoutDict isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
+ (void)drawRect:(CGRect)bounds withParameters:(NSDictionary *)layoutDict isCancelled:(NS_NOESCAPE asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
{
ASTextContainer *container = layoutDict[@"container"];
NSAttributedString *text = layoutDict[@"text"];
@@ -530,7 +528,9 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
// For now, assume that a tap inside this text, but outside the text range is a tap on the
// truncation token.
if (![layout textRangeAtPoint:point]) {
*inAdditionalTruncationMessageOut = YES;
if (inAdditionalTruncationMessageOut != NULL) {
*inAdditionalTruncationMessageOut = YES;
}
return nil;
}
@@ -948,7 +948,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
}
}
- (NSArray *)pointSizeScaleFactors
- (NSArray<NSNumber *> *)pointSizeScaleFactors
{
return ASLockedSelf(_pointSizeScaleFactors);
}
@@ -1094,7 +1094,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
*/
- (NSAttributedString *)_locked_composedTruncationText
{
ASDisplayNodeAssertLockOwnedByCurrentThread(__instanceLock__);
ASAssertLocked(__instanceLock__);
if (_composedTruncationText == nil) {
if (_truncationAttributedText != nil && _additionalTruncationMessage != nil) {
NSMutableAttributedString *newComposedTruncationString = [[NSMutableAttributedString alloc] initWithAttributedString:_truncationAttributedText];
@@ -1120,7 +1120,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
*/
- (NSAttributedString *)_locked_prepareTruncationStringForDrawing:(NSAttributedString *)truncationString
{
ASDisplayNodeAssertLockOwnedByCurrentThread(__instanceLock__);
ASAssertLocked(__instanceLock__);
NSMutableAttributedString *truncationMutableString = [truncationString mutableCopy];
// Grab the attributes from the full string
if (_attributedText.length > 0) {
@@ -1131,7 +1131,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
NSDictionary *originalStringAttributes = [originalString attributesAtIndex:originalStringLength-1 effectiveRange:NULL];
[truncationString enumerateAttributesInRange:NSMakeRange(0, truncationString.length) options:0 usingBlock:
^(NSDictionary *attributes, NSRange range, BOOL *stop) {
NSMutableDictionary *futureTruncationAttributes = [NSMutableDictionary dictionaryWithDictionary:originalStringAttributes];
NSMutableDictionary *futureTruncationAttributes = [originalStringAttributes mutableCopy];
[futureTruncationAttributes addEntriesFromDictionary:attributes];
[truncationMutableString setAttributes:futureTruncationAttributes range:range];
}];

View File

@@ -2,12 +2,8 @@
// 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
// Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <Foundation/Foundation.h>

Some files were not shown because too many files have changed in this diff Show More