From 65b4961802b5e3239e858224ec0ecd342d2fd254 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Tue, 29 Mar 2016 19:59:17 -0700 Subject: [PATCH] Add extensibility support for ASEnvironmentLayoutOptionsState --- AsyncDisplayKit.xcodeproj/project.pbxproj | 10 +++- AsyncDisplayKit/ASDisplayNode.mm | 36 +++++++++++++- AsyncDisplayKit/Details/ASEnvironment.h | 21 ++++++-- AsyncDisplayKit/Layout/ASLayoutSpec.mm | 33 +++++++++++++ AsyncDisplayKit/Layout/ASLayoutable.h | 3 +- AsyncDisplayKit/Layout/ASLayoutable.mm | 7 ++- .../Layout/ASLayoutableExtensibility.h | 25 ++++++++++ .../Private/ASEnvironmentInternal.h | 13 +++++ .../Private/ASEnvironmentInternal.mm | 49 +++++++++++++++++++ 9 files changed, 186 insertions(+), 11 deletions(-) create mode 100644 AsyncDisplayKit/Layout/ASLayoutableExtensibility.h diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index ac41e847c5..e159eae52b 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -262,6 +262,8 @@ 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 */; }; @@ -742,6 +744,7 @@ 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 = ""; }; + 698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutableExtensibility.h; path = AsyncDisplayKit/Layout/ASLayoutableExtensibility.h; 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 = ""; }; @@ -1317,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 */, @@ -1334,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 */, @@ -1379,6 +1383,7 @@ 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 */, @@ -1522,6 +1527,7 @@ 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 */, diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index febf735ff0..d6fc281d17 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -24,7 +24,7 @@ #import "ASDisplayNodeExtras.h" #import "ASEqualityHelpers.h" #import "ASRunLoopQueue.h" -#import "ASEnvironment.h" +#import "ASEnvironmentInternal.h" #import "ASInternalHelpers.h" #import "ASLayout.h" @@ -2697,6 +2697,40 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority"; return NO; } + +#pragma mark - ASLayoutableExtensibility + +- (void)setLayoutOptionExtensionBool:(BOOL)value atIndex:(int)idx +{ + _ASEnvironmentLayoutOptionsExtensionSetBoolAtIndex(self, idx, value); +} + +- (BOOL)layoutOptionExtensionBoolAtIndex:(int)idx +{ + return _ASEnvironmentLayoutOptionsExtensionGetBoolAtIndex(self, idx); +} + +- (void)setLayoutOptionExtensionInteger:(NSInteger)value atIndex:(int)idx +{ + _ASEnvironmentLayoutOptionsExtensionSetIntegerAtIndex(self, idx, value); +} + +- (NSInteger)layoutOptionExtensionIntegerAtIndex:(int)idx +{ + return _ASEnvironmentLayoutOptionsExtensionGetIntegerAtIndex(self, idx); +} + +- (void)setLayoutOptionExtensionEdgeInsets:(UIEdgeInsets)value atIndex:(int)idx +{ + _ASEnvironmentLayoutOptionsExtensionSetEdgeInsetsAtIndex(self, idx, value); +} + +- (UIEdgeInsets)layoutOptionExtensionEdgeInsetsAtIndex:(int)idx +{ + return _ASEnvironmentLayoutOptionsExtensionGetEdgeInsetsAtIndex(self, idx); +} + + #if TARGET_OS_TV #pragma mark - UIFocusEnvironment Protocol (tvOS) diff --git a/AsyncDisplayKit/Details/ASEnvironment.h b/AsyncDisplayKit/Details/ASEnvironment.h index 7229a166ea..7f1f0f8863 100644 --- a/AsyncDisplayKit/Details/ASEnvironment.h +++ b/AsyncDisplayKit/Details/ASEnvironment.h @@ -18,8 +18,20 @@ 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 ASEnvironmentLayoutOptionsState +#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; @@ -34,13 +46,12 @@ typedef struct ASEnvironmentLayoutOptionsState { ASRelativeSizeRange sizeRange;// = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(CGSizeZero), ASRelativeSizeMakeWithCGSize(CGSizeZero));; CGPoint layoutPosition;// = CGPointZero; - // TODO: ASEnvironment: find a good way to expand the options state - // id otherOptions; + ASEnvironmentStateExtensions _extensions; } ASEnvironmentLayoutOptionsState; extern ASEnvironmentLayoutOptionsState ASEnvironmentLayoutOptionsStateCreate(); -#pragma mark ASEnvironmentHierarchyState +#pragma mark - ASEnvironmentHierarchyState typedef struct ASEnvironmentHierarchyState { unsigned rasterized:1; // = NO @@ -51,7 +62,7 @@ typedef struct ASEnvironmentHierarchyState { extern ASEnvironmentHierarchyState ASEnvironmentHierarchyStateCreate(); -#pragma mark ASEnvironmentCollection +#pragma mark - ASEnvironmentCollection typedef struct ASEnvironmentCollection { struct ASEnvironmentHierarchyState hierarchyState; diff --git a/AsyncDisplayKit/Layout/ASLayoutSpec.mm b/AsyncDisplayKit/Layout/ASLayoutSpec.mm index d0b1b7ba48..77abc59671 100644 --- a/AsyncDisplayKit/Layout/ASLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASLayoutSpec.mm @@ -158,6 +158,39 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey"; return NO; } + +#pragma mark - ASLayoutableExtensibility + +- (void)setLayoutOptionExtensionBool:(BOOL)value atIndex:(int)idx +{ + _ASEnvironmentLayoutOptionsExtensionSetBoolAtIndex(self, idx, value); +} + +- (BOOL)layoutOptionExtensionBoolAtIndex:(int)idx +{ + return _ASEnvironmentLayoutOptionsExtensionGetBoolAtIndex(self, idx); +} + +- (void)setLayoutOptionExtensionInteger:(NSInteger)value atIndex:(int)idx +{ + _ASEnvironmentLayoutOptionsExtensionSetIntegerAtIndex(self, idx, value); +} + +- (NSInteger)layoutOptionExtensionIntegerAtIndex:(int)idx +{ + return _ASEnvironmentLayoutOptionsExtensionGetIntegerAtIndex(self, idx); +} + +- (void)setLayoutOptionExtensionEdgeInsets:(UIEdgeInsets)value atIndex:(int)idx +{ + _ASEnvironmentLayoutOptionsExtensionSetEdgeInsetsAtIndex(self, idx, value); +} + +- (UIEdgeInsets)layoutOptionExtensionEdgeInsetsAtIndex:(int)idx +{ + return _ASEnvironmentLayoutOptionsExtensionGetEdgeInsetsAtIndex(self, idx); +} + @end @implementation ASLayoutSpec (Debugging) diff --git a/AsyncDisplayKit/Layout/ASLayoutable.h b/AsyncDisplayKit/Layout/ASLayoutable.h index 11553674f4..325a81535c 100644 --- a/AsyncDisplayKit/Layout/ASLayoutable.h +++ b/AsyncDisplayKit/Layout/ASLayoutable.h @@ -16,6 +16,7 @@ #import #import +#import @class ASLayout; @class ASLayoutSpec; @@ -38,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 +@protocol ASLayoutable /** * @abstract Calculate a layout based on given size range. diff --git a/AsyncDisplayKit/Layout/ASLayoutable.mm b/AsyncDisplayKit/Layout/ASLayoutable.mm index 6bdfdbe758..c38586ff5a 100644 --- a/AsyncDisplayKit/Layout/ASLayoutable.mm +++ b/AsyncDisplayKit/Layout/ASLayoutable.mm @@ -114,6 +114,9 @@ void ASLayoutableSetValuesForLayoutable(id layoutable) } } + +#pragma mark - ASLayoutOptionsForwarding + /** * 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. @@ -250,11 +253,11 @@ void ASLayoutableSetValuesForLayoutable(id layoutable) }\ -@implementation ASDisplayNode(ASLayoutOptions) +@implementation ASDisplayNode(ASLayoutOptionsForwarding) ASEnvironmentLayoutOptionsForwarding @end -@implementation ASLayoutSpec(ASLayoutOptions) +@implementation ASLayoutSpec(ASLayoutOptionsForwarding) ASEnvironmentLayoutOptionsForwarding @end diff --git a/AsyncDisplayKit/Layout/ASLayoutableExtensibility.h b/AsyncDisplayKit/Layout/ASLayoutableExtensibility.h new file mode 100644 index 0000000000..1451368d27 --- /dev/null +++ b/AsyncDisplayKit/Layout/ASLayoutableExtensibility.h @@ -0,0 +1,25 @@ +// +// ASLayoutableExtensibility.h +// AsyncDisplayKit +// +// Created by Michael Schneider on 3/29/16. +// Copyright © 2016 Facebook. All rights reserved. +// + +#import + +@protocol ASLayoutableExtensibility + +/// 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 diff --git a/AsyncDisplayKit/Private/ASEnvironmentInternal.h b/AsyncDisplayKit/Private/ASEnvironmentInternal.h index cf77e36cfa..877508330a 100644 --- a/AsyncDisplayKit/Private/ASEnvironmentInternal.h +++ b/AsyncDisplayKit/Private/ASEnvironmentInternal.h @@ -14,6 +14,19 @@ enum ASEnvironmentStatePropagation { DOWN, UP }; + +#pragma mark - Set and get extensible values for layout options + +void _ASEnvironmentLayoutOptionsExtensionSetBoolAtIndex(id object, int idx, BOOL value); +BOOL _ASEnvironmentLayoutOptionsExtensionGetBoolAtIndex(id object, int idx); + +void _ASEnvironmentLayoutOptionsExtensionSetIntegerAtIndex(id object, int idx, NSInteger value); +NSInteger _ASEnvironmentLayoutOptionsExtensionGetIntegerAtIndex(id object, int idx); + +void _ASEnvironmentLayoutOptionsExtensionSetEdgeInsetsAtIndex(id object, int idx, UIEdgeInsets value); +UIEdgeInsets _ASEnvironmentLayoutOptionsExtensionGetEdgeInsetsAtIndex(id object, int idx); + + #pragma mark - Traversing an ASEnvironment Tree void ASEnvironmentPerformBlockOnObjectAndChildren(id object, void(^block)(id object)); diff --git a/AsyncDisplayKit/Private/ASEnvironmentInternal.mm b/AsyncDisplayKit/Private/ASEnvironmentInternal.mm index b4e217a1ec..2ab5ed21a0 100644 --- a/AsyncDisplayKit/Private/ASEnvironmentInternal.mm +++ b/AsyncDisplayKit/Private/ASEnvironmentInternal.mm @@ -9,6 +9,7 @@ */ #import "ASEnvironmentInternal.h" + #import //#define LOG(...) NSLog(__VA_ARGS__) @@ -45,6 +46,54 @@ void ASEnvironmentPerformBlockOnObjectAndParents(id object, void( } +#pragma mark - Set and get extensible values from state structs + +void _ASEnvironmentLayoutOptionsExtensionSetBoolAtIndex(id object, int idx, BOOL value) +{ + NSCAssert(idx < kMaxEnvironmentStateBoolExtensions, @"Setting index outside of max bool extensions space"); + + ASEnvironmentStateExtensions extension = object.environmentCollection->layoutOptionsState._extensions; + extension.boolExtensions[idx] = value; + object.environmentCollection->layoutOptionsState._extensions = extension; +} + +BOOL _ASEnvironmentLayoutOptionsExtensionGetBoolAtIndex(id object, int idx) +{ + NSCAssert(idx < kMaxEnvironmentStateBoolExtensions, @"Accessing index outside of max bool extensions space"); + return object.environmentCollection->layoutOptionsState._extensions.boolExtensions[idx]; +} + +void _ASEnvironmentLayoutOptionsExtensionSetIntegerAtIndex(id object, int idx, NSInteger value) +{ + NSCAssert(idx < kMaxEnvironmentStateIntegerExtensions, @"Setting index outside of max integer extensions space"); + + ASEnvironmentStateExtensions extension = object.environmentCollection->layoutOptionsState._extensions; + extension.integerExtensions[idx] = value; + object.environmentCollection->layoutOptionsState._extensions = extension; +} + +NSInteger _ASEnvironmentLayoutOptionsExtensionGetIntegerAtIndex(id object, int idx) +{ + NSCAssert(idx < kMaxEnvironmentStateIntegerExtensions, @"Accessing index outside of max integer extensions space"); + return object.environmentCollection->layoutOptionsState._extensions.integerExtensions[idx]; +} + +void _ASEnvironmentLayoutOptionsExtensionSetEdgeInsetsAtIndex(id object, int idx, UIEdgeInsets value) +{ + NSCAssert(idx < kMaxEnvironmentStateEdgeInsetExtensions, @"Setting index outside of max edge insets extensions space"); + + ASEnvironmentStateExtensions extension = object.environmentCollection->layoutOptionsState._extensions; + extension.edgeInsetsExtensions[idx] = value; + object.environmentCollection->layoutOptionsState._extensions = extension; +} + +UIEdgeInsets _ASEnvironmentLayoutOptionsExtensionGetEdgeInsetsAtIndex(id object, int idx) +{ + NSCAssert(idx < kMaxEnvironmentStateEdgeInsetExtensions, @"Accessing index outside of max edge insets extensions space"); + return object.environmentCollection->layoutOptionsState._extensions.edgeInsetsExtensions[idx]; +} + + #pragma mark - Merging functions for states void ASEnvironmentMergeObjectAndState(id object, ASEnvironmentHierarchyState& state, ASEnvironmentStatePropagation propagation) {