Implement thread-safe bounds and use it in ASTextNode

This commit is contained in:
Huy Nguyen 2016-03-02 22:42:53 -08:00
parent edd567a91d
commit 9162d7b2df
5 changed files with 32 additions and 6 deletions

View File

@ -61,6 +61,7 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
@synthesize name = _name;
@synthesize preferredFrameSize = _preferredFrameSize;
@synthesize isFinalLayoutable = _isFinalLayoutable;
@synthesize threadSafeBounds = _threadSafeBounds;
static BOOL usesImplicitHierarchyManagement = FALSE;
@ -428,11 +429,13 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
ASDisplayNodeAssert(![view isKindOfClass:[_ASDisplayView class]], @"View block should return a synchronously displayed view");
_viewBlock = nil;
_viewClass = [view class];
_usesDisplayView = [_viewClass isKindOfClass:[_ASDisplayView class]];
} else {
if (!_viewClass) {
_viewClass = [self.class viewClass];
}
view = [[_viewClass alloc] init];
_usesDisplayView = [_viewClass isKindOfClass:[_ASDisplayView class]];
}
return view;
@ -1918,6 +1921,18 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
return _preferredFrameSize;
}
- (CGRect)threadSafeBounds
{
ASDN::MutexLocker l(_propertyLock);
return _threadSafeBounds;
}
- (void)setThreadSafeBounds:(CGRect)newBounds
{
ASDN::MutexLocker l(_propertyLock);
_threadSafeBounds = newBounds;
}
- (UIImage *)placeholderImage
{
return nil;

View File

@ -218,10 +218,9 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
#pragma mark - Renderer Management
//only safe to call on the main thread because self.bounds is only safe to call on the main thread one our node is loaded
- (ASTextKitRenderer *)_renderer
{
return [self _rendererWithBounds:self.bounds];
return [self _rendererWithBounds:self.threadSafeBounds];
}
- (ASTextKitRenderer *)_rendererWithBounds:(CGRect)bounds
@ -268,7 +267,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
- (void)_invalidateRendererIfNeeded
{
[self _invalidateRendererIfNeededForBoundsSize:self.bounds.size];
[self _invalidateRendererIfNeededForBoundsSize:self.threadSafeBounds.size];
}
- (void)_invalidateRendererIfNeededForBoundsSize:(CGSize)boundsSize
@ -438,7 +437,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
{
return [[ASTextNodeDrawParameters alloc] initWithBounds:self.bounds backgroundColor:self.backgroundColor];
return [[ASTextNodeDrawParameters alloc] initWithBounds:self.threadSafeBounds backgroundColor:self.backgroundColor];
}
#pragma mark - Attributes
@ -990,7 +989,6 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
}
}
//only safe to call on main thread, because [self _renderer] is only safe to call on the main thread
- (UIEdgeInsets)shadowPadding
{
return [self shadowPaddingWithRenderer:[self _renderer]];

View File

@ -201,6 +201,12 @@
self.layer.contentsGravity = (contentMode != UIViewContentModeRedraw) ? ASDisplayNodeCAContentsGravityFromUIContentMode(contentMode) : kCAGravityResize;
}
- (void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
_node.threadSafeBounds = bounds;
}
#pragma mark - Event Handling + UIResponder Overrides
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

View File

@ -211,6 +211,10 @@ if (shouldApply) { _layer.layerProperty = (layerValueExpr); } else { ASDisplayNo
{
_bridge_prologue_write;
_setToViewOrLayer(bounds, newBounds, bounds, newBounds);
// If _ASDisplayView is available, it already sets the new bounds to threadSafeBounds.
if (! (__loaded(self) && _usesDisplayView)) {
self.threadSafeBounds = newBounds;
}
}
- (CGRect)frame

View File

@ -116,7 +116,8 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
ASDisplayNodeDidLoadBlock _nodeLoadedBlock;
Class _viewClass;
Class _layerClass;
BOOL _usesDisplayView;
UIImage *_placeholderImage;
CALayer *_placeholderLayer;
@ -145,6 +146,8 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
// Bitmask to check which methods an object overrides.
@property (nonatomic, assign, readonly) ASDisplayNodeMethodOverrides methodOverrides;
@property (nonatomic, assign) CGRect threadSafeBounds;
// Swizzle to extend the builtin functionality with custom logic
- (BOOL)__shouldLoadViewOrLayer;