Cleanup ASDisplayLayer (#315)

This commit is contained in:
Adlai Holler 2017-05-29 15:38:27 -07:00 committed by GitHub
parent be956e91c6
commit 7961aa919a
2 changed files with 10 additions and 64 deletions

View File

@ -53,11 +53,11 @@
+ (dispatch_queue_t)displayQueue; + (dispatch_queue_t)displayQueue;
/** /**
@summary Delegate for asynchronous display of the layer. @summary Delegate for asynchronous display of the layer. This should be the node (default) unless you REALLY know what you're doing.
@desc The asyncDelegate will have the opportunity to override the methods related to async display. @desc The asyncDelegate will have the opportunity to override the methods related to async display.
*/ */
@property (nonatomic, weak) id<_ASDisplayLayerDelegate> asyncDelegate; @property (atomic, weak) id<_ASDisplayLayerDelegate> asyncDelegate;
/** /**
@summary Suspends both asynchronous and synchronous display of the receiver if YES. @summary Suspends both asynchronous and synchronous display of the receiver if YES.

View File

@ -28,41 +28,16 @@
@implementation _ASDisplayLayer @implementation _ASDisplayLayer
{ {
ASDN::Mutex _asyncDelegateLock;
// We can take this lock when we're setting displaySuspended and in setNeedsDisplay, so to not deadlock, this is recursive
ASDN::RecursiveMutex _displaySuspendedLock;
BOOL _displaySuspended;
BOOL _attemptedDisplayWhileZeroSized; BOOL _attemptedDisplayWhileZeroSized;
struct { struct {
BOOL delegateDidChangeBounds:1; BOOL delegateDidChangeBounds:1;
} _delegateFlags; } _delegateFlags;
id<_ASDisplayLayerDelegate> __weak _asyncDelegate;
} }
@dynamic displaysAsynchronously; @dynamic displaysAsynchronously;
#pragma mark - #pragma mark - Properties
#pragma mark Lifecycle
- (instancetype)init
{
if ((self = [super init])) {
self.opaque = YES;
}
return self;
}
#pragma mark -
#pragma mark Properties
- (id<_ASDisplayLayerDelegate>)asyncDelegate
{
ASDN::MutexLocker l(_asyncDelegateLock);
return _asyncDelegate;
}
- (void)setDelegate:(id)delegate - (void)setDelegate:(id)delegate
{ {
@ -70,22 +45,9 @@
_delegateFlags.delegateDidChangeBounds = [delegate respondsToSelector:@selector(layer:didChangeBoundsWithOldValue:newValue:)]; _delegateFlags.delegateDidChangeBounds = [delegate respondsToSelector:@selector(layer:didChangeBoundsWithOldValue:newValue:)];
} }
- (void)setAsyncDelegate:(id<_ASDisplayLayerDelegate>)asyncDelegate
{
ASDisplayNodeAssert(!asyncDelegate || [asyncDelegate isKindOfClass:[ASDisplayNode class]], @"_ASDisplayLayer is inherently coupled to ASDisplayNode and cannot be used with another asyncDelegate. Please rethink what you are trying to do.");
ASDN::MutexLocker l(_asyncDelegateLock);
_asyncDelegate = asyncDelegate;
}
- (BOOL)isDisplaySuspended
{
ASDN::MutexLocker l(_displaySuspendedLock);
return _displaySuspended;
}
- (void)setDisplaySuspended:(BOOL)displaySuspended - (void)setDisplaySuspended:(BOOL)displaySuspended
{ {
ASDN::MutexLocker l(_displaySuspendedLock); ASDisplayNodeAssertMainThread();
if (_displaySuspended != displaySuspended) { if (_displaySuspended != displaySuspended) {
_displaySuspended = displaySuspended; _displaySuspended = displaySuspended;
if (!displaySuspended) { if (!displaySuspended) {
@ -147,8 +109,6 @@
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
_displaySuspendedLock.lock();
// FIXME: Reconsider whether we should cancel a display in progress. // FIXME: Reconsider whether we should cancel a display in progress.
// We should definitely cancel a display that is scheduled, but unstarted display. // We should definitely cancel a display that is scheduled, but unstarted display.
[self cancelAsyncDisplay]; [self cancelAsyncDisplay];
@ -157,7 +117,6 @@
if (!_displaySuspended) { if (!_displaySuspended) {
[super setNeedsDisplay]; [super setNeedsDisplay];
} }
_displaySuspendedLock.unlock();
} }
#pragma mark - #pragma mark -
@ -179,13 +138,14 @@
{ {
if ([key isEqualToString:@"displaysAsynchronously"]) { if ([key isEqualToString:@"displaysAsynchronously"]) {
return @YES; return @YES;
} else if ([key isEqualToString:@"opaque"]) {
return @YES;
} else { } else {
return [super defaultValueForKey:key]; return [super defaultValueForKey:key];
} }
} }
#pragma mark - #pragma mark - Display
#pragma mark Display
- (void)displayImmediately - (void)displayImmediately
{ {
@ -209,7 +169,7 @@
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
[self _hackResetNeedsDisplay]; [self _hackResetNeedsDisplay];
if (self.isDisplaySuspended) { if (self.displaySuspended) {
return; return;
} }
@ -222,28 +182,14 @@
_attemptedDisplayWhileZeroSized = YES; _attemptedDisplayWhileZeroSized = YES;
} }
id<_ASDisplayLayerDelegate> NS_VALID_UNTIL_END_OF_SCOPE strongAsyncDelegate; [self.asyncDelegate displayAsyncLayer:self asynchronously:asynchronously];
{
_asyncDelegateLock.lock();
strongAsyncDelegate = _asyncDelegate;
_asyncDelegateLock.unlock();
}
[strongAsyncDelegate displayAsyncLayer:self asynchronously:asynchronously];
} }
- (void)cancelAsyncDisplay - (void)cancelAsyncDisplay
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
id<_ASDisplayLayerDelegate> NS_VALID_UNTIL_END_OF_SCOPE strongAsyncDelegate; [self.asyncDelegate cancelDisplayAsyncLayer:self];
{
_asyncDelegateLock.lock();
strongAsyncDelegate = _asyncDelegate;
_asyncDelegateLock.unlock();
}
[strongAsyncDelegate cancelDisplayAsyncLayer:self];
} }
// e.g. <MYTextNodeLayer: 0xFFFFFF; node = <MYTextNode: 0xFFFFFFE; name = "Username node for user 179">> // e.g. <MYTextNodeLayer: 0xFFFFFF; node = <MYTextNode: 0xFFFFFFE; name = "Username node for user 179">>