From 96df35e41a1574a5b3d93f81499137401f5d1285 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Tue, 29 Mar 2016 11:22:45 -0700 Subject: [PATCH] Initial commit for ASEnvironment --- AsyncDisplayKit.xcodeproj/project.pbxproj | 108 +++---- AsyncDisplayKit/ASDisplayNode.mm | 35 ++- AsyncDisplayKit/AsyncDisplayKit.h | 2 +- AsyncDisplayKit/Details/ASEnvironment.h | 92 ++++++ AsyncDisplayKit/Details/ASEnvironment.m | 41 +++ AsyncDisplayKit/Layout/ASLayoutOptions.h | 91 ------ AsyncDisplayKit/Layout/ASLayoutOptions.mm | 263 ------------------ .../Layout/ASLayoutOptionsPrivate.mm | 143 ---------- AsyncDisplayKit/Layout/ASLayoutSpec.mm | 40 ++- AsyncDisplayKit/Layout/ASLayoutable.h | 3 +- AsyncDisplayKit/Layout/ASLayoutable.mm | 183 ++++++++++++ AsyncDisplayKit/Layout/ASLayoutablePrivate.h | 8 +- AsyncDisplayKit/Layout/ASStackLayoutSpec.mm | 9 + AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm | 10 +- .../Private/ASDisplayNode+FrameworkPrivate.h | 1 - .../Private/ASDisplayNodeInternal.h | 3 +- .../Private/ASEnvironmentInternal.h | 56 ++++ .../Private/ASEnvironmentInternal.mm | 100 +++++++ .../Private/ASLayoutOptionsPrivate.h | 33 --- .../ASStackBaselinePositionedLayout.mm | 1 - .../Private/ASStackPositionedLayout.mm | 1 - .../Private/ASStackUnpositionedLayout.mm | 4 +- .../ASCenterLayoutSpecSnapshotTests.mm | 1 - .../ASRelativeLayoutSpecSnapshotTests.mm | 1 - .../ASStackLayoutSpecSnapshotTests.mm | 1 - 25 files changed, 620 insertions(+), 610 deletions(-) create mode 100644 AsyncDisplayKit/Details/ASEnvironment.h create mode 100644 AsyncDisplayKit/Details/ASEnvironment.m delete mode 100644 AsyncDisplayKit/Layout/ASLayoutOptions.h delete mode 100644 AsyncDisplayKit/Layout/ASLayoutOptions.mm delete mode 100644 AsyncDisplayKit/Layout/ASLayoutOptionsPrivate.mm create mode 100644 AsyncDisplayKit/Private/ASEnvironmentInternal.h create mode 100644 AsyncDisplayKit/Private/ASEnvironmentInternal.mm delete mode 100644 AsyncDisplayKit/Private/ASLayoutOptionsPrivate.h diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index cdabc84113..ac41e847c5 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -258,6 +258,14 @@ 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 */; }; + 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 +296,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 +740,10 @@ 68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Beta.h"; sourceTree = ""; }; 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMainSerialQueue.h; sourceTree = ""; }; 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMainSerialQueue.mm; sourceTree = ""; }; + 698548611CA9E025008A345F /* ASEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEnvironment.h; sourceTree = ""; }; + 698548621CA9E025008A345F /* ASEnvironment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASEnvironment.m; sourceTree = ""; }; + 69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEnvironmentInternal.h; sourceTree = ""; }; + 69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEnvironmentInternal.mm; sourceTree = ""; }; 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASRangeControllerUpdateRangeProtocol+Beta.h"; sourceTree = ""; }; 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = ""; }; 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit+Debug.h"; sourceTree = ""; }; @@ -755,10 +759,6 @@ 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutable.h; path = AsyncDisplayKit/Layout/ASStackLayoutable.h; sourceTree = ""; }; 9C5586671BD549CB00B50E3A /* ASAsciiArtBoxCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASAsciiArtBoxCreator.h; path = AsyncDisplayKit/Layout/ASAsciiArtBoxCreator.h; sourceTree = ""; }; 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASAsciiArtBoxCreator.m; path = AsyncDisplayKit/Layout/ASAsciiArtBoxCreator.m; sourceTree = ""; }; - 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutOptions.h; path = AsyncDisplayKit/Layout/ASLayoutOptions.h; sourceTree = ""; }; - 9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutOptions.mm; path = AsyncDisplayKit/Layout/ASLayoutOptions.mm; sourceTree = ""; }; - 9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutOptionsPrivate.mm; path = AsyncDisplayKit/Layout/ASLayoutOptionsPrivate.mm; sourceTree = ""; }; - 9C65A7291BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutOptionsPrivate.h; sourceTree = ""; }; 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStaticLayoutable.h; path = AsyncDisplayKit/Layout/ASStaticLayoutable.h; sourceTree = ""; }; 9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackBaselinePositionedLayout.h; sourceTree = ""; }; 9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackBaselinePositionedLayout.mm; sourceTree = ""; }; @@ -802,7 +802,7 @@ ACF6ED161B17843500DA7C62 /* ASStackLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutSpec.h; path = AsyncDisplayKit/Layout/ASStackLayoutSpec.h; sourceTree = ""; }; ACF6ED171B17843500DA7C62 /* ASStackLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASStackLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASStackLayoutSpec.mm; sourceTree = ""; }; ACF6ED181B17843500DA7C62 /* ASStaticLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStaticLayoutSpec.h; path = AsyncDisplayKit/Layout/ASStaticLayoutSpec.h; sourceTree = ""; }; - ACF6ED191B17843500DA7C62 /* ASStaticLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASStaticLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm; sourceTree = ""; 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 = ""; }; ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASInternalHelpers.h; sourceTree = ""; }; ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASInternalHelpers.mm; sourceTree = ""; }; ACF6ED451B17847A00DA7C62 /* ASLayoutSpecUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecUtilities.h; sourceTree = ""; }; @@ -1116,14 +1116,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 +1126,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 +1188,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 */, ); @@ -1338,9 +1341,6 @@ 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */, ACF6ED181B17843500DA7C62 /* ASStaticLayoutSpec.h */, ACF6ED191B17843500DA7C62 /* ASStaticLayoutSpec.mm */, - 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */, - 9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.mm */, - 9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */, ); name = Layout; path = ..; @@ -1379,6 +1379,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 698548631CA9E025008A345F /* ASEnvironment.h in Headers */, E5711A2B1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */, 257754C21BEE458E00737CA5 /* ASTextKitCoreTextAdditions.h in Headers */, A373200F1C571B730011FC94 /* ASTextNode+Beta.h in Headers */, @@ -1462,8 +1463,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 +1486,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 +1522,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 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 +1599,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 +1639,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 */, @@ -1872,6 +1872,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 */, @@ -1915,10 +1916,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 */, @@ -2026,6 +2026,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 */, @@ -2055,6 +2056,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 */, @@ -2072,8 +2074,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 */, diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index b08e64a2f9..febf735ff0 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -10,7 +10,6 @@ #import "ASDisplayNode+Subclasses.h" #import "ASDisplayNode+FrameworkPrivate.h" #import "ASDisplayNode+Beta.h" -#import "ASLayoutOptionsPrivate.h" #import #import @@ -25,6 +24,7 @@ #import "ASDisplayNodeExtras.h" #import "ASEqualityHelpers.h" #import "ASRunLoopQueue.h" +#import "ASEnvironment.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,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c) _contentsScaleForDisplay = ASScreenScale(); _displaySentinel = [[ASSentinel alloc] init]; _preferredFrameSize = CGSizeZero; + + _environmentCollection = ASEnvironmentCollectionCreate(); + ASLayoutableSetValuesForLayoutable(self); } - (id)init @@ -1855,6 +1858,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) if (_methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits) { ASLayoutSpec *layoutSpec = [self layoutSpecThatFits:constrainedSize]; layoutSpec.isMutable = NO; + layoutSpec.parent = self; ASLayout *layout = [layoutSpec measureWithSizeRange:constrainedSize]; // Make sure layoutableObject of the root layout is `self`, so that the flattened layout will be structurally correct. if (layout.layoutableObject != self) { @@ -2666,6 +2670,33 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority"; return self; } +#pragma mark - ASEnvironment + +- (ASEnvironmentCollection *)environmentCollection +{ + return &_environmentCollection; +} + +- (ASDisplayNode *)parent +{ + return self.supernode; +} + +- (void)setParent:(ASDisplayNode *)parent +{ + [self __setSupernode:parent]; +} + +- (NSArray *)children +{ + return self.subnodes; +} + +- (BOOL)supportsMultipleChildren +{ + return NO; +} + #if TARGET_OS_TV #pragma mark - UIFocusEnvironment Protocol (tvOS) diff --git a/AsyncDisplayKit/AsyncDisplayKit.h b/AsyncDisplayKit/AsyncDisplayKit.h index 1c94faffbf..6e11c23a55 100644 --- a/AsyncDisplayKit/AsyncDisplayKit.h +++ b/AsyncDisplayKit/AsyncDisplayKit.h @@ -41,6 +41,7 @@ #import #import +#import #import #import #import @@ -68,7 +69,6 @@ #import #import #import -#import #import #import #import diff --git a/AsyncDisplayKit/Details/ASEnvironment.h b/AsyncDisplayKit/Details/ASEnvironment.h new file mode 100644 index 0000000000..7229a166ea --- /dev/null +++ b/AsyncDisplayKit/Details/ASEnvironment.h @@ -0,0 +1,92 @@ +/* + * 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 + +#import "ASDimension.h" +#import "ASStackLayoutDefines.h" +#import "ASRelativeSize.h" + + +ASDISPLAYNODE_EXTERN_C_BEGIN +NS_ASSUME_NONNULL_BEGIN + + +#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; + + // TODO: ASEnvironment: find a good way to expand the options state + // id otherOptions; +} ASEnvironmentLayoutOptionsState; +extern ASEnvironmentLayoutOptionsState ASEnvironmentLayoutOptionsStateCreate(); + + +#pragma mark ASEnvironmentHierarchyState + +typedef struct ASEnvironmentHierarchyState { + unsigned rasterized:1; // = NO + unsigned rangeManaged:1; // = NO + unsigned transitioningSupernodes:1; // = NO + unsigned layoutPending:1; // = NO +} ASEnvironmentHierarchyState; +extern ASEnvironmentHierarchyState ASEnvironmentHierarchyStateCreate(); + + +#pragma mark ASEnvironmentCollection + +typedef struct ASEnvironmentCollection { + struct ASEnvironmentHierarchyState hierarchyState; + struct ASEnvironmentLayoutOptionsState layoutOptionsState; +} ASEnvironmentCollection; +extern ASEnvironmentCollection ASEnvironmentCollectionCreate(); + +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 ASEnvironmentCollection 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 + +/// The environment collection of an object which class conforms to the ASEnvironment protocol +- (ASEnvironmentCollection *)environmentCollection; + +/// Returns the parent of an object which class conforms to the ASEnvironment protocol +- (id)parent; + +/// Set the parent of an object which class conforms to the ASEnvironment protocol +- (void)setParent:(id)parent; + +/// Returns all children of an object which class conforms to the ASEnvironment protocol +- (NSArray> *)children; + +// TODO: ASEnvironment: Find a better name. As in ASDisplayNode this returns NO which in theory is wrong as as +// it supports multiple subnodes +- (BOOL)supportsMultipleChildren; + +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/AsyncDisplayKit/Details/ASEnvironment.m b/AsyncDisplayKit/Details/ASEnvironment.m new file mode 100644 index 0000000000..e08795a7b3 --- /dev/null +++ b/AsyncDisplayKit/Details/ASEnvironment.m @@ -0,0 +1,41 @@ +/* + * 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 ASEnvironmentLayoutOptionsStateCreate() +{ + return (ASEnvironmentLayoutOptionsState) { + .spacingBefore = 0, + .flexBasis = ASRelativeDimensionUnconstrained, + .alignSelf = ASStackLayoutAlignSelfAuto, + + .sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(CGSizeZero), ASRelativeSizeMakeWithCGSize(CGSizeZero)), + .layoutPosition = CGPointZero + }; +} + +ASEnvironmentHierarchyState ASEnvironmentHierarchyStateCreate() +{ + return (ASEnvironmentHierarchyState) { + .rasterized = NO, + .rangeManaged = NO, + .transitioningSupernodes = NO, + .layoutPending = NO + }; +} + +ASEnvironmentCollection ASEnvironmentCollectionCreate() +{ + return (ASEnvironmentCollection) { + .hierarchyState = ASEnvironmentHierarchyStateCreate(), + .layoutOptionsState = ASEnvironmentLayoutOptionsStateCreate() + }; +} \ No newline at end of file diff --git a/AsyncDisplayKit/Layout/ASLayoutOptions.h b/AsyncDisplayKit/Layout/ASLayoutOptions.h deleted file mode 100644 index fbc50bf8e3..0000000000 --- a/AsyncDisplayKit/Layout/ASLayoutOptions.h +++ /dev/null @@ -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 -#import -#import - -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 - -/** - * 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)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 - diff --git a/AsyncDisplayKit/Layout/ASLayoutOptions.mm b/AsyncDisplayKit/Layout/ASLayoutOptions.mm deleted file mode 100644 index ad503014bf..0000000000 --- a/AsyncDisplayKit/Layout/ASLayoutOptions.mm +++ /dev/null @@ -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 -#import -#import -#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)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, 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)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 diff --git a/AsyncDisplayKit/Layout/ASLayoutOptionsPrivate.mm b/AsyncDisplayKit/Layout/ASLayoutOptionsPrivate.mm deleted file mode 100644 index 334f42f1a5..0000000000 --- a/AsyncDisplayKit/Layout/ASLayoutOptionsPrivate.mm +++ /dev/null @@ -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 - - -/** - * 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 diff --git a/AsyncDisplayKit/Layout/ASLayoutSpec.mm b/AsyncDisplayKit/Layout/ASLayoutSpec.mm index abb428ebd1..d0b1b7ba48 100644 --- a/AsyncDisplayKit/Layout/ASLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASLayoutSpec.mm @@ -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 static NSString * const kDefaultChildKey = @"kDefaultChildKey"; static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey"; -@interface ASLayoutSpec() +@interface ASLayoutSpec() { + ASEnvironmentCollection _environmentCollection; +} +@property (nonatomic, weak) id parent; @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,9 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey"; return nil; } _isMutable = YES; + _environmentCollection = ASEnvironmentCollectionCreate(); + ASLayoutableSetValuesForLayoutable(self); + return self; } @@ -75,7 +82,8 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey"; id finalLayoutable = [child finalLayoutable]; if (finalLayoutable != child) { - [finalLayoutable.layoutOptions copyFromOptions:child.layoutOptions]; + // Copy layout options + finalLayoutable.environmentCollection->layoutOptionsState = child.environmentCollection->layoutOptionsState; return finalLayoutable; } } @@ -90,6 +98,15 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey"; return _layoutChildren; } +- (void)setParent:(id)parent +{ + _parent = parent; + + if (![parent supportsMultipleChildren]) { + ASEnvironmentStatePropagateUp(parent, self.environmentCollection->layoutOptionsState); + } +} + - (void)setChild:(id)child; { [self setChild:child forIdentifier:kDefaultChildKey]; @@ -128,6 +145,19 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey"; return self.layoutChildren[kDefaultChildrenKey]; } + +#pragma mark - ASEnvironment + +- (ASEnvironmentCollection *)environmentCollection +{ + return &_environmentCollection; +} + +- (BOOL)supportsMultipleChildren +{ + return NO; +} + @end @implementation ASLayoutSpec (Debugging) diff --git a/AsyncDisplayKit/Layout/ASLayoutable.h b/AsyncDisplayKit/Layout/ASLayoutable.h index 121477b1f6..11553674f4 100644 --- a/AsyncDisplayKit/Layout/ASLayoutable.h +++ b/AsyncDisplayKit/Layout/ASLayoutable.h @@ -15,6 +15,7 @@ #import #import +#import @class ASLayout; @class ASLayoutSpec; @@ -37,7 +38,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 +@protocol ASLayoutable /** * @abstract Calculate a layout based on given size range. diff --git a/AsyncDisplayKit/Layout/ASLayoutable.mm b/AsyncDisplayKit/Layout/ASLayoutable.mm index 78aeb9bc12..6bdfdbe758 100644 --- a/AsyncDisplayKit/Layout/ASLayoutable.mm +++ b/AsyncDisplayKit/Layout/ASLayoutable.mm @@ -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 #import @@ -75,3 +81,180 @@ void ASLayoutableClearCurrentContext() ASDN::StaticMutexLocker l(_layoutableContextLock); layoutableContextMap.erase(key); } + +/** + * Given an id, 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 this helper function + * 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 via this function 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 ASLayoutableSetValuesForLayoutable(id layoutable) +{ + //ASDN::MutexLocker l(_propertyLock); + if ([layoutable isKindOfClass:[ASDisplayNode class]]) { + ASDisplayNode *displayNode = (ASDisplayNode *)layoutable; + displayNode.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(); + textNode.ascender = round([[attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * screenScale)/screenScale; + textNode.descender = round([[attributedString attribute:NSFontAttributeName atIndex:attributedString.length - 1 effectiveRange:NULL] descender] * screenScale)/screenScale; + } + } + + } +} + +/** + * 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. + */ + +#define ASEnvironmentLayoutOptionsForwarding \ +- (ASEnvironmentLayoutOptionsState *)layoutOptionsState\ +{\ + return &(self.environmentCollection->layoutOptionsState);\ +}\ +- (void)propagateUpLayoutOptionsState\ +{\ + id parent = [self parent];\ + if (![parent supportsMultipleChildren]) {\ + ASEnvironmentStatePropagateUp(parent, self.environmentCollection->layoutOptionsState);\ + }\ +}\ +\ +- (CGFloat)spacingAfter\ +{\ + return self.layoutOptionsState->spacingAfter;\ +}\ +\ +- (void)setSpacingAfter:(CGFloat)spacingAfter\ +{\ + self.layoutOptionsState->spacingAfter = spacingAfter;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (CGFloat)spacingBefore\ +{\ + return self.layoutOptionsState->spacingBefore;\ +}\ +\ +- (void)setSpacingBefore:(CGFloat)spacingBefore\ +{\ + self.layoutOptionsState->spacingBefore = spacingBefore;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (BOOL)flexGrow\ +{\ + return self.layoutOptionsState->flexGrow;\ +}\ +\ +- (void)setFlexGrow:(BOOL)flexGrow\ +{\ + self.layoutOptionsState->flexGrow = flexGrow;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (BOOL)flexShrink\ +{\ + return self.layoutOptionsState->flexShrink;\ +}\ +\ +- (void)setFlexShrink:(BOOL)flexShrink\ +{\ + self.layoutOptionsState->flexShrink = flexShrink;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (ASRelativeDimension)flexBasis\ +{\ + return self.layoutOptionsState->flexBasis;\ +}\ +\ +- (void)setFlexBasis:(ASRelativeDimension)flexBasis\ +{\ + self.layoutOptionsState->flexBasis = flexBasis;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (ASStackLayoutAlignSelf)alignSelf\ +{\ + return self.layoutOptionsState->alignSelf;\ +}\ +\ +- (void)setAlignSelf:(ASStackLayoutAlignSelf)alignSelf\ +{\ + self.layoutOptionsState->alignSelf = alignSelf;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (CGFloat)ascender\ +{\ + return self.layoutOptionsState->ascender;\ +}\ +\ +- (void)setAscender:(CGFloat)ascender\ +{\ + self.layoutOptionsState->ascender = ascender;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (CGFloat)descender\ +{\ + return self.layoutOptionsState->descender;\ +}\ +\ +- (void)setDescender:(CGFloat)descender\ +{\ + self.layoutOptionsState->descender = descender;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (ASRelativeSizeRange)sizeRange\ +{\ + return self.layoutOptionsState->sizeRange;\ +}\ +\ +- (void)setSizeRange:(ASRelativeSizeRange)sizeRange\ +{\ + self.layoutOptionsState->sizeRange = sizeRange;\ + [self propagateUpLayoutOptionsState];\ +}\ +\ +- (CGPoint)layoutPosition\ +{\ + return self.layoutOptionsState->layoutPosition;\ +}\ +\ +- (void)setLayoutPosition:(CGPoint)layoutPosition\ +{\ + self.layoutOptionsState->layoutPosition = layoutPosition;\ + [self propagateUpLayoutOptionsState];\ +}\ + + +@implementation ASDisplayNode(ASLayoutOptions) +ASEnvironmentLayoutOptionsForwarding +@end + +@implementation ASLayoutSpec(ASLayoutOptions) +ASEnvironmentLayoutOptionsForwarding +@end + diff --git a/AsyncDisplayKit/Layout/ASLayoutablePrivate.h b/AsyncDisplayKit/Layout/ASLayoutablePrivate.h index 2ae509b621..e4aa37e8db 100644 --- a/AsyncDisplayKit/Layout/ASLayoutablePrivate.h +++ b/AsyncDisplayKit/Layout/ASLayoutablePrivate.h @@ -11,7 +11,6 @@ #import @class ASLayoutSpec; -@class ASLayoutOptions; @protocol ASLayoutable; struct ASLayoutableContext { @@ -35,6 +34,8 @@ extern struct ASLayoutableContext ASLayoutableGetCurrentContext(); extern void ASLayoutableClearCurrentContext(); +extern void ASLayoutableSetValuesForLayoutable(id layoutable); + /** * The base protocol for ASLayoutable. Generally the methods/properties in this class do not need to be * called by the end user and are only called internally. However, there may be a case where the methods are useful. @@ -60,9 +61,4 @@ extern void ASLayoutableClearCurrentContext(); */ @property (nonatomic, assign) BOOL isFinalLayoutable; - -/** - * The class that holds all of the layoutOptions set on an ASLayoutable. - */ -@property (nonatomic, strong, readonly) ASLayoutOptions *layoutOptions; @end diff --git a/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm b/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm index 76539bf57a..6af951ec86 100644 --- a/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm @@ -198,6 +198,15 @@ @end +@implementation ASStackLayoutSpec (ASEnvironment) + +- (BOOL)supportsMultipleChildren +{ + return YES; +} + +@end + @implementation ASStackLayoutSpec (Debugging) #pragma mark - ASLayoutableAsciiArtProtocol diff --git a/AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm b/AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm index 2d0edba4cd..388b06aa02 100644 --- a/AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm @@ -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)supportsMultipleChildren +{ + return YES; +} + +@end + @implementation ASStaticLayoutSpec (Debugging) #pragma mark - ASLayoutableAsciiArtProtocol diff --git a/AsyncDisplayKit/Private/ASDisplayNode+FrameworkPrivate.h b/AsyncDisplayKit/Private/ASDisplayNode+FrameworkPrivate.h index 996ec2a7d0..07cb3440b8 100644 --- a/AsyncDisplayKit/Private/ASDisplayNode+FrameworkPrivate.h +++ b/AsyncDisplayKit/Private/ASDisplayNode+FrameworkPrivate.h @@ -16,7 +16,6 @@ #import "ASDisplayNode.h" #import "ASSentinel.h" #import "ASThread.h" -#import "ASLayoutOptions.h" #import "_ASDisplayLayer.h" NS_ASSUME_NONNULL_BEGIN diff --git a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h index bd00cd9417..f632f64ae0 100644 --- a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h +++ b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h @@ -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 @@ -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; + ASEnvironmentCollection _environmentCollection; ASLayout *_layout; ASSizeRange _constrainedSize; diff --git a/AsyncDisplayKit/Private/ASEnvironmentInternal.h b/AsyncDisplayKit/Private/ASEnvironmentInternal.h new file mode 100644 index 0000000000..cf77e36cfa --- /dev/null +++ b/AsyncDisplayKit/Private/ASEnvironmentInternal.h @@ -0,0 +1,56 @@ +/* + * 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 ASEnvironmentStatePropagation { DOWN, UP }; + +#pragma mark - Traversing an ASEnvironment Tree + +void ASEnvironmentPerformBlockOnObjectAndChildren(id object, void(^block)(id object)); +void ASEnvironmentPerformBlockOnObjectAndParents(id object, void(^block)(id object)); + + +#pragma mark - Merging + +static const struct ASEnvironmentLayoutOptionsState ASEnvironmentDefaultLayoutOptionsState = {}; +void ASEnvironmentMergeObjectAndState(id object, ASEnvironmentLayoutOptionsState& state, ASEnvironmentStatePropagation propagation); + + +static const struct ASEnvironmentHierarchyState ASEnvironmentDefaultHierarchyState = {}; +void ASEnvironmentMergeObjectAndState(id object, ASEnvironmentHierarchyState& state, ASEnvironmentStatePropagation propagation); + + +#pragma mark - Propagation + +template +void ASEnvironmentStatePropagateDown(id object, ASEnvironmentStateType& state) { + ASEnvironmentPerformBlockOnObjectAndChildren(object, ^(id node) { + ASEnvironmentMergeObjectAndState(object, state, DOWN); + }); +} + +template +void ASEnvironmentStatePropagateUp(id object, ASEnvironmentStateType& state) { + ASEnvironmentPerformBlockOnObjectAndParents(object, ^(id node) { + ASEnvironmentMergeObjectAndState(object, state, UP); + }); +} + +template +void ASEnvironmentStateApply(id object, ASEnvironmentStateType& state, ASEnvironmentStatePropagation propagate) { + if (propagate == DOWN) { + ASEnvironmentStatePropagateUp(object, state); + } else if (propagate == UP) { + ASEnvironmentStatePropagateDown(object, state); + } +} diff --git a/AsyncDisplayKit/Private/ASEnvironmentInternal.mm b/AsyncDisplayKit/Private/ASEnvironmentInternal.mm new file mode 100644 index 0000000000..b4e217a1ec --- /dev/null +++ b/AsyncDisplayKit/Private/ASEnvironmentInternal.mm @@ -0,0 +1,100 @@ +/* + * 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 + +//#define LOG(...) NSLog(__VA_ARGS__) +#define LOG(...) + +#pragma mark - Traversing an ASEnvironment Tree + +void ASEnvironmentPerformBlockOnObjectAndChildren(id object, void(^block)(id node)) +{ + if (!object) { + return; + } + + std::queue> queue; + queue.push(object); + + while (!queue.empty()) { + id object = queue.front(); queue.pop(); + + block(object); + + for (id child in [object children]) { + queue.push(child); + } + } +} + +void ASEnvironmentPerformBlockOnObjectAndParents(id object, void(^block)(id node)) +{ + while (object) { + block(object); + object = [object parent]; + } +} + + +#pragma mark - Merging functions for states + +void ASEnvironmentMergeObjectAndState(id object, ASEnvironmentHierarchyState& state, ASEnvironmentStatePropagation propagation) { + // Merge object and hierarchy state + LOG(@"Merge object and state: %@ - ASEnvironmentHierarchyState", object); +} + +void ASEnvironmentMergeObjectAndState(id object, ASEnvironmentLayoutOptionsState& state, ASEnvironmentStatePropagation propagation) { + // Merge object and layout options state + LOG(@"Merge object and state: %@ - ASEnvironmentLayoutOptionsState", object); + + // Support propagate up + if (propagation == UP) { + + // Object is the parent and the state is the state of the child + const ASEnvironmentLayoutOptionsState defaultState = ASEnvironmentDefaultLayoutOptionsState; + ASEnvironmentLayoutOptionsState parentState = object.environmentCollection->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; + } + + object.environmentCollection->layoutOptionsState = parentState; + } + +} diff --git a/AsyncDisplayKit/Private/ASLayoutOptionsPrivate.h b/AsyncDisplayKit/Private/ASLayoutOptionsPrivate.h deleted file mode 100644 index 34a26da4f2..0000000000 --- a/AsyncDisplayKit/Private/ASLayoutOptionsPrivate.h +++ /dev/null @@ -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 -#import -#import - -@interface ASDisplayNode(ASLayoutOptions) -@end - -@interface ASDisplayNode() -{ - ASLayoutOptions *_layoutOptions; - ASDN::RecursiveMutex _layoutOptionsLock; -} -@end - -@interface ASLayoutSpec(ASLayoutOptions) -@end - -@interface ASLayoutSpec() -{ - ASLayoutOptions *_layoutOptions; - ASDN::RecursiveMutex _layoutOptionsLock; -} -@end diff --git a/AsyncDisplayKit/Private/ASStackBaselinePositionedLayout.mm b/AsyncDisplayKit/Private/ASStackBaselinePositionedLayout.mm index ed6b622162..46df924adf 100644 --- a/AsyncDisplayKit/Private/ASStackBaselinePositionedLayout.mm +++ b/AsyncDisplayKit/Private/ASStackBaselinePositionedLayout.mm @@ -12,7 +12,6 @@ #import "ASLayoutSpecUtilities.h" #import "ASStackLayoutSpecUtilities.h" -#import "ASLayoutOptions.h" static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style, const ASLayout *layout) { diff --git a/AsyncDisplayKit/Private/ASStackPositionedLayout.mm b/AsyncDisplayKit/Private/ASStackPositionedLayout.mm index 428319d317..cd18dd2157 100644 --- a/AsyncDisplayKit/Private/ASStackPositionedLayout.mm +++ b/AsyncDisplayKit/Private/ASStackPositionedLayout.mm @@ -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, diff --git a/AsyncDisplayKit/Private/ASStackUnpositionedLayout.mm b/AsyncDisplayKit/Private/ASStackUnpositionedLayout.mm index a19ae298ba..57902a6b4e 100644 --- a/AsyncDisplayKit/Private/ASStackUnpositionedLayout.mm +++ b/AsyncDisplayKit/Private/ASStackUnpositionedLayout.mm @@ -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 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. diff --git a/AsyncDisplayKitTests/ASCenterLayoutSpecSnapshotTests.mm b/AsyncDisplayKitTests/ASCenterLayoutSpecSnapshotTests.mm index f6ba9da1e5..bb38be0d18 100644 --- a/AsyncDisplayKitTests/ASCenterLayoutSpecSnapshotTests.mm +++ b/AsyncDisplayKitTests/ASCenterLayoutSpecSnapshotTests.mm @@ -13,7 +13,6 @@ #import "ASBackgroundLayoutSpec.h" #import "ASCenterLayoutSpec.h" #import "ASStackLayoutSpec.h" -#import "ASLayoutOptions.h" static const ASSizeRange kSize = {{100, 120}, {320, 160}}; diff --git a/AsyncDisplayKitTests/ASRelativeLayoutSpecSnapshotTests.mm b/AsyncDisplayKitTests/ASRelativeLayoutSpecSnapshotTests.mm index 468b515a05..213045ea68 100644 --- a/AsyncDisplayKitTests/ASRelativeLayoutSpecSnapshotTests.mm +++ b/AsyncDisplayKitTests/ASRelativeLayoutSpecSnapshotTests.mm @@ -13,7 +13,6 @@ #import "ASBackgroundLayoutSpec.h" #import "ASRelativeLayoutSpec.h" #import "ASStackLayoutSpec.h" -#import "ASLayoutOptions.h" static const ASSizeRange kSize = {{100, 120}, {320, 160}}; diff --git a/AsyncDisplayKitTests/ASStackLayoutSpecSnapshotTests.mm b/AsyncDisplayKitTests/ASStackLayoutSpecSnapshotTests.mm index 20989a71d3..d5ca9074aa 100644 --- a/AsyncDisplayKitTests/ASStackLayoutSpecSnapshotTests.mm +++ b/AsyncDisplayKitTests/ASStackLayoutSpecSnapshotTests.mm @@ -15,7 +15,6 @@ #import "ASBackgroundLayoutSpec.h" #import "ASRatioLayoutSpec.h" #import "ASInsetLayoutSpec.h" -#import "ASLayoutOptions.h" @interface ASStackLayoutSpecSnapshotTests : ASLayoutSpecSnapshotTestCase @end