Merge pull request #1456 from maicki/ASEnvironment

[ASEnvironment] Add support for ASEnvironment, supporting generalized state propagation both up and down node and layout spec trees.
This commit is contained in:
appleguy
2016-03-31 21:05:38 -07:00
28 changed files with 776 additions and 611 deletions

View File

@@ -258,6 +258,16 @@
68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */; };
68EE0DBF1C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; };
68EE0DC01C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; };
698548631CA9E025008A345F /* ASEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 698548611CA9E025008A345F /* ASEnvironment.h */; settings = {ATTRIBUTES = (Public, ); }; };
698548641CA9E025008A345F /* ASEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 698548611CA9E025008A345F /* ASEnvironment.h */; settings = {ATTRIBUTES = (Public, ); }; };
698548651CA9E025008A345F /* ASEnvironment.m in Sources */ = {isa = PBXBuildFile; fileRef = 698548621CA9E025008A345F /* ASEnvironment.m */; };
698548661CA9E025008A345F /* ASEnvironment.m in Sources */ = {isa = PBXBuildFile; fileRef = 698548621CA9E025008A345F /* ASEnvironment.m */; };
698C8B611CAB49FC0052DC3F /* ASLayoutableExtensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */; settings = {ATTRIBUTES = (Public, ); }; };
698C8B621CAB49FC0052DC3F /* ASLayoutableExtensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */; settings = {ATTRIBUTES = (Public, ); }; };
69E1006D1CA89CB600D88C1B /* ASEnvironmentInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */; };
69E1006E1CA89CB600D88C1B /* ASEnvironmentInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */; };
69E1006F1CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */; };
69E100701CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */; };
69F10C861C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; };
69F10C871C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; };
6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -288,14 +298,6 @@
9C55866A1BD549CB00B50E3A /* ASAsciiArtBoxCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */; };
9C55866B1BD54A1900B50E3A /* ASAsciiArtBoxCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */; };
9C55866C1BD54A3000B50E3A /* ASAsciiArtBoxCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5586671BD549CB00B50E3A /* ASAsciiArtBoxCreator.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3511B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3521B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3531B8F6ADF00A62714 /* ASLayoutOptions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.mm */; };
9C5FA3541B8F6ADF00A62714 /* ASLayoutOptions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.mm */; };
9C5FA35F1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */; };
9C5FA3601B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */; };
9C65A72A1BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C65A7291BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h */; };
9C65A72B1BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C65A7291BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h */; };
9C6BB3B21B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C6BB3B31B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C8221951BA237B80037F19A /* ASStackBaselinePositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */; };
@@ -740,6 +742,11 @@
68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Beta.h"; sourceTree = "<group>"; };
68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMainSerialQueue.h; sourceTree = "<group>"; };
68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMainSerialQueue.mm; sourceTree = "<group>"; };
698548611CA9E025008A345F /* ASEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEnvironment.h; sourceTree = "<group>"; };
698548621CA9E025008A345F /* ASEnvironment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASEnvironment.m; sourceTree = "<group>"; };
698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutableExtensibility.h; path = AsyncDisplayKit/Layout/ASLayoutableExtensibility.h; sourceTree = "<group>"; };
69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEnvironmentInternal.h; sourceTree = "<group>"; };
69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEnvironmentInternal.mm; sourceTree = "<group>"; };
69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASRangeControllerUpdateRangeProtocol+Beta.h"; sourceTree = "<group>"; };
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = "<group>"; };
764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit+Debug.h"; sourceTree = "<group>"; };
@@ -755,10 +762,6 @@
9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutable.h; path = AsyncDisplayKit/Layout/ASStackLayoutable.h; sourceTree = "<group>"; };
9C5586671BD549CB00B50E3A /* ASAsciiArtBoxCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASAsciiArtBoxCreator.h; path = AsyncDisplayKit/Layout/ASAsciiArtBoxCreator.h; sourceTree = "<group>"; };
9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASAsciiArtBoxCreator.m; path = AsyncDisplayKit/Layout/ASAsciiArtBoxCreator.m; sourceTree = "<group>"; };
9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutOptions.h; path = AsyncDisplayKit/Layout/ASLayoutOptions.h; sourceTree = "<group>"; };
9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutOptions.mm; path = AsyncDisplayKit/Layout/ASLayoutOptions.mm; sourceTree = "<group>"; };
9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutOptionsPrivate.mm; path = AsyncDisplayKit/Layout/ASLayoutOptionsPrivate.mm; sourceTree = "<group>"; };
9C65A7291BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutOptionsPrivate.h; sourceTree = "<group>"; };
9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStaticLayoutable.h; path = AsyncDisplayKit/Layout/ASStaticLayoutable.h; sourceTree = "<group>"; };
9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackBaselinePositionedLayout.h; sourceTree = "<group>"; };
9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackBaselinePositionedLayout.mm; sourceTree = "<group>"; };
@@ -802,7 +805,7 @@
ACF6ED161B17843500DA7C62 /* ASStackLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutSpec.h; path = AsyncDisplayKit/Layout/ASStackLayoutSpec.h; sourceTree = "<group>"; };
ACF6ED171B17843500DA7C62 /* ASStackLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASStackLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASStackLayoutSpec.mm; sourceTree = "<group>"; };
ACF6ED181B17843500DA7C62 /* ASStaticLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStaticLayoutSpec.h; path = AsyncDisplayKit/Layout/ASStaticLayoutSpec.h; sourceTree = "<group>"; };
ACF6ED191B17843500DA7C62 /* ASStaticLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASStaticLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
ACF6ED191B17843500DA7C62 /* ASStaticLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASStaticLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm; sourceTree = "<group>"; };
ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASInternalHelpers.h; sourceTree = "<group>"; };
ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASInternalHelpers.mm; sourceTree = "<group>"; };
ACF6ED451B17847A00DA7C62 /* ASLayoutSpecUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecUtilities.h; sourceTree = "<group>"; };
@@ -1116,14 +1119,6 @@
058D09E1195D050800B7D73C /* Details */ = {
isa = PBXGroup;
children = (
25B171EA1C12242700508A7A /* Data Controller */,
81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */,
81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */,
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */,
CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */,
251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */,
251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */,
251B8EF61BBB3D690087C538 /* ASDataController+Subclasses.h */,
058D09E2195D050800B7D73C /* _ASDisplayLayer.h */,
058D09E3195D050800B7D73C /* _ASDisplayLayer.mm */,
058D09E4195D050800B7D73C /* _ASDisplayView.h */,
@@ -1134,31 +1129,41 @@
054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */,
299DA1A71A828D2900162D41 /* ASBatchContext.h */,
299DA1A81A828D2900162D41 /* ASBatchContext.mm */,
251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */,
251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */,
205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */,
205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.mm */,
251B8EF61BBB3D690087C538 /* ASDataController+Subclasses.h */,
05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */,
05A6D05919D0EB64002DD95E /* ASDealloc2MainObject.m */,
698548611CA9E025008A345F /* ASEnvironment.h */,
698548621CA9E025008A345F /* ASEnvironment.m */,
4640521B1A3F83C40061C0BA /* ASFlowLayoutController.h */,
4640521C1A3F83C40061C0BA /* ASFlowLayoutController.mm */,
058D09E6195D050800B7D73C /* ASHighlightOverlayLayer.h */,
058D09E7195D050800B7D73C /* ASHighlightOverlayLayer.mm */,
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */,
430E7C8D1B4C23F100697A4C /* ASIndexPath.h */,
430E7C8E1B4C23F100697A4C /* ASIndexPath.m */,
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */,
4640521D1A3F83C40061C0BA /* ASLayoutController.h */,
292C59991A956527007E5DD6 /* ASLayoutRangeType.h */,
68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */,
68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */,
058D09E8195D050800B7D73C /* ASMutableAttributedStringBuilder.h */,
058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */,
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */,
CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */,
055F1A3619ABD413004DAFF1 /* ASRangeController.h */,
055F1A3719ABD413004DAFF1 /* ASRangeController.mm */,
69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */,
81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */,
81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */,
296A0A311A951715005ACEAA /* ASScrollDirection.h */,
205F0E111B371BD7007741D0 /* ASScrollDirection.m */,
058D0A12195D050800B7D73C /* ASThread.h */,
205F0E1F1B376416007741D0 /* CGRect+ASConvenience.h */,
205F0E201B376416007741D0 /* CGRect+ASConvenience.m */,
25B171EA1C12242700508A7A /* Data Controller */,
058D09F5195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.h */,
058D09F6195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m */,
058D09F7195D050800B7D73C /* Transactions */,
@@ -1186,50 +1191,51 @@
058D0A01195D050800B7D73C /* Private */ = {
isa = PBXGroup;
children = (
DB55C25F1C6408D6004EDCF5 /* _ASTransitionContext.h */,
DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.m */,
CC3B20811C3F76D600798563 /* ASPendingStateController.h */,
CC3B20821C3F76D600798563 /* ASPendingStateController.mm */,
CC3B20871C3F7A5400798563 /* ASWeakSet.h */,
CC3B20881C3F7A5400798563 /* ASWeakSet.m */,
AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */,
AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */,
9C65A7291BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h */,
9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */,
9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */,
2967F9E11AB0A4CF0072E4AB /* ASBasicImageDownloaderInternal.h */,
058D0A02195D050800B7D73C /* _AS-objc-internal.h */,
058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */,
058D0A04195D050800B7D73C /* _ASCoreAnimationExtras.mm */,
AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */,
AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */,
058D0A05195D050800B7D73C /* _ASPendingState.h */,
058D0A06195D050800B7D73C /* _ASPendingState.mm */,
058D0A07195D050800B7D73C /* _ASScopeTimer.h */,
058D0A08195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm */,
DB55C25F1C6408D6004EDCF5 /* _ASTransitionContext.h */,
DB55C2601C6408D6004EDCF5 /* _ASTransitionContext.m */,
2967F9E11AB0A4CF0072E4AB /* ASBasicImageDownloaderInternal.h */,
044285051BAA63FE00D16268 /* ASBatchFetching.h */,
044285061BAA63FE00D16268 /* ASBatchFetching.m */,
AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */,
AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */,
058D0A08195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm */,
058D0A09195D050800B7D73C /* ASDisplayNode+DebugTiming.h */,
058D0A0A195D050800B7D73C /* ASDisplayNode+DebugTiming.mm */,
058D0A0B195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm */,
DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */,
058D0A0B195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm */,
058D0A0C195D050800B7D73C /* ASDisplayNodeInternal.h */,
E52405B41C8FEF16004DC8E7 /* ASDisplayNodeLayoutContext.h */,
E52405B21C8FEF03004DC8E7 /* ASDisplayNodeLayoutContext.mm */,
058D0A0C195D050800B7D73C /* ASDisplayNodeInternal.h */,
69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */,
69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */,
058D0A0D195D050800B7D73C /* ASImageNode+CGExtras.h */,
058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */,
058D0A10195D050800B7D73C /* ASSentinel.h */,
058D0A11195D050800B7D73C /* ASSentinel.m */,
ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */,
ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */,
ACF6ED451B17847A00DA7C62 /* ASLayoutSpecUtilities.h */,
0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */,
0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */,
CC3B20811C3F76D600798563 /* ASPendingStateController.h */,
CC3B20821C3F76D600798563 /* ASPendingStateController.mm */,
058D0A10195D050800B7D73C /* ASSentinel.h */,
058D0A11195D050800B7D73C /* ASSentinel.m */,
9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */,
9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */,
ACF6ED461B17847A00DA7C62 /* ASStackLayoutSpecUtilities.h */,
ACF6ED471B17847A00DA7C62 /* ASStackPositionedLayout.h */,
ACF6ED481B17847A00DA7C62 /* ASStackPositionedLayout.mm */,
ACF6ED491B17847A00DA7C62 /* ASStackUnpositionedLayout.h */,
ACF6ED4A1B17847A00DA7C62 /* ASStackUnpositionedLayout.mm */,
0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */,
0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */,
AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */,
AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */,
CC3B20871C3F7A5400798563 /* ASWeakSet.h */,
CC3B20881C3F7A5400798563 /* ASWeakSet.m */,
DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */,
DBC452DA1C5BF64600B16017 /* NSArray+Diffing.m */,
);
@@ -1314,14 +1320,13 @@
ACF6ED041B17843500DA7C62 /* ASCenterLayoutSpec.mm */,
ACF6ED071B17843500DA7C62 /* ASDimension.h */,
ACF6ED081B17843500DA7C62 /* ASDimension.mm */,
AC47D9431B3BB41900AAEE9D /* ASRelativeSize.h */,
AC47D9441B3BB41900AAEE9D /* ASRelativeSize.mm */,
ACF6ED091B17843500DA7C62 /* ASInsetLayoutSpec.h */,
ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutSpec.mm */,
ACF6ED0B1B17843500DA7C62 /* ASLayout.h */,
ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */,
ACF6ED111B17843500DA7C62 /* ASLayoutable.h */,
E55D86311CA8A14000A0C26F /* ASLayoutable.mm */,
698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */,
9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */,
ACF6ED0D1B17843500DA7C62 /* ASLayoutSpec.h */,
ACF6ED0E1B17843500DA7C62 /* ASLayoutSpec.mm */,
@@ -1331,6 +1336,8 @@
ACF6ED151B17843500DA7C62 /* ASRatioLayoutSpec.mm */,
7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */,
7A06A7381C35F08800FE8DAA /* ASRelativeLayoutSpec.mm */,
AC47D9431B3BB41900AAEE9D /* ASRelativeSize.h */,
AC47D9441B3BB41900AAEE9D /* ASRelativeSize.mm */,
9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */,
AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */,
ACF6ED161B17843500DA7C62 /* ASStackLayoutSpec.h */,
@@ -1338,9 +1345,6 @@
9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */,
ACF6ED181B17843500DA7C62 /* ASStaticLayoutSpec.h */,
ACF6ED191B17843500DA7C62 /* ASStaticLayoutSpec.mm */,
9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */,
9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.mm */,
9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */,
);
name = Layout;
path = ..;
@@ -1379,6 +1383,8 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
698C8B611CAB49FC0052DC3F /* ASLayoutableExtensibility.h in Headers */,
698548631CA9E025008A345F /* ASEnvironment.h in Headers */,
E5711A2B1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */,
257754C21BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h in Headers */,
A373200F1C571B730011FC94 /* ASTextNode+Beta.h in Headers */,
@@ -1462,8 +1468,6 @@
9CDC18CC1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */,
B0F8805A1BEAEC7500D17647 /* ASTableNode.h in Headers */,
464052241A3F83C40061C0BA /* ASLayoutController.h in Headers */,
9C5FA3511B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */,
9C65A72A1BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h in Headers */,
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */,
257754B61BEE44CD00737CA5 /* ASEqualityHashHelpers.h in Headers */,
ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */,
@@ -1487,6 +1491,7 @@
9C8221951BA237B80037F19A /* ASStackBaselinePositionedLayout.h in Headers */,
257754C31BEE458E00737CA5 /* ASTextNodeTypes.h in Headers */,
9C49C36F1B853957000B0DD5 /* ASStackLayoutable.h in Headers */,
69E1006D1CA89CB600D88C1B /* ASEnvironmentInternal.h in Headers */,
AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */,
CC7FD9DE1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */,
ACF6ED2F1B17843500DA7C62 /* ASStackLayoutSpec.h in Headers */,
@@ -1522,6 +1527,8 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
698C8B621CAB49FC0052DC3F /* ASLayoutableExtensibility.h in Headers */,
698548641CA9E025008A345F /* ASEnvironment.h in Headers */,
AC026B6A1BD57D6F00BBC17E /* ASChangeSetDataController.h in Headers */,
B35062481B010EFD0018CF92 /* _AS-objc-internal.h in Headers */,
69F10C871C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */,
@@ -1598,8 +1605,6 @@
34EFC7691B701CE100AD841F /* ASLayoutable.h in Headers */,
9CDC18CD1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */,
B35062201B010EFD0018CF92 /* ASLayoutController.h in Headers */,
9C5FA3521B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */,
9C65A72B1BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h in Headers */,
B35062211B010EFD0018CF92 /* ASLayoutRangeType.h in Headers */,
34EFC76A1B701CE600AD841F /* ASLayoutSpec.h in Headers */,
34EFC7791B701D3600AD841F /* ASLayoutSpecUtilities.h in Headers */,
@@ -1640,6 +1645,7 @@
92DD2FE81BF4D0A80074C9DD /* ASMapNode.h in Headers */,
044284FE1BAA387800D16268 /* ASStackLayoutSpecUtilities.h in Headers */,
34EFC7751B701D2400AD841F /* ASStackPositionedLayout.h in Headers */,
69E1006E1CA89CB600D88C1B /* ASEnvironmentInternal.h in Headers */,
34EFC7771B701D2D00AD841F /* ASStackUnpositionedLayout.h in Headers */,
9C6BB3B31B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */,
34EFC7731B701D0700AD841F /* ASStaticLayoutSpec.h in Headers */,
@@ -1873,6 +1879,7 @@
DBDB83961C6E879900D0098C /* ASPagerFlowLayout.m in Sources */,
058D0A26195D050800B7D73C /* _ASCoreAnimationExtras.mm in Sources */,
257754B41BEE44CD00737CA5 /* ASTextKitTailTruncater.mm in Sources */,
69E1006F1CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */,
AC026B711BD57DBF00BBC17E /* _ASHierarchyChangeSet.m in Sources */,
257754BF1BEE458E00737CA5 /* ASTextKitCoreTextAdditions.m in Sources */,
058D0A18195D050800B7D73C /* _ASDisplayLayer.mm in Sources */,
@@ -1916,10 +1923,9 @@
430E7C911B4C23F100697A4C /* ASIndexPath.m in Sources */,
ACF6ED231B17843500DA7C62 /* ASInsetLayoutSpec.mm in Sources */,
ACF6ED4C1B17847A00DA7C62 /* ASInternalHelpers.mm in Sources */,
698548651CA9E025008A345F /* ASEnvironment.m in Sources */,
ACF6ED251B17843500DA7C62 /* ASLayout.mm in Sources */,
DB55C2631C6408D6004EDCF5 /* _ASTransitionContext.m in Sources */,
9C5FA3531B8F6ADF00A62714 /* ASLayoutOptions.mm in Sources */,
9C5FA35F1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */,
251B8EFA1BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m in Sources */,
ACF6ED271B17843500DA7C62 /* ASLayoutSpec.mm in Sources */,
257754B01BEE44CD00737CA5 /* ASTextKitRenderer+TextChecking.mm in Sources */,
@@ -2027,6 +2033,7 @@
B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.m in Sources */,
B350624A1B010EFD0018CF92 /* _ASCoreAnimationExtras.mm in Sources */,
68EE0DC01C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */,
698548661CA9E025008A345F /* ASEnvironment.m in Sources */,
2767E9421BB19BD600EA9B77 /* ASViewController.m in Sources */,
B35062101B010EFD0018CF92 /* _ASDisplayLayer.mm in Sources */,
9C55866B1BD54A1900B50E3A /* ASAsciiArtBoxCreator.m in Sources */,
@@ -2056,6 +2063,7 @@
636EA1A41C7FF4EC00EE152F /* NSArray+Diffing.m in Sources */,
B35062501B010EFD0018CF92 /* ASDisplayNode+DebugTiming.mm in Sources */,
DEC146B91C37A16A004A0EE7 /* ASCollectionInternal.m in Sources */,
69E100701CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */,
254C6B891BF94F8A003EC431 /* ASTextKitRenderer+Positioning.mm in Sources */,
E5711A301C840C96009619D4 /* ASIndexedNodeContext.m in Sources */,
B35062511B010EFD0018CF92 /* ASDisplayNode+UIViewBridge.mm in Sources */,
@@ -2073,8 +2081,6 @@
34EFC7601B701C8B00AD841F /* ASInsetLayoutSpec.mm in Sources */,
34EFC75E1B701BF000AD841F /* ASInternalHelpers.mm in Sources */,
34EFC7681B701CDE00AD841F /* ASLayout.mm in Sources */,
9C5FA3541B8F6ADF00A62714 /* ASLayoutOptions.mm in Sources */,
9C5FA3601B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */,
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */,
254C6B841BF94F8A003EC431 /* ASTextNodeWordKerner.m in Sources */,
34EFC76B1B701CEB00AD841F /* ASLayoutSpec.mm in Sources */,

View File

@@ -10,7 +10,6 @@
#import "ASDisplayNode+Subclasses.h"
#import "ASDisplayNode+FrameworkPrivate.h"
#import "ASDisplayNode+Beta.h"
#import "ASLayoutOptionsPrivate.h"
#import <objc/runtime.h>
#import <deque>
@@ -25,6 +24,7 @@
#import "ASDisplayNodeExtras.h"
#import "ASEqualityHelpers.h"
#import "ASRunLoopQueue.h"
#import "ASEnvironmentInternal.h"
#import "ASInternalHelpers.h"
#import "ASLayout.h"
@@ -60,7 +60,7 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
@implementation ASDisplayNode
// these dynamic properties all defined in ASLayoutOptionsPrivate.m
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender, sizeRange, layoutPosition, layoutOptions;
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender, sizeRange, layoutPosition;
@synthesize name = _name;
@synthesize preferredFrameSize = _preferredFrameSize;
@synthesize isFinalLayoutable = _isFinalLayoutable;
@@ -252,6 +252,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
_contentsScaleForDisplay = ASScreenScale();
_displaySentinel = [[ASSentinel alloc] init];
_preferredFrameSize = CGSizeZero;
_environmentState = ASEnvironmentStateMakeDefault();
}
- (id)init
@@ -1700,6 +1702,10 @@ static NSInteger incrementIfFound(NSInteger i) {
[self exitHierarchyState:stateToEnterOrExit];
}
}
if ([newSupernode supportsUpwardPropagation]) {
ASEnvironmentStatePropagateUp(newSupernode, _environmentState.layoutOptionsState);
}
}
// Track that a node will be displayed as part of the current node hierarchy.
@@ -1854,6 +1860,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
ASDN::MutexLocker l(_propertyLock);
if (_methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits) {
ASLayoutSpec *layoutSpec = [self layoutSpecThatFits:constrainedSize];
layoutSpec.parent = self;
layoutSpec.isMutable = NO;
ASLayout *layout = [layoutSpec measureWithSizeRange:constrainedSize];
// Make sure layoutableObject of the root layout is `self`, so that the flattened layout will be structurally correct.
@@ -1918,6 +1925,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
ASDN::MutexLocker l(_propertyLock);
if (! CGSizeEqualToSize(_preferredFrameSize, preferredFrameSize)) {
_preferredFrameSize = preferredFrameSize;
self.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(_preferredFrameSize), ASRelativeSizeMakeWithCGSize(_preferredFrameSize));
[self invalidateCalculatedLayout];
}
}
@@ -2666,6 +2674,37 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority";
return self;
}
#pragma mark - ASEnvironment
- (ASEnvironmentState)environmentState
{
return _environmentState;
}
- (void)setEnvironmentState:(ASEnvironmentState)environmentState
{
_environmentState = environmentState;
}
- (ASDisplayNode *)parent
{
return self.supernode;
}
- (NSArray<ASDisplayNode *> *)children
{
return self.subnodes;
}
- (BOOL)supportsUpwardPropagation
{
return YES;
}
ASEnvironmentLayoutOptionsForwarding
ASEnvironmentLayoutExtensibilityForwarding
#if TARGET_OS_TV
#pragma mark - UIFocusEnvironment Protocol (tvOS)

View File

@@ -365,6 +365,12 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
_attributedString = ASCleanseAttributedStringOfCoreTextAttributes(attributedString);
if (_attributedString.length > 0) {
CGFloat screenScale = ASScreenScale();
self.ascender = round([[_attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * screenScale)/screenScale;
self.descender = round([[_attributedString attribute:NSFontAttributeName atIndex:_attributedString.length - 1 effectiveRange:NULL] descender] * screenScale)/screenScale;
}
// Sync the truncation string with attributes from the updated _attributedString
// Without this, the size calculation of the text with truncation applied will
// not take into account the attributes of attributedString in the last line

View File

@@ -40,6 +40,7 @@
#import <AsyncDisplayKit/ASLayout.h>
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASEnvironment.h>
#import <AsyncDisplayKit/ASLayoutable.h>
#import <AsyncDisplayKit/ASLayoutSpec.h>
#import <AsyncDisplayKit/ASBackgroundLayoutSpec.h>
@@ -67,7 +68,6 @@
#import <AsyncDisplayKit/ASEqualityHelpers.h>
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
#import <AsyncDisplayKit/ASIndexPath.h>
#import <AsyncDisplayKit/ASLayoutOptions.h>
#import <AsyncDisplayKit/ASLog.h>
#import <AsyncDisplayKit/ASMutableAttributedStringBuilder.h>
#import <AsyncDisplayKit/ASThread.h>

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <Foundation/Foundation.h>
#import "ASDimension.h"
#import "ASStackLayoutDefines.h"
#import "ASRelativeSize.h"
ASDISPLAYNODE_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
static const int kMaxEnvironmentStateBoolExtensions = 1;
static const int kMaxEnvironmentStateIntegerExtensions = 4;
static const int kMaxEnvironmentStateEdgeInsetExtensions = 1;
#pragma mark -
typedef struct ASEnvironmentStateExtensions {
// Values to store extensions
BOOL boolExtensions[kMaxEnvironmentStateBoolExtensions];
NSInteger integerExtensions[kMaxEnvironmentStateIntegerExtensions];
UIEdgeInsets edgeInsetsExtensions[kMaxEnvironmentStateEdgeInsetExtensions];
} ASEnvironmentStateExtensions;
#pragma mark - ASEnvironmentLayoutOptionsState
typedef struct ASEnvironmentLayoutOptionsState {
CGFloat spacingBefore;// = 0;
CGFloat spacingAfter;// = 0;
BOOL flexGrow;// = NO;
BOOL flexShrink;// = NO;
ASRelativeDimension flexBasis;// = ASRelativeDimensionUnconstrained;
ASStackLayoutAlignSelf alignSelf;// = ASStackLayoutAlignSelfAuto;
CGFloat ascender;// = 0;
CGFloat descender;// = 0;
ASRelativeSizeRange sizeRange;// = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(CGSizeZero), ASRelativeSizeMakeWithCGSize(CGSizeZero));;
CGPoint layoutPosition;// = CGPointZero;
ASEnvironmentStateExtensions _extensions;
} ASEnvironmentLayoutOptionsState;
#pragma mark - ASEnvironmentHierarchyState
typedef struct ASEnvironmentHierarchyState {
unsigned rasterized:1; // = NO
unsigned rangeManaged:1; // = NO
unsigned transitioningSupernodes:1; // = NO
unsigned layoutPending:1; // = NO
} ASEnvironmentHierarchyState;
#pragma mark - ASEnvironmentState
typedef struct ASEnvironmentState {
struct ASEnvironmentHierarchyState hierarchyState;
struct ASEnvironmentLayoutOptionsState layoutOptionsState;
} ASEnvironmentState;
extern ASEnvironmentState ASEnvironmentStateMakeDefault();
ASDISPLAYNODE_EXTERN_C_END
#pragma mark - ASEnvironment
/**
* ASEnvironment allows objects that conform to the ASEnvironment protocol to be able to propagate specific States
* defined in an ASEnvironmentState up and down the ASEnvironment tree. To be able to define how merges of
* States should happen, specific merge functions can be provided
*/
@protocol ASEnvironment <NSObject>
/// The environment collection of an object which class conforms to the ASEnvironment protocol
- (ASEnvironmentState)environmentState;
- (void)setEnvironmentState:(ASEnvironmentState)environmentState;
/// Returns the parent of an object which class conforms to the ASEnvironment protocol
- (id<ASEnvironment> _Nullable)parent;
/// Returns all children of an object which class conforms to the ASEnvironment protocol
- (NSArray<id<ASEnvironment>> *)children;
/// Classes should implement this method and return YES / NO dependent if upward propagation is enabled or not
- (BOOL)supportsUpwardPropagation;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "ASEnvironment.h"
ASEnvironmentLayoutOptionsState _ASEnvironmentLayoutOptionsStateMakeDefault()
{
return (ASEnvironmentLayoutOptionsState) {
// Default values can be defined in here
};
}
ASEnvironmentHierarchyState _ASEnvironmentHierarchyStateMakeDefault()
{
return (ASEnvironmentHierarchyState) {
// Default values can be defined in here
};
}
ASEnvironmentState ASEnvironmentStateMakeDefault()
{
return (ASEnvironmentState) {
.layoutOptionsState = _ASEnvironmentLayoutOptionsStateMakeDefault(),
.hierarchyState = _ASEnvironmentHierarchyStateMakeDefault()
};
}

View File

@@ -1,91 +0,0 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASStaticLayoutable.h>
#import <AsyncDisplayKit/ASStackLayoutable.h>
NS_ASSUME_NONNULL_BEGIN
@protocol ASLayoutable;
/**
* A store for all of the options defined by ASLayoutSpec subclasses. All implementors of ASLayoutable own a
* ASLayoutOptions. When certain layoutSpecs need option values, they are read from this class.
*
* Unless you wish to create a custom layout spec, ASLayoutOptions can largely be ignored. Instead you can access
* the layout option properties exposed in ASLayoutable directly, which will set the values in ASLayoutOptions
* behind the scenes.
*/
@interface ASLayoutOptions : NSObject <ASStackLayoutable, ASStaticLayoutable, NSCopying>
/**
* Sets the class name for the ASLayoutOptions subclasses that will be created when a node or layoutSpec's options
* are first accessed.
*
* If you create a custom layoutSpec that includes new options, you will want to subclass ASLayoutOptions to add
* the new layout options for your layoutSpec(s). In order to make sure your subclass is created instead of an
* instance of ASLayoutOptions, call setDefaultLayoutOptionsClass: early in app launch (applicationDidFinishLaunching:)
* with your subclass's class.
*
* @param defaultLayoutOptionsClass The class of ASLayoutOptions that will be lazily created for a node or layout spec.
*/
+ (void)setDefaultLayoutOptionsClass:(Class)defaultLayoutOptionsClass;
/**
* @return the Class of ASLayoutOptions that will be created for a node or layoutspec. Defaults to [ASLayoutOptions class];
*/
+ (Class)defaultLayoutOptionsClass;
#pragma mark - Subclasses should implement these!
/**
* Initializes a new ASLayoutOptions using the given layoutable to assign any intrinsic option values.
* This init function sets a sensible default value for each layout option. If you create a subclass of
* ASLayoutOptions, your subclass should do the same.
*
* @param layoutable The layoutable that will own these options. The layoutable will be used to set any intrinsic
* layoutOptions. For example, if the layoutable is an ASTextNode the ascender/descender values will get set.
*
* @return a new instance of ASLayoutOptions
*/
- (instancetype)initWithLayoutable:(id<ASLayoutable>)layoutable;
/**
* Copies the values of layoutOptions into self. This is useful when placing a layoutable inside of another. Consider
* an ASTextNode that you want to align to the baseline by putting it in an ASStackLayoutSpec. Before that, you want
* to inset the ASTextNode by placing it in an ASInsetLayoutSpec. An ASInsetLayoutSpec will not have any information
* about the ASTextNode's ascender/descender unless we copy over the layout options from ASTextNode to ASInsetLayoutSpec.
* This is done automatically and should not need to be called directly. It is listed here to make sure that any
* ASLayoutOptions subclass implements the method.
*
* @param layoutOptions The layoutOptions to copy from
*/
- (void)copyFromOptions:(ASLayoutOptions *)layoutOptions;
#pragma mark - ASStackLayoutable
@property (nonatomic, readwrite) CGFloat spacingBefore;
@property (nonatomic, readwrite) CGFloat spacingAfter;
@property (nonatomic, readwrite) BOOL flexGrow;
@property (nonatomic, readwrite) BOOL flexShrink;
@property (nonatomic, readwrite) ASRelativeDimension flexBasis;
@property (nonatomic, readwrite) ASStackLayoutAlignSelf alignSelf;
@property (nonatomic, readwrite) CGFloat ascender;
@property (nonatomic, readwrite) CGFloat descender;
#pragma mark - ASStaticLayoutable
@property (nonatomic, readwrite) ASRelativeSizeRange sizeRange;
@property (nonatomic, readwrite) CGPoint layoutPosition;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,263 +0,0 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "ASLayoutOptions.h"
#import <AsyncDisplayKit/ASAssert.h>
#import <AsyncDisplayKit/ASThread.h>
#import <AsyncDisplayKit/ASTextNode.h>
#import "ASInternalHelpers.h"
@interface ASLayoutOptions()
{
ASDN::RecursiveMutex _propertyLock;
}
@end
@implementation ASLayoutOptions
@synthesize spacingBefore = _spacingBefore;
@synthesize spacingAfter = _spacingAfter;
@synthesize flexGrow = _flexGrow;
@synthesize flexShrink = _flexShrink;
@synthesize flexBasis = _flexBasis;
@synthesize alignSelf = _alignSelf;
@synthesize ascender = _ascender;
@synthesize descender = _descender;
@synthesize sizeRange = _sizeRange;
@synthesize layoutPosition = _layoutPosition;
static Class gDefaultLayoutOptionsClass = nil;
+ (void)setDefaultLayoutOptionsClass:(Class)defaultLayoutOptionsClass
{
gDefaultLayoutOptionsClass = defaultLayoutOptionsClass;
}
+ (Class)defaultLayoutOptionsClass
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (gDefaultLayoutOptionsClass == nil) {
// If someone is asking for this and it hasn't been customized yet, use the default.
gDefaultLayoutOptionsClass = [ASLayoutOptions class];
}
});
return gDefaultLayoutOptionsClass;
}
- (instancetype)init
{
return nil;
}
- (instancetype)initWithLayoutable:(id<ASLayoutable>)layoutable
{
self = [super init];
if (self) {
self.flexBasis = ASRelativeDimensionUnconstrained;
self.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(CGSizeZero), ASRelativeSizeMakeWithCGSize(CGSizeZero));
self.layoutPosition = CGPointZero;
// The following properties use a default value of 0 which we do not need to assign.
// self.spacingBefore = 0;
// self.spacingAfter = 0;
// self.flexGrow = NO;
// self.flexShrink = NO;
// self.alignSelf = ASStackLayoutAlignSelfAuto;
// self.ascender = 0;
// self.descender = 0;
[self setValuesFromLayoutable:layoutable];
}
return self;
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone
{
ASLayoutOptions *copy = [[[self class] alloc] init];
[copy copyFromOptions:self];
return copy;
}
- (void)copyFromOptions:(ASLayoutOptions *)layoutOptions
{
ASDN::MutexLocker l(_propertyLock);
self.flexBasis = layoutOptions.flexBasis;
self.spacingAfter = layoutOptions.spacingAfter;
self.spacingBefore = layoutOptions.spacingBefore;
self.flexGrow = layoutOptions.flexGrow;
self.flexShrink = layoutOptions.flexShrink;
self.alignSelf = layoutOptions.alignSelf;
self.ascender = layoutOptions.ascender;
self.descender = layoutOptions.descender;
self.sizeRange = layoutOptions.sizeRange;
self.layoutPosition = layoutOptions.layoutPosition;
}
/**
* Given an id<ASLayoutable>, set up layout options that are intrinsically defined by the layoutable.
*
* While this could be done in the layoutable object itself, moving the logic into the ASLayoutOptions class
* allows a custom spec to set up defaults without needing to alter the layoutable itself. For example,
* image you were creating a custom baseline spec that needed ascender/descender. To assign values automatically
* when a text node's attribute string is set, you would need to subclass ASTextNode and assign the values in the
* override of setAttributeString. However, assigning the defaults in an ASLayoutOptions subclass's
* setValuesFromLayoutable allows you to create a custom spec without the need to create a
* subclass of ASTextNode.
*
* @param layoutable The layoutable object to inspect for default intrinsic layout option values
*/
- (void)setValuesFromLayoutable:(id<ASLayoutable>)layoutable
{
ASDN::MutexLocker l(_propertyLock);
if ([layoutable isKindOfClass:[ASDisplayNode class]]) {
ASDisplayNode *displayNode = (ASDisplayNode *)layoutable;
self.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(displayNode.preferredFrameSize), ASRelativeSizeMakeWithCGSize(displayNode.preferredFrameSize));
if ([layoutable isKindOfClass:[ASTextNode class]]) {
ASTextNode *textNode = (ASTextNode *)layoutable;
NSAttributedString *attributedString = textNode.attributedString;
if (attributedString.length > 0) {
CGFloat screenScale = ASScreenScale();
self.ascender = round([[attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * screenScale)/screenScale;
self.descender = round([[attributedString attribute:NSFontAttributeName atIndex:attributedString.length - 1 effectiveRange:NULL] descender] * screenScale)/screenScale;
}
}
}
}
- (CGFloat)spacingAfter
{
ASDN::MutexLocker l(_propertyLock);
return _spacingAfter;
}
- (void)setSpacingAfter:(CGFloat)spacingAfter
{
ASDN::MutexLocker l(_propertyLock);
_spacingAfter = spacingAfter;
}
- (CGFloat)spacingBefore
{
ASDN::MutexLocker l(_propertyLock);
return _spacingBefore;
}
- (void)setSpacingBefore:(CGFloat)spacingBefore
{
ASDN::MutexLocker l(_propertyLock);
_spacingBefore = spacingBefore;
}
- (BOOL)flexGrow
{
ASDN::MutexLocker l(_propertyLock);
return _flexGrow;
}
- (void)setFlexGrow:(BOOL)flexGrow
{
ASDN::MutexLocker l(_propertyLock);
_flexGrow = flexGrow;
}
- (BOOL)flexShrink
{
ASDN::MutexLocker l(_propertyLock);
return _flexShrink;
}
- (void)setFlexShrink:(BOOL)flexShrink
{
ASDN::MutexLocker l(_propertyLock);
_flexShrink = flexShrink;
}
- (ASRelativeDimension)flexBasis
{
ASDN::MutexLocker l(_propertyLock);
return _flexBasis;
}
- (void)setFlexBasis:(ASRelativeDimension)flexBasis
{
ASDN::MutexLocker l(_propertyLock);
_flexBasis = flexBasis;
}
- (ASStackLayoutAlignSelf)alignSelf
{
ASDN::MutexLocker l(_propertyLock);
return _alignSelf;
}
- (void)setAlignSelf:(ASStackLayoutAlignSelf)alignSelf
{
ASDN::MutexLocker l(_propertyLock);
_alignSelf = alignSelf;
}
- (CGFloat)ascender
{
ASDN::MutexLocker l(_propertyLock);
return _ascender;
}
- (void)setAscender:(CGFloat)ascender
{
ASDN::MutexLocker l(_propertyLock);
_ascender = ascender;
}
- (CGFloat)descender
{
ASDN::MutexLocker l(_propertyLock);
return _descender;
}
- (void)setDescender:(CGFloat)descender
{
ASDN::MutexLocker l(_propertyLock);
_descender = descender;
}
- (ASRelativeSizeRange)sizeRange
{
ASDN::MutexLocker l(_propertyLock);
return _sizeRange;
}
- (void)setSizeRange:(ASRelativeSizeRange)sizeRange
{
ASDN::MutexLocker l(_propertyLock);
_sizeRange = sizeRange;
}
- (CGPoint)layoutPosition
{
ASDN::MutexLocker l(_propertyLock);
return _layoutPosition;
}
- (void)setLayoutPosition:(CGPoint)layoutPosition
{
ASDN::MutexLocker l(_propertyLock);
_layoutPosition = layoutPosition;
}
@end

View File

@@ -1,143 +0,0 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "ASLayoutOptionsPrivate.h"
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
/**
* Both an ASDisplayNode and an ASLayoutSpec conform to ASLayoutable. There are several properties
* in ASLayoutable that are used as layoutOptions when a node or spec is used in a layout spec.
* These properties are provided for convenience, as they are forwards to the node or spec's
* ASLayoutOptions class. Instead of duplicating the property forwarding in both classes, we
* create a define that allows us to easily implement the forwards in one place.
*
* If you create a custom layout spec, we recommend this stragety if you decide to extend
* ASDisplayNode and ASLayoutSpec to provide convenience properties for any options that your
* layoutSpec may require.
*/
#define ASLayoutOptionsForwarding \
- (ASLayoutOptions *)layoutOptions\
{\
ASDN::MutexLocker l(_layoutOptionsLock);\
if (_layoutOptions == nil) {\
_layoutOptions = [[[ASLayoutOptions defaultLayoutOptionsClass] alloc] initWithLayoutable:self];\
}\
return _layoutOptions;\
}\
\
- (CGFloat)spacingBefore\
{\
return self.layoutOptions.spacingBefore;\
}\
\
- (void)setSpacingBefore:(CGFloat)spacingBefore\
{\
self.layoutOptions.spacingBefore = spacingBefore;\
}\
\
- (CGFloat)spacingAfter\
{\
return self.layoutOptions.spacingAfter;\
}\
\
- (void)setSpacingAfter:(CGFloat)spacingAfter\
{\
self.layoutOptions.spacingAfter = spacingAfter;\
}\
\
- (BOOL)flexGrow\
{\
return self.layoutOptions.flexGrow;\
}\
\
- (void)setFlexGrow:(BOOL)flexGrow\
{\
self.layoutOptions.flexGrow = flexGrow;\
}\
\
- (BOOL)flexShrink\
{\
return self.layoutOptions.flexShrink;\
}\
\
- (void)setFlexShrink:(BOOL)flexShrink\
{\
self.layoutOptions.flexShrink = flexShrink;\
}\
\
- (ASRelativeDimension)flexBasis\
{\
return self.layoutOptions.flexBasis;\
}\
\
- (void)setFlexBasis:(ASRelativeDimension)flexBasis\
{\
self.layoutOptions.flexBasis = flexBasis;\
}\
\
- (ASStackLayoutAlignSelf)alignSelf\
{\
return self.layoutOptions.alignSelf;\
}\
\
- (void)setAlignSelf:(ASStackLayoutAlignSelf)alignSelf\
{\
self.layoutOptions.alignSelf = alignSelf;\
}\
\
- (CGFloat)ascender\
{\
return self.layoutOptions.ascender;\
}\
\
- (void)setAscender:(CGFloat)ascender\
{\
self.layoutOptions.ascender = ascender;\
}\
\
- (CGFloat)descender\
{\
return self.layoutOptions.descender;\
}\
\
- (void)setDescender:(CGFloat)descender\
{\
self.layoutOptions.descender = descender;\
}\
\
- (ASRelativeSizeRange)sizeRange\
{\
return self.layoutOptions.sizeRange;\
}\
\
- (void)setSizeRange:(ASRelativeSizeRange)sizeRange\
{\
self.layoutOptions.sizeRange = sizeRange;\
}\
\
- (CGPoint)layoutPosition\
{\
return self.layoutOptions.layoutPosition;\
}\
\
- (void)setLayoutPosition:(CGPoint)position\
{\
self.layoutOptions.layoutPosition = position;\
}\
@implementation ASDisplayNode(ASLayoutOptions)
ASLayoutOptionsForwarding
@end
@implementation ASLayoutSpec(ASLayoutOptions)
ASLayoutOptionsForwarding
@end

View File

@@ -25,6 +25,8 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init;
@property (nullable, nonatomic, weak) id<ASLayoutable> parent;
/**
* Adds a child to this layout spec using a default identifier.
*

View File

@@ -8,29 +8,33 @@
*
*/
#import "ASLayoutOptionsPrivate.h"
#import "ASLayoutSpec.h"
#import "ASAssert.h"
#import "ASBaseDefines.h"
#import "ASEnvironmentInternal.h"
#import "ASInternalHelpers.h"
#import "ASLayout.h"
#import "ASLayoutOptions.h"
#import "ASThread.h"
#import <objc/runtime.h>
static NSString * const kDefaultChildKey = @"kDefaultChildKey";
static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
@interface ASLayoutSpec()
@interface ASLayoutSpec() {
ASEnvironmentState _environmentState;
ASDN::RecursiveMutex _propertyLock;
}
@property (nonatomic, strong) NSMutableDictionary *layoutChildren;
@end
@implementation ASLayoutSpec
// these dynamic properties all defined in ASLayoutOptionsPrivate.m
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender, sizeRange, layoutPosition, layoutOptions;
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender, sizeRange, layoutPosition;
@synthesize layoutChildren = _layoutChildren;
@synthesize isFinalLayoutable = _isFinalLayoutable;
@@ -40,6 +44,8 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
return nil;
}
_isMutable = YES;
_environmentState = ASEnvironmentStateMakeDefault();
return self;
}
@@ -75,7 +81,8 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
id<ASLayoutable> finalLayoutable = [child finalLayoutable];
if (finalLayoutable != child) {
[finalLayoutable.layoutOptions copyFromOptions:child.layoutOptions];
// Layout options state of child needs to be copied to final layoutable
finalLayoutable.environmentState.layoutOptionsState = child.environmentState.layoutOptionsState;
return finalLayoutable;
}
}
@@ -90,6 +97,15 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
return _layoutChildren;
}
- (void)setParent:(id<ASLayoutable>)parent
{
_parent = parent;
if ([parent supportsUpwardPropagation]) {
ASEnvironmentStatePropagateUp(parent, _environmentState.layoutOptionsState);
}
}
- (void)setChild:(id<ASLayoutable>)child;
{
[self setChild:child forIdentifier:kDefaultChildKey];
@@ -98,7 +114,14 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
- (void)setChild:(id<ASLayoutable>)child forIdentifier:(NSString *)identifier
{
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
self.layoutChildren[identifier] = [self layoutableToAddFromLayoutable:child];;
id<ASLayoutable> finalLayoutable = [self layoutableToAddFromLayoutable:child];
BOOL needsToPropagateLayoutOptionsState = (child != finalLayoutable);
self.layoutChildren[identifier] = finalLayoutable;
if (needsToPropagateLayoutOptionsState) {
// We only need to propagate up layout options in setChild: as up propagation is currently only supported for
// layout specification has with one child
[self propagateUpLayoutOptionsState];
}
}
- (void)setChildren:(NSArray *)children
@@ -128,6 +151,30 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
return self.layoutChildren[kDefaultChildrenKey];
}
#pragma mark - ASEnvironment
- (ASEnvironmentState)environmentState
{
return _environmentState;
}
- (void)setEnvironmentState:(ASEnvironmentState)environmentState
{
_environmentState = environmentState;
}
// Subclasses can override this method to return NO, because upward propagation is not enabled if a layout
// specification has more than one child. Currently ASStackLayoutSpec and ASStaticLayoutSpec are currently
// the specifications that are known to have more than one.
- (BOOL)supportsUpwardPropagation
{
return YES;
}
ASEnvironmentLayoutOptionsForwarding
ASEnvironmentLayoutExtensibilityForwarding
@end
@implementation ASLayoutSpec (Debugging)

View File

@@ -15,6 +15,8 @@
#import <AsyncDisplayKit/ASStaticLayoutable.h>
#import <AsyncDisplayKit/ASLayoutablePrivate.h>
#import <AsyncDisplayKit/ASEnvironment.h>
#import <AsyncDisplayKit/ASLayoutableExtensibility.h>
@class ASLayout;
@class ASLayoutSpec;
@@ -37,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
* access to the options via convenience properties. If you are creating custom layout spec, then you can
* extend the backing layout options class to accommodate any new layout options.
*/
@protocol ASLayoutable <ASStackLayoutable, ASStaticLayoutable, ASLayoutablePrivate>
@protocol ASLayoutable <ASEnvironment, ASStackLayoutable, ASStaticLayoutable, ASLayoutablePrivate, ASLayoutableExtensibility>
/**
* @abstract Calculate a layout based on given size range.

View File

@@ -7,6 +7,12 @@
//
#import "ASLayoutablePrivate.h"
#import "ASInternalHelpers.h"
#import "ASEnvironmentInternal.h"
#import "ASDisplayNodeInternal.h"
#import "ASTextNode.h"
#import "ASLayoutSpec.h"
#import "pthread.h"
#import <map>
#import <iterator>

View File

@@ -0,0 +1,25 @@
//
// ASLayoutableExtensibility.h
// AsyncDisplayKit
//
// Created by Michael Schneider on 3/29/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <UIKit/UIGeometry.h>
@protocol ASLayoutableExtensibility <NSObject>
/// Currently up to 4 BOOL values
- (void)setLayoutOptionExtensionBool:(BOOL)value atIndex:(int)idx;
- (BOOL)layoutOptionExtensionBoolAtIndex:(int)idx;
/// Currently up to 1 NSInteger value
- (void)setLayoutOptionExtensionInteger:(NSInteger)value atIndex:(int)idx;
- (NSInteger)layoutOptionExtensionIntegerAtIndex:(int)idx;
/// Currently up to 1 UIEdgeInsets value
- (void)setLayoutOptionExtensionEdgeInsets:(UIEdgeInsets)value atIndex:(int)idx;
- (UIEdgeInsets)layoutOptionExtensionEdgeInsetsAtIndex:(int)idx;
@end

View File

@@ -11,7 +11,6 @@
#import <Foundation/Foundation.h>
@class ASLayoutSpec;
@class ASLayoutOptions;
@protocol ASLayoutable;
struct ASLayoutableContext {
@@ -60,9 +59,211 @@ extern void ASLayoutableClearCurrentContext();
*/
@property (nonatomic, assign) BOOL isFinalLayoutable;
@end
#pragma mark - ASLayoutOptionsForwarding
/**
* The class that holds all of the layoutOptions set on an ASLayoutable.
* Both an ASDisplayNode and an ASLayoutSpec conform to ASLayoutable. There are several properties
* in ASLayoutable that are used when a node or spec is used in a layout spec.
* These properties are provided for convenience, as they are forwards to the node or spec's
* properties. Instead of duplicating the property forwarding in both classes, we
* create a define that allows us to easily implement the forwards in one place.
*
* If you create a custom layout spec, we recommend this stragety if you decide to extend
* ASDisplayNode and ASLayoutSpec to provide convenience properties for any options that your
* layoutSpec may require.
*/
@property (nonatomic, strong, readonly) ASLayoutOptions *layoutOptions;
@end
#define ASEnvironmentLayoutOptionsForwarding \
- (void)propagateUpLayoutOptionsState\
{\
id<ASEnvironment> parent = [self parent];\
if ([parent supportsUpwardPropagation]) {\
ASEnvironmentStatePropagateUp(parent, _environmentState.layoutOptionsState);\
}\
}\
\
- (CGFloat)spacingAfter\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.spacingAfter;\
}\
\
- (void)setSpacingAfter:(CGFloat)spacingAfter\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.spacingAfter = spacingAfter;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (CGFloat)spacingBefore\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.spacingBefore;\
}\
\
- (void)setSpacingBefore:(CGFloat)spacingBefore\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.spacingBefore = spacingBefore;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (BOOL)flexGrow\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.flexGrow;\
}\
\
- (void)setFlexGrow:(BOOL)flexGrow\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.flexGrow = flexGrow;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (BOOL)flexShrink\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.flexShrink;\
}\
\
- (void)setFlexShrink:(BOOL)flexShrink\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.flexShrink = flexShrink;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (ASRelativeDimension)flexBasis\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.flexBasis;\
}\
\
- (void)setFlexBasis:(ASRelativeDimension)flexBasis\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.flexBasis = flexBasis;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (ASStackLayoutAlignSelf)alignSelf\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.alignSelf;\
}\
\
- (void)setAlignSelf:(ASStackLayoutAlignSelf)alignSelf\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.alignSelf = alignSelf;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (CGFloat)ascender\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.ascender;\
}\
\
- (void)setAscender:(CGFloat)ascender\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.ascender = ascender;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (CGFloat)descender\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.descender;\
}\
\
- (void)setDescender:(CGFloat)descender\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.descender = descender;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (ASRelativeSizeRange)sizeRange\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.sizeRange;\
}\
\
- (void)setSizeRange:(ASRelativeSizeRange)sizeRange\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.sizeRange = sizeRange;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
\
- (CGPoint)layoutPosition\
{\
ASDN::MutexLocker l(_propertyLock);\
return _environmentState.layoutOptionsState.layoutPosition;\
}\
\
- (void)setLayoutPosition:(CGPoint)layoutPosition\
{\
_propertyLock.lock();\
_environmentState.layoutOptionsState.layoutPosition = layoutPosition;\
[self propagateUpLayoutOptionsState];\
_propertyLock.unlock();\
}\
#pragma mark - ASLayoutableExtensibility
#define ASEnvironmentLayoutExtensibilityForwarding \
- (void)setLayoutOptionExtensionBool:(BOOL)value atIndex:(int)idx\
{\
_propertyLock.lock();\
_ASEnvironmentLayoutOptionsExtensionSetBoolAtIndex(self, idx, value);\
_propertyLock.unlock();\
}\
\
- (BOOL)layoutOptionExtensionBoolAtIndex:(int)idx\
{\
ASDN::MutexLocker l(_propertyLock);\
return _ASEnvironmentLayoutOptionsExtensionGetBoolAtIndex(self, idx);\
}\
\
- (void)setLayoutOptionExtensionInteger:(NSInteger)value atIndex:(int)idx\
{\
_propertyLock.lock();\
_ASEnvironmentLayoutOptionsExtensionSetIntegerAtIndex(self, idx, value);\
_propertyLock.unlock();\
}\
\
- (NSInteger)layoutOptionExtensionIntegerAtIndex:(int)idx\
{\
ASDN::MutexLocker l(_propertyLock);\
return _ASEnvironmentLayoutOptionsExtensionGetIntegerAtIndex(self, idx);\
}\
\
- (void)setLayoutOptionExtensionEdgeInsets:(UIEdgeInsets)value atIndex:(int)idx\
{\
_propertyLock.lock();\
_ASEnvironmentLayoutOptionsExtensionSetEdgeInsetsAtIndex(self, idx, value);\
_propertyLock.unlock();\
}\
\
- (UIEdgeInsets)layoutOptionExtensionEdgeInsetsAtIndex:(int)idx\
{\
ASDN::MutexLocker l(_propertyLock);\
return _ASEnvironmentLayoutOptionsExtensionGetEdgeInsetsAtIndex(self, idx);\
}\

View File

@@ -198,6 +198,15 @@
@end
@implementation ASStackLayoutSpec (ASEnvironment)
- (BOOL)supportsUpwardPropagation
{
return NO;
}
@end
@implementation ASStackLayoutSpec (Debugging)
#pragma mark - ASLayoutableAsciiArtProtocol

View File

@@ -11,7 +11,6 @@
#import "ASStaticLayoutSpec.h"
#import "ASLayoutSpecUtilities.h"
#import "ASLayoutOptions.h"
#import "ASInternalHelpers.h"
#import "ASLayout.h"
@@ -86,6 +85,15 @@
@end
@implementation ASStaticLayoutSpec (ASEnvironment)
- (BOOL)supportsUpwardPropagation
{
return NO;
}
@end
@implementation ASStaticLayoutSpec (Debugging)
#pragma mark - ASLayoutableAsciiArtProtocol

View File

@@ -16,7 +16,6 @@
#import "ASDisplayNode.h"
#import "ASSentinel.h"
#import "ASThread.h"
#import "ASLayoutOptions.h"
#import "_ASDisplayLayer.h"
NS_ASSUME_NONNULL_BEGIN

View File

@@ -16,9 +16,9 @@
#import "ASDisplayNode.h"
#import "ASSentinel.h"
#import "ASThread.h"
#import "ASLayoutOptions.h"
#import "_ASTransitionContext.h"
#import "ASDisplayNodeLayoutContext.h"
#import "ASEnvironment.h"
#include <vector>
@@ -97,6 +97,7 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
// This is the desired contentsScale, not the scale at which the layer's contents should be displayed
CGFloat _contentsScaleForDisplay;
ASEnvironmentState _environmentState;
ASLayout *_layout;
ASSizeRange _constrainedSize;

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "ASEnvironment.h"
#pragma once
enum class ASEnvironmentStatePropagation { DOWN, UP };
#pragma mark - Set and get extensible values for layout options
void _ASEnvironmentLayoutOptionsExtensionSetBoolAtIndex(id<ASEnvironment> object, int idx, BOOL value);
BOOL _ASEnvironmentLayoutOptionsExtensionGetBoolAtIndex(id<ASEnvironment> object, int idx);
void _ASEnvironmentLayoutOptionsExtensionSetIntegerAtIndex(id<ASEnvironment> object, int idx, NSInteger value);
NSInteger _ASEnvironmentLayoutOptionsExtensionGetIntegerAtIndex(id<ASEnvironment> object, int idx);
void _ASEnvironmentLayoutOptionsExtensionSetEdgeInsetsAtIndex(id<ASEnvironment> object, int idx, UIEdgeInsets value);
UIEdgeInsets _ASEnvironmentLayoutOptionsExtensionGetEdgeInsetsAtIndex(id<ASEnvironment> object, int idx);
#pragma mark - Traversing an ASEnvironment Tree
void ASEnvironmentPerformBlockOnObjectAndChildren(id<ASEnvironment> object, void(^block)(id<ASEnvironment> object));
void ASEnvironmentPerformBlockOnObjectAndParents(id<ASEnvironment> object, void(^block)(id<ASEnvironment> object));
#pragma mark - Merging
static const struct ASEnvironmentLayoutOptionsState ASEnvironmentDefaultLayoutOptionsState = {};
ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState environmentState, ASEnvironmentLayoutOptionsState state, ASEnvironmentStatePropagation propagation);
static const struct ASEnvironmentHierarchyState ASEnvironmentDefaultHierarchyState = {};
ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState environmentState, ASEnvironmentHierarchyState state, ASEnvironmentStatePropagation propagation);
#pragma mark - Propagation
template <typename ASEnvironmentStateType>
void ASEnvironmentStatePropagateDown(id<ASEnvironment> object, ASEnvironmentStateType state) {
ASEnvironmentPerformBlockOnObjectAndChildren(object, ^(id<ASEnvironment> node) {
object.environmentState = ASEnvironmentMergeObjectAndState(object.environmentState, state, ASEnvironmentStatePropagation::DOWN);
});
}
template <typename ASEnvironmentStateType>
void ASEnvironmentStatePropagateUp(id<ASEnvironment> object, ASEnvironmentStateType state) {
ASEnvironmentPerformBlockOnObjectAndParents(object, ^(id<ASEnvironment> node) {
object.environmentState = ASEnvironmentMergeObjectAndState(object.environmentState, state, ASEnvironmentStatePropagation::UP);
});
}
template <typename ASEnvironmentStateType>
void ASEnvironmentStateApply(id<ASEnvironment> object, ASEnvironmentStateType& state, ASEnvironmentStatePropagation propagate) {
if (propagate == ASEnvironmentStatePropagation::DOWN) {
ASEnvironmentStatePropagateUp(object, state);
} else if (propagate == ASEnvironmentStatePropagation::UP) {
ASEnvironmentStatePropagateDown(object, state);
}
}

View File

@@ -0,0 +1,151 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "ASEnvironmentInternal.h"
#import <queue>
//#define LOG(...) NSLog(__VA_ARGS__)
#define LOG(...)
#pragma mark - Traversing an ASEnvironment Tree
void ASEnvironmentPerformBlockOnObjectAndChildren(id<ASEnvironment> object, void(^block)(id<ASEnvironment> node))
{
if (!object) {
return;
}
std::queue<id<ASEnvironment>> queue;
queue.push(object);
while (!queue.empty()) {
id<ASEnvironment> object = queue.front(); queue.pop();
block(object);
for (id<ASEnvironment> child in [object children]) {
queue.push(child);
}
}
}
void ASEnvironmentPerformBlockOnObjectAndParents(id<ASEnvironment> object, void(^block)(id<ASEnvironment> node))
{
while (object) {
block(object);
object = [object parent];
}
}
#pragma mark - Set and get extensible values from state structs
void _ASEnvironmentLayoutOptionsExtensionSetBoolAtIndex(id<ASEnvironment> object, int idx, BOOL value)
{
NSCAssert(idx < kMaxEnvironmentStateBoolExtensions, @"Setting index outside of max bool extensions space");
ASEnvironmentStateExtensions extension = object.environmentState.layoutOptionsState._extensions;
extension.boolExtensions[idx] = value;
object.environmentState.layoutOptionsState._extensions = extension;
}
BOOL _ASEnvironmentLayoutOptionsExtensionGetBoolAtIndex(id<ASEnvironment> object, int idx)
{
NSCAssert(idx < kMaxEnvironmentStateBoolExtensions, @"Accessing index outside of max bool extensions space");
return object.environmentState.layoutOptionsState._extensions.boolExtensions[idx];
}
void _ASEnvironmentLayoutOptionsExtensionSetIntegerAtIndex(id<ASEnvironment> object, int idx, NSInteger value)
{
NSCAssert(idx < kMaxEnvironmentStateIntegerExtensions, @"Setting index outside of max integer extensions space");
ASEnvironmentStateExtensions extension = object.environmentState.layoutOptionsState._extensions;
extension.integerExtensions[idx] = value;
object.environmentState.layoutOptionsState._extensions = extension;
}
NSInteger _ASEnvironmentLayoutOptionsExtensionGetIntegerAtIndex(id<ASEnvironment> object, int idx)
{
NSCAssert(idx < kMaxEnvironmentStateIntegerExtensions, @"Accessing index outside of max integer extensions space");
return object.environmentState.layoutOptionsState._extensions.integerExtensions[idx];
}
void _ASEnvironmentLayoutOptionsExtensionSetEdgeInsetsAtIndex(id<ASEnvironment> object, int idx, UIEdgeInsets value)
{
NSCAssert(idx < kMaxEnvironmentStateEdgeInsetExtensions, @"Setting index outside of max edge insets extensions space");
ASEnvironmentStateExtensions extension = object.environmentState.layoutOptionsState._extensions;
extension.edgeInsetsExtensions[idx] = value;
object.environmentState.layoutOptionsState._extensions = extension;
}
UIEdgeInsets _ASEnvironmentLayoutOptionsExtensionGetEdgeInsetsAtIndex(id<ASEnvironment> object, int idx)
{
NSCAssert(idx < kMaxEnvironmentStateEdgeInsetExtensions, @"Accessing index outside of max edge insets extensions space");
return object.environmentState.layoutOptionsState._extensions.edgeInsetsExtensions[idx];
}
#pragma mark - Merging functions for states
ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState environmentState, ASEnvironmentHierarchyState state, ASEnvironmentStatePropagation propagation) {
// Merge object and hierarchy state
LOG(@"Merge object and state: %@ - ASEnvironmentHierarchyState", object);
return environmentState;
}
ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState environmentState, ASEnvironmentLayoutOptionsState state, ASEnvironmentStatePropagation propagation) {
// Merge object and layout options state
LOG(@"Merge object and state: %@ - ASEnvironmentLayoutOptionsState", object);
// Support propagate up
if (propagation == ASEnvironmentStatePropagation::UP) {
// Object is the parent and the state is the state of the child
const ASEnvironmentLayoutOptionsState defaultState = ASEnvironmentDefaultLayoutOptionsState;
ASEnvironmentLayoutOptionsState parentState = environmentState.layoutOptionsState;
// For every field check if the parent value is equal to the default than propegate up the child value to
// the parent
if (parentState.spacingBefore != defaultState.spacingBefore) {
parentState.spacingBefore = state.spacingBefore;
}
if (parentState.spacingAfter != defaultState.spacingAfter) {
parentState.spacingAfter = state.spacingAfter;
}
if (parentState.alignSelf != defaultState.alignSelf) {
parentState.alignSelf = defaultState.alignSelf;
}
if (parentState.flexGrow != defaultState.flexGrow) {
parentState.flexGrow = defaultState.flexGrow;
}
if (!ASRelativeDimensionEqualToRelativeDimension(parentState.flexBasis, defaultState.flexBasis)) {
parentState.flexBasis = defaultState.flexBasis;
}
if (parentState.alignSelf != defaultState.alignSelf) {
parentState.alignSelf = defaultState.alignSelf;
}
if (parentState.ascender != defaultState.ascender) {
parentState.ascender = defaultState.ascender;
}
if (!ASRelativeSizeRangeEqualToRelativeSizeRange(parentState.sizeRange, defaultState.sizeRange)) {
parentState.sizeRange = defaultState.sizeRange;
}
if (CGPointEqualToPoint(parentState.layoutPosition, defaultState.layoutPosition)) {
parentState.layoutPosition = defaultState.layoutPosition;
}
environmentState.layoutOptionsState = parentState;
}
return environmentState;
}

View File

@@ -1,33 +0,0 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <AsyncDisplayKit/ASDisplayNode.h>
#import <AsyncDisplayKit/ASLayoutSpec.h>
#import <AsyncDisplayKit/ASThread.h>
@interface ASDisplayNode(ASLayoutOptions)<ASLayoutable>
@end
@interface ASDisplayNode()
{
ASLayoutOptions *_layoutOptions;
ASDN::RecursiveMutex _layoutOptionsLock;
}
@end
@interface ASLayoutSpec(ASLayoutOptions)<ASLayoutable>
@end
@interface ASLayoutSpec()
{
ASLayoutOptions *_layoutOptions;
ASDN::RecursiveMutex _layoutOptionsLock;
}
@end

View File

@@ -12,7 +12,6 @@
#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASLayoutOptions.h"
static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style,
const ASLayout *layout) {

View File

@@ -14,7 +14,6 @@
#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASLayoutable.h"
#import "ASLayoutOptions.h"
#import "ASAssert.h"
static CGFloat crossOffset(const ASStackLayoutSpecStyle &style,

View File

@@ -14,7 +14,6 @@
#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASLayoutOptions.h"
/**
Sizes the child given the parameters specified, and returns the computed layout.
@@ -116,8 +115,7 @@ static CGFloat computeStackDimensionSum(const std::vector<ASStackUnpositionedIte
children.empty() ? 0 : style.spacing * (children.size() - 1),
[&](CGFloat x, const ASStackUnpositionedItem &l) {
const id<ASLayoutable> child = l.child;
const ASLayoutOptions *layoutOptions = child.layoutOptions;
return x + layoutOptions.spacingBefore + layoutOptions.spacingAfter;
return x + child.spacingBefore + child.spacingAfter;
});
// Sum up the childrens' dimensions (including spacing) in the stack direction.

View File

@@ -13,7 +13,6 @@
#import "ASBackgroundLayoutSpec.h"
#import "ASCenterLayoutSpec.h"
#import "ASStackLayoutSpec.h"
#import "ASLayoutOptions.h"
static const ASSizeRange kSize = {{100, 120}, {320, 160}};

View File

@@ -13,7 +13,6 @@
#import "ASBackgroundLayoutSpec.h"
#import "ASRelativeLayoutSpec.h"
#import "ASStackLayoutSpec.h"
#import "ASLayoutOptions.h"
static const ASSizeRange kSize = {{100, 120}, {320, 160}};

View File

@@ -15,7 +15,6 @@
#import "ASBackgroundLayoutSpec.h"
#import "ASRatioLayoutSpec.h"
#import "ASInsetLayoutSpec.h"
#import "ASLayoutOptions.h"
@interface ASStackLayoutSpecSnapshotTests : ASLayoutSpecSnapshotTestCase
@end