diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index cf0531770d..3cbf2848da 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -210,9 +210,6 @@ 697796601D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */; }; 697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */; }; 697B315A1CFE4B410049936F /* ASEditableTextNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */; }; - 697C0DE41CF38F28001DE0D4 /* ASLayoutValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */; }; - 697C0DE51CF38F28001DE0D4 /* ASLayoutValidation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */; }; - 697C0DE61CF38F28001DE0D4 /* ASLayoutValidation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */; }; 698548641CA9E025008A345F /* ASEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 698548611CA9E025008A345F /* ASEnvironment.h */; settings = {ATTRIBUTES = (Public, ); }; }; 698C8B621CAB49FC0052DC3F /* ASLayoutableExtensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */; settings = {ATTRIBUTES = (Public, ); }; }; 69B225671D72535E00B25B22 /* ASDisplayNodeLayoutTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69B225661D72535E00B25B22 /* ASDisplayNodeLayoutTests.mm */; }; @@ -619,7 +616,6 @@ F7CE6CA01D2CDB5800BE4C15 /* ASStackUnpositionedLayout.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = ACF6ED491B17847A00DA7C62 /* ASStackUnpositionedLayout.h */; }; F7CE6CA11D2CDB5800BE4C15 /* ASWeakSet.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CC3B20871C3F7A5400798563 /* ASWeakSet.h */; }; F7CE6CA21D2CDB5800BE4C15 /* ASDefaultPlaybackButton.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8B0768B11CE752EC002E1453 /* ASDefaultPlaybackButton.h */; }; - F7CE6CA31D2CDB5800BE4C15 /* ASLayoutValidation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */; }; F7CE6CA41D2CDB5800BE4C15 /* ASLayoutManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = B30BF6501C5964B0004FCD53 /* ASLayoutManager.h */; }; F7CE6CB71D2CE2D000BE4C15 /* ASLayoutableExtensibility.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */; }; /* End PBXBuildFile section */ @@ -793,7 +789,6 @@ F7CE6CA01D2CDB5800BE4C15 /* ASStackUnpositionedLayout.h in CopyFiles */, F7CE6CA11D2CDB5800BE4C15 /* ASWeakSet.h in CopyFiles */, F7CE6CA21D2CDB5800BE4C15 /* ASDefaultPlaybackButton.h in CopyFiles */, - F7CE6CA31D2CDB5800BE4C15 /* ASLayoutValidation.h in CopyFiles */, F7CE6CA41D2CDB5800BE4C15 /* ASLayoutManager.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; @@ -992,8 +987,6 @@ 6977965D1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ASLayoutSpec+Subclasses.h"; path = "AsyncDisplayKit/Layout/ASLayoutSpec+Subclasses.h"; sourceTree = ""; }; 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASLayoutSpec+Subclasses.mm"; path = "AsyncDisplayKit/Layout/ASLayoutSpec+Subclasses.mm"; sourceTree = ""; }; 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASEditableTextNodeTests.m; sourceTree = ""; }; - 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutValidation.h; path = AsyncDisplayKit/Layout/ASLayoutValidation.h; sourceTree = ""; }; - 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutValidation.mm; path = AsyncDisplayKit/Layout/ASLayoutValidation.mm; sourceTree = ""; }; 698548611CA9E025008A345F /* ASEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEnvironment.h; sourceTree = ""; }; 698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutableExtensibility.h; path = AsyncDisplayKit/Layout/ASLayoutableExtensibility.h; sourceTree = ""; }; 69B225661D72535E00B25B22 /* ASDisplayNodeLayoutTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeLayoutTests.mm; sourceTree = ""; }; @@ -1693,8 +1686,6 @@ ACF6ED0E1B17843500DA7C62 /* ASLayoutSpec.mm */, 6977965D1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h */, 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */, - 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */, - 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */, ACF6ED121B17843500DA7C62 /* ASOverlayLayoutSpec.h */, ACF6ED131B17843500DA7C62 /* ASOverlayLayoutSpec.mm */, ACF6ED141B17843500DA7C62 /* ASRatioLayoutSpec.h */, @@ -1845,7 +1836,6 @@ 9CDC18CD1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */, 68B8A4E21CBDB958007E4543 /* ASWeakProxy.h in Headers */, B35062201B010EFD0018CF92 /* ASLayoutController.h in Headers */, - 697C0DE41CF38F28001DE0D4 /* ASLayoutValidation.h in Headers */, B35062211B010EFD0018CF92 /* ASLayoutRangeType.h in Headers */, 34EFC76A1B701CE600AD841F /* ASLayoutSpec.h in Headers */, 695943401D70815300B0EE1F /* ASDisplayNodeLayout.h in Headers */, @@ -2219,7 +2209,6 @@ ACF6ED301B17843500DA7C62 /* ASStackLayoutSpec.mm in Sources */, 257754BE1BEE458E00737CA5 /* ASTextKitComponents.m in Sources */, 257754A91BEE44CD00737CA5 /* ASTextKitContext.mm in Sources */, - 697C0DE51CF38F28001DE0D4 /* ASLayoutValidation.mm in Sources */, ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */, ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */, 83A7D95A1D44542100BF333E /* ASWeakMap.m in Sources */, @@ -2406,7 +2395,6 @@ 34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */, 34EFC7761B701D2A00AD841F /* ASStackPositionedLayout.mm in Sources */, 7AB338661C55B3420055FDE8 /* ASRelativeLayoutSpec.mm in Sources */, - 697C0DE61CF38F28001DE0D4 /* ASLayoutValidation.mm in Sources */, 9C70F2051CDA4F06007D6C76 /* ASTraitCollection.m in Sources */, 83A7D95B1D44547700BF333E /* ASWeakMap.m in Sources */, 34EFC7781B701D3100AD841F /* ASStackUnpositionedLayout.mm in Sources */, diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 841441adb3..1b2b7d37fe 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -31,7 +31,6 @@ #import "ASInternalHelpers.h" #import "ASLayout.h" #import "ASLayoutSpec.h" -#import "ASLayoutValidation.h" #import "ASCellNode+Internal.h" #import "ASWeakProxy.h" @@ -2449,9 +2448,6 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) if (isFinalLayoutable) { layout.position = CGPointZero; layout = [ASLayout layoutWithLayoutable:self size:layout.size sublayouts:@[layout]]; -#if LAYOUT_VALIDATION - ASLayoutableValidateLayout(layout); -#endif } ASDisplayNodeLogEvent(self, @"computedLayout: %@", layout); return [layout filteredNodeLayoutTree]; diff --git a/AsyncDisplayKit/Layout/ASLayoutValidation.h b/AsyncDisplayKit/Layout/ASLayoutValidation.h deleted file mode 100644 index 1b18ba7cd7..0000000000 --- a/AsyncDisplayKit/Layout/ASLayoutValidation.h +++ /dev/null @@ -1,86 +0,0 @@ -// -// ASLayoutValidation.h -// AsyncDisplayKit -// -// 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 - -NS_ASSUME_NONNULL_BEGIN - -@class ASLayout; - -// Enable or disable automatic layout validation -#define LAYOUT_VALIDATION 0 - -ASDISPLAYNODE_EXTERN_C_BEGIN - -extern void ASLayoutableValidateLayout(ASLayout *layout); - -ASDISPLAYNODE_EXTERN_C_END - -#pragma mark - ASLayoutableValidator - -@protocol ASLayoutableValidator -- (void)validateLayout:(ASLayout *)layout; -@end - -typedef void (^ASLayoutableBlockValidatorBlock)(id layout); - -@interface ASLayoutableBlockValidator : NSObject -@property (nonatomic, copy) ASLayoutableBlockValidatorBlock block; -- (instancetype)initWithBlock:(ASLayoutableBlockValidatorBlock)block NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; -@end - -/* - * ASLayoutables that have sizeRange or layoutPosition set needs to be wrapped into a ASAbsoluteLayoutSpec. This - * validator checks if sublayouts has sizeRange or layoutPosition set and is wrapped in a ASAbsoluteLayoutSpec - */ -@interface ASLayoutableStaticValidator : NSObject - -@end - -/* - * ASLayoutables that have spacingBefore, spacingAfter, flexGrow, flexShrink, flexBasis, alignSelf, ascender or descender - * set needs to be wrapped into a ASStackLayout. This validator checks if sublayouts has set one of this properties and - * asserts if it's not wrapped in a ASStackLayout if so. - */ -@interface ASLayoutableStackValidator : NSObject - -@end - -/* - * Not in use at the moment - */ -@interface ASLayoutablePreferredSizeValidator : NSObject - -@end - - -#pragma mark - ASLayoutableValidation - -@interface ASLayoutableValidation : NSObject - -/// Currently registered validators -@property (copy, nonatomic, readonly) NSArray> *validators; - -/// Start from given layout and validates each layout in the layout tree with registered validators -- (void)validateLayout:(ASLayout *)layout; - -/// Register a layout validator -- (void)registerValidator:(id)validator; - -/// Register a layout validator with a block. Method returns the registered ASLayoutableValidator object that can be used to store somewhere and unregister -- (id)registerValidatorWithBlock:(ASLayoutableBlockValidatorBlock)block; - -/// Unregister a validtor -- (void)unregisterValidator:(id)validator; -@end - -NS_ASSUME_NONNULL_END diff --git a/AsyncDisplayKit/Layout/ASLayoutValidation.mm b/AsyncDisplayKit/Layout/ASLayoutValidation.mm deleted file mode 100644 index cf7ba92638..0000000000 --- a/AsyncDisplayKit/Layout/ASLayoutValidation.mm +++ /dev/null @@ -1,215 +0,0 @@ -// -// ASLayoutValidation.mm -// AsyncDisplayKit -// -// 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 "ASLayoutValidation.h" -#import "ASLayout.h" -#import "ASDisplayNode.h" - -#import "ASAbsoluteLayoutSpec.h" -#import "ASStackLayoutSpec.h" - -#import - -#pragma mark - Layout Validation - -void ASLayoutableValidateLayout(ASLayout *layout) { - ASLayoutableValidation *validation = [[ASLayoutableValidation alloc] init]; - [validation registerValidator:[[ASLayoutableStaticValidator alloc] init]]; - [validation registerValidator:[[ASLayoutableStackValidator alloc] init]]; - [validation validateLayout:layout]; -} - -#pragma mark - Helpers - -static NSString *ASLayoutValidationWrappingAssertMessage(SEL selector, id obj, Class cl) { - return [NSString stringWithFormat:@"%@ was set on %@. It is either unecessary or the node needs to be wrapped in a %@", NSStringFromSelector(selector), obj, NSStringFromClass(cl)]; -} - -#pragma mark - ASLayoutableBlockValidator - -@implementation ASLayoutableBlockValidator - -#pragma mark Lifecycle - -- (instancetype)initWithBlock:(ASLayoutableBlockValidatorBlock)block -{ - self = [super init]; - if (self) { - _block = [block copy]; - } - return self; -} - -#pragma mark - -- (void)validateLayout:(ASLayout *)layout -{ - if (self.block) { - self.block(layout); - } -} - -@end - -#pragma mark - ASLayoutableStaticValidator - -@implementation ASLayoutableStaticValidator - -- (void)validateLayout:(ASLayout *)layout -{ - for (ASLayout *sublayout in layout.sublayouts) { - id layoutable = layout.layoutable; - id sublayoutLayoutable = sublayout.layoutable; - - NSString *assertMessage = nil; - Class stackContainerClass = [ASAbsoluteLayoutSpec class]; - - // Check for default layoutPosition - if (!CGPointEqualToPoint(sublayoutLayoutable.style.layoutPosition, CGPointZero)) { - assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(layoutPosition), sublayoutLayoutable, stackContainerClass); - } - - // Sublayout layoutable should be wrapped in a ASAbsoluteLayoutSpec - if (assertMessage == nil || [layoutable isKindOfClass:stackContainerClass]) { - continue; - } - - ASDisplayNodeCAssert(NO, assertMessage); - } -} - -@end - - -#pragma mark - ASLayoutableStackValidator - -@implementation ASLayoutableStackValidator - -#pragma mark - -- (void)validateLayout:(ASLayout *)layout -{ - id layoutable = layout.layoutable; - for (ASLayout *sublayout in layout.sublayouts) { - id sublayoutLayoutable = sublayout.layoutable; - - NSString *assertMessage = nil; - Class stackContainerClass = [ASStackLayoutSpec class]; - - // Check if default values related to ASStackLayoutSpec have changed - if (sublayoutLayoutable.style.spacingBefore != 0) { - assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(spacingBefore), sublayoutLayoutable, stackContainerClass); - } else if (sublayoutLayoutable.style.spacingAfter != 0) { - assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(spacingAfter), sublayoutLayoutable, stackContainerClass); - } else if (sublayoutLayoutable.style.flexGrow == YES) { - assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(flexGrow), sublayoutLayoutable, stackContainerClass); - } else if (sublayoutLayoutable.style.flexShrink == YES) { - assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(flexShrink), sublayoutLayoutable, stackContainerClass); - } else if (!ASDimensionEqualToDimension(sublayoutLayoutable.style.flexBasis, ASDimensionAuto) ) { - assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(flexBasis), sublayoutLayoutable, stackContainerClass); - } else if (sublayoutLayoutable.style.alignSelf != ASStackLayoutAlignSelfAuto) { - assertMessage = ASLayoutValidationWrappingAssertMessage(@selector(alignSelf), sublayoutLayoutable, stackContainerClass); - } - - // Sublayout layoutable should be wrapped in a ASStackLayoutSpec - if (assertMessage == nil || [layoutable isKindOfClass:stackContainerClass]) { - continue; - } - - ASDisplayNodeCAssert(NO, assertMessage); - } -} - -@end - -#pragma mark ASLayoutablePreferredSizeValidator - -@implementation ASLayoutablePreferredSizeValidator - -#pragma mark - -- (void)validateLayout:(ASLayout *)layout -{ - // TODO: Implement validation that certain node classes need to have a preferredSize set e.g. ASVideoNode -} - -@end - - -#pragma mark - ASLayoutableValidation - -@interface ASLayoutableValidation () -@end - -@implementation ASLayoutableValidation { - NSMutableArray *_validators; -} - -#pragma mark Lifecycle - -- (instancetype)init -{ - self = [super init]; - if (self) { - _validators = [NSMutableArray array]; - } - return self; -} - -#pragma mark Validator Management - -- (NSArray> *)validators -{ - return [_validators copy]; -} - -- (void)registerValidator:(id)validator -{ - [_validators addObject:validator]; -} - -- (id)registerValidatorWithBlock:(ASLayoutableBlockValidatorBlock)block -{ - ASLayoutableBlockValidator *blockValidator = [[ASLayoutableBlockValidator alloc] initWithBlock:block]; - [_validators addObject:blockValidator]; - return blockValidator; -} - -- (void)unregisterValidator:(id)validator -{ - [_validators removeObject:validator]; -} - -#pragma mark Validation Process - -- (void)validateLayout:(ASLayout *)layout -{ - // Queue used to keep track of sublayouts while traversing this layout in a BFS fashion. - std::queue queue; - queue.push(layout); - - while (!queue.empty()) { - layout = queue.front(); - queue.pop(); - - // Validate layout with all registered validators - for (id validator in self.validators) { - [validator validateLayout:layout]; - } - - // Push sublayouts to queue for validation - for (id sublayout in [layout sublayouts]) { - queue.push(sublayout); - } - - } -} - -@end