Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small changes required by the coming layout debugger #337

Merged
merged 3 commits into from
Jun 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@
- [Fix] Fix a major regression in our image node contents caching. [Adlai Holler](https://github.com/Adlai-Holler) [#287](https://github.com/TextureGroup/Texture/pull/287)
- [Fix] Fixed a bug where ASVideoNodeDelegate error reporting callback would crash an app because of not responding to selector. [Sergey Petrachkov](https://github.com/Petrachkov) [#291](https://github.com/TextureGroup/Texture/issues/291)
- [IGListKit] Add IGListKit headers to public section of Xcode project [Michael Schneider](https://github.com/maicki)[#286](https://github.com/TextureGroup/Texture/pull/286)
- [Layout] Ensure -layout and -layoutDidFinish are called only if a node is loaded. [Huy Nguyen](https://github.com/nguyenhuy) [#285](https://github.com/TextureGroup/Texture/pull/285)
- [Layout] Ensure -layout and -layoutDidFinish are called only if a node is loaded. [Huy Nguyen](https://github.com/nguyenhuy) [#285](https://github.com/TextureGroup/Texture/pull/285)
- [Layout Debugger] Small changes needed for the coming layout debugger [Huy Nguyen](https://github.com/nguyenhuy) [#337](https://github.com/TextureGroup/Texture/pull/337)
6 changes: 6 additions & 0 deletions Source/ASDisplayNode+Layout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,12 @@ - (void)_locked_setCalculatedDisplayNodeLayout:(std::shared_ptr<ASDisplayNodeLay
ASDisplayNodeAssertTrue(displayNodeLayout->layout.size.width >= 0.0);
ASDisplayNodeAssertTrue(displayNodeLayout->layout.size.height >= 0.0);

// Flatten the layout if it wasn't done before (@see -calculateLayoutThatFits:).
if ([ASDisplayNode shouldStoreUnflattenedLayouts]) {
_unflattenedLayout = displayNodeLayout->layout;
displayNodeLayout->layout = [_unflattenedLayout filteredNodeLayoutTree];
}

_calculatedDisplayNodeLayout = displayNodeLayout;
}

Expand Down
24 changes: 24 additions & 0 deletions Source/ASDisplayNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,30 @@ extern NSInteger const ASDefaultDrawingPriority;
*/
@interface ASDisplayNode (Debugging) <ASDebugNameProvider>

/**
* Set to YES to tell all ASDisplayNode instances to store their unflattened layouts.
*
* The layout can be accessed via `-unflattenedCalculatedLayout`.
*
* Flattened layouts use less memory and are faster to lookup. On the other hand, unflattened layouts are useful for debugging
* because they preserve original information.
*/
+ (void)setShouldStoreUnflattenedLayouts:(BOOL)shouldStore;

/**
* Whether or not ASDisplayNode instances should store their unflattened layouts.
*
* The layout can be accessed via `-unflattenedCalculatedLayout`.
*
* Flattened layouts use less memory and are faster to lookup. On the other hand, unflattened layouts are useful for debugging
* because they preserve original information.
*
* Defaults to NO.
*/
+ (BOOL)shouldStoreUnflattenedLayouts;

@property (nonatomic, strong, readonly, nullable) ASLayout *unflattenedCalculatedLayout;

/**
* @abstract Return a description of the node hierarchy.
*
Expand Down
28 changes: 26 additions & 2 deletions Source/ASDisplayNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ @implementation ASDisplayNode
@synthesize threadSafeBounds = _threadSafeBounds;

static BOOL suppressesInvalidCollectionUpdateExceptions = NO;
static std::atomic_bool storesUnflattenedLayouts = ATOMIC_VAR_INIT(NO);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh man, this is way nicer than objc!


+ (BOOL)suppressesInvalidCollectionUpdateExceptions
{
Expand Down Expand Up @@ -887,6 +888,8 @@ - (void)invalidateCalculatedLayout
if (_pendingDisplayNodeLayout != nullptr) {
_pendingDisplayNodeLayout->invalidate();
}

_unflattenedLayout = nil;

#if YOGA_TREE_CONTIGUOUS
[self invalidateCalculatedYogaLayout];
Expand Down Expand Up @@ -1013,7 +1016,6 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize

// Manually propagate the trait collection here so that any layoutSpec children of layoutSpec will get a traitCollection
{

ASDN::SumScopeTimer t(_layoutSpecTotalTime, measureLayoutSpec);
ASTraitCollectionPropagateDown(layoutElement, self.primitiveTraitCollection);
}
Expand All @@ -1038,7 +1040,13 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
}
ASDisplayNodeLogEvent(self, @"computedLayout: %@", layout);

return [layout filteredNodeLayoutTree];
// Return the (original) unflattened layout if it needs to be stored. The layout will be flattened later on (@see _locked_setCalculatedDisplayNodeLayout:).
// Otherwise, flatten it right away.
if (! [ASDisplayNode shouldStoreUnflattenedLayouts]) {
layout = [layout filteredNodeLayoutTree];
}

return layout;
}

- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
Expand Down Expand Up @@ -3286,6 +3294,22 @@ - (UIView *)preferredFocusedView

@implementation ASDisplayNode (Debugging)

+ (void)setShouldStoreUnflattenedLayouts:(BOOL)shouldStore
{
storesUnflattenedLayouts.store(shouldStore);
}

+ (BOOL)shouldStoreUnflattenedLayouts
{
return storesUnflattenedLayouts.load();
}

- (ASLayout *)unflattenedCalculatedLayout
{
ASDN::MutexLocker l(__instanceLock__);
return _unflattenedLayout;
}

- (NSString *)displayNodeRecursiveDescription
{
return [self _recursiveDescriptionHelperWithIndent:@""];
Expand Down
2 changes: 1 addition & 1 deletion Source/ASDisplayNodeExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ extern ASDisplayNode * _Nullable ASLayerToDisplayNode(CALayer * _Nullable layer)
extern ASDisplayNode * _Nullable ASViewToDisplayNode(UIView * _Nullable view) AS_WARN_UNUSED_RESULT;

/**
Given a node, returns the root of the node heirarchy (where supernode == nil)
Given a node, returns the root of the node hierarchy (where supernode == nil)
*/
extern ASDisplayNode *ASDisplayNodeUltimateParentOfNode(ASDisplayNode *node) AS_WARN_UNUSED_RESULT;

Expand Down
12 changes: 12 additions & 0 deletions Source/Layout/ASLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ ASDISPLAYNODE_EXTERN_C_END

@interface ASLayout (Debugging)

/**
* Set to YES to tell all ASLayout instances to retain their sublayout elements. Defaults to NO.
* Can be overridden at instance level.
*/
+ (void)setShouldRetainSublayoutLayoutElements:(BOOL)shouldRetain;

/**
* Whether or not ASLayout instances should retain their sublayout elements.
* Can be overridden at instance level.
*/
+ (BOOL)shouldRetainSublayoutLayoutElements;

/**
* Recrusively output the description of the layout tree.
*/
Expand Down
14 changes: 13 additions & 1 deletion Source/Layout/ASLayout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ @implementation ASLayout

@dynamic frame, type;

static std::atomic_bool static_retainsSublayoutLayoutElements = ATOMIC_VAR_INIT(NO);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added static prefix because ASLayout also has an instance variable called retainSublayoutLayoutElements here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


+ (void)setShouldRetainSublayoutLayoutElements:(BOOL)shouldRetain
{
static_retainsSublayoutLayoutElements.store(shouldRetain);
}

+ (BOOL)shouldRetainSublayoutLayoutElements
{
return static_retainsSublayoutLayoutElements.load();
}

- (instancetype)initWithLayoutElement:(id<ASLayoutElement>)layoutElement
size:(CGSize)size
position:(CGPoint)position
Expand Down Expand Up @@ -118,7 +130,7 @@ - (instancetype)initWithLayoutElement:(id<ASLayoutElement>)layoutElement
}

_flattened = NO;
_retainSublayoutLayoutElements = NO;
self.retainSublayoutLayoutElements = [ASLayout shouldRetainSublayoutLayoutElements];
}

return self;
Expand Down
3 changes: 3 additions & 0 deletions Source/Private/ASDisplayNodeInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo

NSString *_debugName;

#pragma mark - ASDisplayNode (Debugging)
ASLayout *_unflattenedLayout;

#if TIME_DISPLAYNODE_OPS
@public
NSTimeInterval _debugTimeToCreateView;
Expand Down