mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
[ASTextNode, ASImageNode, ASVideoNode] Use ASDisplayNode base class lock for subclass property synchronization (#1877)
* [ASTextNode, ASVideoNode] Use ASDisplayNode base class lock for subclass property synchronization * fix headers to match master * address @appleguy, @maicki comments * import header * Swap lock in ASNetworkImageNode as well * remove invalid comment * more cleanup of locks
This commit is contained in:
@@ -44,7 +44,6 @@ struct ASImageNodeDrawParameters {
|
||||
UIImage *_image;
|
||||
|
||||
void (^_displayCompletionBlock)(BOOL canceled);
|
||||
ASDN::RecursiveMutex _imageLock;
|
||||
|
||||
// Drawing
|
||||
ASImageNodeDrawParameters _drawParameter;
|
||||
@@ -119,7 +118,7 @@ struct ASImageNodeDrawParameters {
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
// if a preferredFrameSize is set, call the superclass to return that instead of using the image size.
|
||||
if (CGSizeEqualToSize(self.preferredFrameSize, CGSizeZero) == NO)
|
||||
return [super calculateSizeThatFits:constrainedSize];
|
||||
@@ -133,11 +132,9 @@ struct ASImageNodeDrawParameters {
|
||||
|
||||
- (void)setImage:(UIImage *)image
|
||||
{
|
||||
_imageLock.lock();
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (!ASObjectIsEqual(_image, image)) {
|
||||
_image = image;
|
||||
|
||||
_imageLock.unlock();
|
||||
|
||||
[self invalidateCalculatedLayout];
|
||||
if (image) {
|
||||
@@ -153,14 +150,12 @@ struct ASImageNodeDrawParameters {
|
||||
} else {
|
||||
self.contents = nil;
|
||||
}
|
||||
} else {
|
||||
_imageLock.unlock(); // We avoid using MutexUnlocker as it needlessly re-locks at the end of the scope.
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImage *)image
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _image;
|
||||
}
|
||||
|
||||
@@ -176,7 +171,7 @@ struct ASImageNodeDrawParameters {
|
||||
|
||||
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
_drawParameter = {
|
||||
.bounds = self.bounds,
|
||||
@@ -221,7 +216,7 @@ struct ASImageNodeDrawParameters {
|
||||
asimagenode_modification_block_t imageModificationBlock;
|
||||
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
ASImageNodeDrawParameters drawParameter = _drawParameter;
|
||||
|
||||
drawParameterBounds = drawParameter.bounds;
|
||||
@@ -356,19 +351,19 @@ struct ASImageNodeDrawParameters {
|
||||
{
|
||||
[super displayDidFinish];
|
||||
|
||||
_imageLock.lock();
|
||||
_propertyLock.lock();
|
||||
void (^displayCompletionBlock)(BOOL canceled) = _displayCompletionBlock;
|
||||
UIImage *image = _image;
|
||||
_imageLock.unlock();
|
||||
_propertyLock.unlock();
|
||||
|
||||
// If we've got a block to perform after displaying, do it.
|
||||
if (image && displayCompletionBlock) {
|
||||
|
||||
displayCompletionBlock(NO);
|
||||
|
||||
_imageLock.lock();
|
||||
_propertyLock.lock();
|
||||
_displayCompletionBlock = nil;
|
||||
_imageLock.unlock();
|
||||
_propertyLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,7 +376,7 @@ struct ASImageNodeDrawParameters {
|
||||
}
|
||||
|
||||
// Stash the block and call-site queue. We'll invoke it in -displayDidFinish.
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_displayCompletionBlock != displayCompletionBlock) {
|
||||
_displayCompletionBlock = [displayCompletionBlock copy];
|
||||
}
|
||||
@@ -393,7 +388,7 @@ struct ASImageNodeDrawParameters {
|
||||
|
||||
- (BOOL)isCropEnabled
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _cropEnabled;
|
||||
}
|
||||
|
||||
@@ -404,7 +399,7 @@ struct ASImageNodeDrawParameters {
|
||||
|
||||
- (void)setCropEnabled:(BOOL)cropEnabled recropImmediately:(BOOL)recropImmediately inBounds:(CGRect)cropBounds
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_cropEnabled == cropEnabled)
|
||||
return;
|
||||
|
||||
@@ -425,13 +420,13 @@ struct ASImageNodeDrawParameters {
|
||||
|
||||
- (CGRect)cropRect
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _cropRect;
|
||||
}
|
||||
|
||||
- (void)setCropRect:(CGRect)cropRect
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (CGRectEqualToRect(_cropRect, cropRect))
|
||||
return;
|
||||
|
||||
@@ -452,25 +447,25 @@ struct ASImageNodeDrawParameters {
|
||||
|
||||
- (BOOL)forceUpscaling
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _forceUpscaling;
|
||||
}
|
||||
|
||||
- (void)setForceUpscaling:(BOOL)forceUpscaling
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_forceUpscaling = forceUpscaling;
|
||||
}
|
||||
|
||||
- (asimagenode_modification_block_t)imageModificationBlock
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _imageModificationBlock;
|
||||
}
|
||||
|
||||
- (void)setImageModificationBlock:(asimagenode_modification_block_t)imageModificationBlock
|
||||
{
|
||||
ASDN::MutexLocker l(_imageLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_imageModificationBlock = imageModificationBlock;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#import "ASNetworkImageNode.h"
|
||||
|
||||
#import "ASBasicImageDownloader.h"
|
||||
#import "ASDisplayNodeInternal.h"
|
||||
#import "ASDisplayNode+Subclasses.h"
|
||||
#import "ASDisplayNode+FrameworkPrivate.h"
|
||||
#import "ASEqualityHelpers.h"
|
||||
@@ -26,11 +27,10 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
|
||||
@interface ASNetworkImageNode ()
|
||||
{
|
||||
ASDN::RecursiveMutex _lock;
|
||||
__weak id<ASImageCacheProtocol, ASImageCacheProtocolDeprecated> _cache;
|
||||
__weak id<ASImageDownloaderProtocol, ASImageDownloaderProtocolDeprecated> _downloader;
|
||||
|
||||
// Only access any of these with _lock.
|
||||
// Only access any of these with _propertyLock.
|
||||
__weak id<ASNetworkImageNodeDelegate> _delegate;
|
||||
|
||||
NSURL *_URL;
|
||||
@@ -121,7 +121,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
|
||||
- (void)setURL:(NSURL *)URL resetToDefault:(BOOL)reset
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (ASObjectIsEqual(URL, _URL)) {
|
||||
return;
|
||||
@@ -150,16 +150,15 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
|
||||
- (NSURL *)URL
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _URL;
|
||||
}
|
||||
|
||||
- (void)setDefaultImage:(UIImage *)defaultImage
|
||||
{
|
||||
_lock.lock();
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (ASObjectIsEqual(defaultImage, _defaultImage)) {
|
||||
_lock.unlock();
|
||||
return;
|
||||
}
|
||||
_defaultImage = defaultImage;
|
||||
@@ -172,49 +171,43 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.currentImageQuality = hasURL ? 0.0 : 1.0;
|
||||
});
|
||||
_lock.unlock();
|
||||
// Locking: it is important to release _lock before entering setImage:, as it needs to release the lock before -invalidateCalculatedLayout.
|
||||
// If we continue to hold the lock here, it will still be locked until the next unlock() call, causing a possible deadlock with
|
||||
// -[ASNetworkImageNode displayWillStart] (which is called on a different thread / main, at an unpredictable time due to ASMainRunloopQueue).
|
||||
self.image = defaultImage;
|
||||
} else {
|
||||
_lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImage *)defaultImage
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _defaultImage;
|
||||
}
|
||||
|
||||
- (void)setCurrentImageQuality:(CGFloat)currentImageQuality
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_currentImageQuality = currentImageQuality;
|
||||
}
|
||||
|
||||
- (CGFloat)currentImageQuality
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _currentImageQuality;
|
||||
}
|
||||
|
||||
- (void)setRenderedImageQuality:(CGFloat)renderedImageQuality
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_renderedImageQuality = renderedImageQuality;
|
||||
}
|
||||
|
||||
- (CGFloat)renderedImageQuality
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _renderedImageQuality;
|
||||
}
|
||||
|
||||
- (void)setDelegate:(id<ASNetworkImageNodeDelegate>)delegate
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_delegate = delegate;
|
||||
|
||||
_delegateFlags.delegateDidStartFetchingData = [delegate respondsToSelector:@selector(imageNodeDidStartFetchingData:)];
|
||||
@@ -225,13 +218,13 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
|
||||
- (id<ASNetworkImageNodeDelegate>)delegate
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
- (void)setShouldRenderProgressImages:(BOOL)shouldRenderProgressImages
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (shouldRenderProgressImages == _shouldRenderProgressImages) {
|
||||
return;
|
||||
}
|
||||
@@ -239,19 +232,19 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
_shouldRenderProgressImages = shouldRenderProgressImages;
|
||||
|
||||
|
||||
ASDN::MutexUnlocker u(_lock);
|
||||
ASDN::MutexUnlocker u(_propertyLock);
|
||||
[self _updateProgressImageBlockOnDownloaderIfNeeded];
|
||||
}
|
||||
|
||||
- (BOOL)shouldRenderProgressImages
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _shouldRenderProgressImages;
|
||||
}
|
||||
|
||||
- (BOOL)placeholderShouldPersist
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return (self.image == nil && _URL != nil);
|
||||
}
|
||||
|
||||
@@ -262,7 +255,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
[super displayWillStart];
|
||||
|
||||
if (_cacheFlags.cacheSupportsSynchronousFetch) {
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_imageLoaded == NO && _URL && _downloadIdentifier == nil) {
|
||||
UIImage *result = [[_cache synchronouslyFetchedCachedImageWithURL:_URL] asdk_image];
|
||||
if (result) {
|
||||
@@ -279,7 +272,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
[self fetchData];
|
||||
|
||||
if (self.image == nil && _downloaderFlags.downloaderImplementsSetPriority) {
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_downloadIdentifier != nil) {
|
||||
[_downloader setPriority:ASImageDownloaderPriorityImminent withDownloadIdentifier:_downloadIdentifier];
|
||||
}
|
||||
@@ -293,7 +286,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
[super visibleStateDidChange:isVisible];
|
||||
|
||||
if (_downloaderFlags.downloaderImplementsSetPriority) {
|
||||
_lock.lock();
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_downloadIdentifier != nil) {
|
||||
if (isVisible) {
|
||||
[_downloader setPriority:ASImageDownloaderPriorityVisible withDownloadIdentifier:_downloadIdentifier];
|
||||
@@ -301,10 +294,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
[_downloader setPriority:ASImageDownloaderPriorityPreload withDownloadIdentifier:_downloadIdentifier];
|
||||
}
|
||||
}
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
// This method has to be called without _lock held
|
||||
[self _updateProgressImageBlockOnDownloaderIfNeeded];
|
||||
}
|
||||
|
||||
@@ -313,7 +304,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
[super clearFetchedData];
|
||||
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
[self _cancelImageDownload];
|
||||
[self _clearImage];
|
||||
@@ -328,24 +319,19 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
[super fetchData];
|
||||
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
[self _lazilyLoadImageIfNecessary];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Private methods -- only call with lock.
|
||||
|
||||
/**
|
||||
@note: This should be called without _lock held. We will lock
|
||||
super to read our interface state and it's best to avoid acquiring both locks.
|
||||
*/
|
||||
- (void)_updateProgressImageBlockOnDownloaderIfNeeded
|
||||
{
|
||||
BOOL shouldRenderProgressImages = self.shouldRenderProgressImages;
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
// Read our interface state before locking so that we don't lock super while holding our lock.
|
||||
BOOL shouldRenderProgressImages = _shouldRenderProgressImages;
|
||||
ASInterfaceState interfaceState = self.interfaceState;
|
||||
ASDN::MutexLocker l(_lock);
|
||||
|
||||
if (!_downloaderFlags.downloaderImplementsSetProgress || _downloadIdentifier == nil) {
|
||||
return;
|
||||
@@ -360,14 +346,15 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
return;
|
||||
}
|
||||
|
||||
ASDN::MutexLocker l(strongSelf->_lock);
|
||||
ASDN::MutexLocker l(strongSelf->_propertyLock);
|
||||
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
||||
if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
|
||||
return;
|
||||
}
|
||||
strongSelf.image = progressImage;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
strongSelf->_currentImageQuality = progress;
|
||||
// See comment in -displayDidFinish for why this must be dispatched to main
|
||||
strongSelf.currentImageQuality = progress;
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -391,6 +378,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
self.animatedImage = nil;
|
||||
self.image = _defaultImage;
|
||||
_imageLoaded = NO;
|
||||
// See comment in -displayDidFinish for why this must be dispatched to main
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.currentImageQuality = 0.0;
|
||||
});
|
||||
@@ -413,7 +401,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
- (void)_downloadImageWithCompletion:(void (^)(id <ASImageContainerProtocol> imageContainer, NSError*, id downloadIdentifier))finished
|
||||
{
|
||||
ASPerformBlockOnBackgroundThread(^{
|
||||
_lock.lock();
|
||||
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_downloaderFlags.downloaderSupportsNewProtocol) {
|
||||
_downloadIdentifier = [_downloader downloadImageWithURL:_URL
|
||||
callbackQueue:dispatch_get_main_queue()
|
||||
@@ -436,9 +425,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
}];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
_lock.unlock();
|
||||
|
||||
// This method has to be called without _lock held
|
||||
|
||||
[self _updateProgressImageBlockOnDownloaderIfNeeded];
|
||||
|
||||
});
|
||||
@@ -449,7 +436,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
// FIXME: We should revisit locking in this method (e.g. to access the instance variables at the top, and holding lock while calling delegate)
|
||||
if (!_imageLoaded && _URL != nil && _downloadIdentifier == nil) {
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_delegateFlags.delegateDidStartFetchingData) {
|
||||
[_delegate imageNodeDidStartFetchingData:self];
|
||||
}
|
||||
@@ -457,7 +444,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
|
||||
if (_URL.isFileURL) {
|
||||
{
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.shouldCacheImage) {
|
||||
@@ -515,7 +502,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
return;
|
||||
}
|
||||
|
||||
ASDN::MutexLocker l(strongSelf->_lock);
|
||||
ASDN::MutexLocker l(strongSelf->_propertyLock);
|
||||
|
||||
//Getting a result back for a different download identifier, download must not have been successfully canceled
|
||||
if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) {
|
||||
@@ -592,7 +579,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0};
|
||||
{
|
||||
[super displayDidFinish];
|
||||
|
||||
ASDN::MutexLocker l(_lock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_delegateFlags.delegateDidFinishDecoding && self.layer.contents != nil) {
|
||||
/* We store the image quality in _currentImageQuality whenever _image is set. On the following displayDidFinish, we'll know that
|
||||
_currentImageQuality is the quality of the image that has just finished rendering. In order for this to be accurate, we
|
||||
|
||||
@@ -57,8 +57,6 @@ struct ASTextNodeDrawParameter {
|
||||
NSRange _highlightRange;
|
||||
ASHighlightOverlayLayer *_activeHighlightLayer;
|
||||
|
||||
std::recursive_mutex _textLock;
|
||||
|
||||
CGSize _constrainedSize;
|
||||
|
||||
ASTextKitRenderer *_renderer;
|
||||
@@ -153,7 +151,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
NSString *plainString = [[_attributedText string] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
|
||||
NSString *truncationString = [_composedTruncationText string];
|
||||
@@ -222,7 +220,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (ASTextKitRenderer *)_rendererWithBounds:(CGRect)bounds
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_renderer == nil) {
|
||||
CGSize constrainedSize = _constrainedSize.width != -INFINITY ? _constrainedSize : bounds.size;
|
||||
@@ -234,7 +232,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (ASTextKitAttributes)_rendererAttributes
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return {
|
||||
.attributedString = _attributedText,
|
||||
@@ -260,7 +258,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
// so our previous layout information is invalid, and TextKit may draw at the
|
||||
// incorrect origin.
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_constrainedSize = CGSizeMake(-INFINITY, -INFINITY);
|
||||
}
|
||||
[self _invalidateRenderer];
|
||||
@@ -269,7 +267,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (void)_invalidateRenderer
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_renderer) {
|
||||
// Destruction of the layout managers/containers/text storage is quite
|
||||
@@ -288,7 +286,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_renderer == nil) {
|
||||
return YES;
|
||||
@@ -327,7 +325,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
ASLayout *layout = self.calculatedLayout;
|
||||
|
||||
if (layout != nil) {
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_constrainedSize = layout.size;
|
||||
_renderer.constrainedSize = layout.size;
|
||||
}
|
||||
@@ -338,7 +336,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width);
|
||||
ASDisplayNodeAssert(constrainedSize.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.height);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
_constrainedSize = constrainedSize;
|
||||
|
||||
@@ -373,7 +371,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
// Don't hold textLock for too long.
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (ASObjectIsEqual(attributedText, _attributedText)) {
|
||||
return;
|
||||
}
|
||||
@@ -411,7 +409,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (void)setExclusionPaths:(NSArray *)exclusionPaths
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (ASObjectIsEqual(exclusionPaths, _exclusionPaths)) {
|
||||
return;
|
||||
@@ -425,7 +423,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (NSArray *)exclusionPaths
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return _exclusionPaths;
|
||||
}
|
||||
@@ -434,7 +432,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
_drawParameter = {
|
||||
.backgroundColor = self.backgroundColor,
|
||||
@@ -446,7 +444,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (void)drawRect:(CGRect)bounds withParameters:(id <NSObject>)p isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
ASTextNodeDrawParameter drawParameter = _drawParameter;
|
||||
CGRect drawParameterBounds = drawParameter.bounds;
|
||||
@@ -499,7 +497,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
ASTextKitRenderer *renderer = [self _renderer];
|
||||
NSRange visibleRange = renderer.firstVisibleRange;
|
||||
@@ -626,14 +624,14 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (ASTextNodeHighlightStyle)highlightStyle
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return _highlightStyle;
|
||||
}
|
||||
|
||||
- (void)setHighlightStyle:(ASTextNodeHighlightStyle)highlightStyle
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
_highlightStyle = highlightStyle;
|
||||
}
|
||||
@@ -717,7 +715,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
}
|
||||
|
||||
if (highlightTargetLayer != nil) {
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
NSArray *highlightRects = [[self _renderer] rectsForTextRange:highlightRange measureOption:ASTextKitRendererMeasureOptionBlock];
|
||||
NSMutableArray *converted = [NSMutableArray arrayWithCapacity:highlightRects.count];
|
||||
@@ -797,7 +795,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (NSArray *)_rectsForTextRange:(NSRange)textRange measureOption:(ASTextKitRendererMeasureOption)measureOption
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
NSArray *rects = [[self _renderer] rectsForTextRange:textRange measureOption:measureOption];
|
||||
NSMutableArray *adjustedRects = [NSMutableArray array];
|
||||
@@ -815,7 +813,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (CGRect)trailingRect
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
CGRect rect = [[self _renderer] trailingRect];
|
||||
return ASTextNodeAdjustRenderRectForShadowPadding(rect, self.shadowPadding);
|
||||
@@ -823,7 +821,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (CGRect)frameForTextRange:(NSRange)textRange
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
CGRect frame = [[self _renderer] frameForTextRange:textRange];
|
||||
return ASTextNodeAdjustRenderRectForShadowPadding(frame, self.shadowPadding);
|
||||
@@ -833,7 +831,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (void)setPlaceholderColor:(UIColor *)placeholderColor
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
_placeholderColor = placeholderColor;
|
||||
|
||||
@@ -850,7 +848,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
return nil;
|
||||
}
|
||||
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
UIGraphicsBeginImageContext(size);
|
||||
[self.placeholderColor setFill];
|
||||
@@ -932,7 +930,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
if (inAdditionalTruncationMessage) {
|
||||
NSRange visibleRange = NSMakeRange(0, 0);
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
visibleRange = [self _renderer].firstVisibleRange;
|
||||
}
|
||||
NSRange truncationMessageRange = [self _additionalTruncationMessageRangeWithVisibleRange:visibleRange];
|
||||
@@ -1011,14 +1009,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (BOOL)_pendingLinkTap
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return (_highlightedLinkAttributeValue != nil && ![self _pendingTruncationTap]) && _delegate != nil;
|
||||
}
|
||||
|
||||
- (BOOL)_pendingTruncationTap
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return [_highlightedLinkAttributeName isEqualToString:ASTextNodeTruncationTokenAttributeName];
|
||||
}
|
||||
@@ -1027,14 +1025,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (CGColorRef)shadowColor
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return _shadowColor;
|
||||
}
|
||||
|
||||
- (void)setShadowColor:(CGColorRef)shadowColor
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_shadowColor != shadowColor) {
|
||||
if (shadowColor != NULL) {
|
||||
@@ -1048,14 +1046,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (CGSize)shadowOffset
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return _shadowOffset;
|
||||
}
|
||||
|
||||
- (void)setShadowOffset:(CGSize)shadowOffset
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (!CGSizeEqualToSize(_shadowOffset, shadowOffset)) {
|
||||
_shadowOffset = shadowOffset;
|
||||
@@ -1066,14 +1064,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (CGFloat)shadowOpacity
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return _shadowOpacity;
|
||||
}
|
||||
|
||||
- (void)setShadowOpacity:(CGFloat)shadowOpacity
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_shadowOpacity != shadowOpacity) {
|
||||
_shadowOpacity = shadowOpacity;
|
||||
@@ -1084,14 +1082,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (CGFloat)shadowRadius
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return _shadowRadius;
|
||||
}
|
||||
|
||||
- (void)setShadowRadius:(CGFloat)shadowRadius
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_shadowRadius != shadowRadius) {
|
||||
_shadowRadius = shadowRadius;
|
||||
@@ -1107,7 +1105,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI
|
||||
|
||||
- (UIEdgeInsets)shadowPaddingWithRenderer:(ASTextKitRenderer *)renderer
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return renderer.shadower.shadowPadding;
|
||||
}
|
||||
@@ -1126,7 +1124,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
|
||||
- (void)setTruncationAttributedText:(NSAttributedString *)truncationAttributedText
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (ASObjectIsEqual(_truncationAttributedText, truncationAttributedText)) {
|
||||
return;
|
||||
@@ -1138,7 +1136,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
|
||||
- (void)setAdditionalTruncationMessage:(NSAttributedString *)additionalTruncationMessage
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (ASObjectIsEqual(_additionalTruncationMessage, additionalTruncationMessage)) {
|
||||
return;
|
||||
@@ -1150,7 +1148,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
|
||||
- (void)setTruncationMode:(NSLineBreakMode)truncationMode
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_truncationMode != truncationMode) {
|
||||
_truncationMode = truncationMode;
|
||||
@@ -1161,7 +1159,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
|
||||
- (BOOL)isTruncated
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
ASTextKitRenderer *renderer = [self _renderer];
|
||||
return renderer.firstVisibleRange.length < _attributedText.length;
|
||||
@@ -1169,7 +1167,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
|
||||
- (void)setPointSizeScaleFactors:(NSArray *)pointSizeScaleFactors
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if ([_pointSizeScaleFactors isEqualToArray:pointSizeScaleFactors] == NO) {
|
||||
_pointSizeScaleFactors = pointSizeScaleFactors;
|
||||
@@ -1179,7 +1177,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
|
||||
- (void)setMaximumNumberOfLines:(NSUInteger)maximumNumberOfLines
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_maximumNumberOfLines != maximumNumberOfLines) {
|
||||
_maximumNumberOfLines = maximumNumberOfLines;
|
||||
@@ -1190,7 +1188,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
|
||||
- (NSUInteger)lineCount
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return [[self _renderer] lineCount];
|
||||
}
|
||||
@@ -1199,7 +1197,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
|
||||
- (void)_updateComposedTruncationText
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
_composedTruncationText = [self _prepareTruncationStringForDrawing:[self _composedTruncationText]];
|
||||
}
|
||||
@@ -1217,7 +1215,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
*/
|
||||
- (NSRange)_additionalTruncationMessageRangeWithVisibleRange:(NSRange)visibleRange
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
// Check if we even have an additional truncation message.
|
||||
if (!_additionalTruncationMessage) {
|
||||
@@ -1240,7 +1238,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
*/
|
||||
- (NSAttributedString *)_composedTruncationText
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
//If we have neither return the default
|
||||
if (!_additionalTruncationMessage && !_truncationAttributedText) {
|
||||
@@ -1270,7 +1268,7 @@ static NSAttributedString *DefaultTruncationAttributedString()
|
||||
*/
|
||||
- (NSAttributedString *)_prepareTruncationStringForDrawing:(NSAttributedString *)truncationString
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> l(_textLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
truncationString = ASCleanseAttributedStringOfCoreTextAttributes(truncationString);
|
||||
NSMutableAttributedString *truncationMutableString = [truncationString mutableCopy];
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
//
|
||||
#if TARGET_OS_IOS
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import "ASDisplayNodeInternal.h"
|
||||
#import "ASDisplayNode+Subclasses.h"
|
||||
#import "ASVideoNode.h"
|
||||
#import "ASEqualityHelpers.h"
|
||||
@@ -39,8 +40,6 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
@interface ASVideoNode ()
|
||||
{
|
||||
ASDN::RecursiveMutex _videoLock;
|
||||
|
||||
__weak id<ASVideoNodeDelegate> _delegate;
|
||||
struct {
|
||||
unsigned int delegateVideNodeShouldChangePlayerStateTo:1;
|
||||
@@ -122,7 +121,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (AVPlayerItem *)constructPlayerItem
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_asset != nil) {
|
||||
return [[AVPlayerItem alloc] initWithAsset:_asset];
|
||||
@@ -210,7 +209,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
CGSize calculatedSize = constrainedSize;
|
||||
|
||||
// if a preferredFrameSize is set, call the superclass to return that instead of using the image size.
|
||||
@@ -273,7 +272,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (void)setVideoPlaceholderImage:(UIImage *)image
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (image != nil) {
|
||||
self.contentMode = ASContentModeFromVideoGravity(_gravity);
|
||||
}
|
||||
@@ -282,7 +281,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (object != _currentPlayerItem) {
|
||||
return;
|
||||
@@ -335,7 +334,7 @@ static NSString * const kStatus = @"status";
|
||||
{
|
||||
[super fetchData];
|
||||
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
AVAsset *asset = self.asset;
|
||||
// Return immediately if the asset is nil;
|
||||
if (asset == nil || self.playerState == ASVideoNodePlayerStateInitialLoading) {
|
||||
@@ -385,7 +384,7 @@ static NSString * const kStatus = @"status";
|
||||
[super clearFetchedData];
|
||||
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
self.player = nil;
|
||||
self.currentItem = nil;
|
||||
@@ -396,7 +395,7 @@ static NSString * const kStatus = @"status";
|
||||
{
|
||||
[super visibleStateDidChange:isVisible];
|
||||
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (isVisible) {
|
||||
if (_shouldBePlaying || _shouldAutoplay) {
|
||||
@@ -413,7 +412,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (void)setPlayerState:(ASVideoNodePlayerState)playerState
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
ASVideoNodePlayerState oldState = _playerState;
|
||||
|
||||
@@ -430,7 +429,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (void)setAsset:(AVAsset *)asset
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (ASAssetIsEqual(asset, _asset)) {
|
||||
return;
|
||||
@@ -445,13 +444,13 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (AVAsset *)asset
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _asset;
|
||||
}
|
||||
|
||||
- (AVPlayer *)player
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _player;
|
||||
}
|
||||
|
||||
@@ -489,7 +488,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (void)setGravity:(NSString *)gravity
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (_playerNode.isNodeLoaded) {
|
||||
((AVPlayerLayer *)_playerNode.layer).videoGravity = gravity;
|
||||
}
|
||||
@@ -499,19 +498,19 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (NSString *)gravity
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _gravity;
|
||||
}
|
||||
|
||||
- (BOOL)muted
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _muted;
|
||||
}
|
||||
|
||||
- (void)setMuted:(BOOL)muted
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
_player.muted = muted;
|
||||
_muted = muted;
|
||||
@@ -521,7 +520,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (void)play
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (![self isStateChangeValid:ASVideoNodePlayerStatePlaying]) {
|
||||
return;
|
||||
@@ -558,7 +557,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (void)pause
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (![self isStateChangeValid:ASVideoNodePlayerStatePaused]) {
|
||||
return;
|
||||
}
|
||||
@@ -569,7 +568,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (BOOL)isPlaying
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
return (_player.rate > 0 && !_player.error);
|
||||
}
|
||||
@@ -637,13 +636,13 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (AVPlayerItem *)currentItem
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _currentPlayerItem;
|
||||
}
|
||||
|
||||
- (void)setCurrentItem:(AVPlayerItem *)currentItem
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
[self removePlayerItemObservers:_currentPlayerItem];
|
||||
|
||||
@@ -656,13 +655,13 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (ASDisplayNode *)playerNode
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _playerNode;
|
||||
}
|
||||
|
||||
- (void)setPlayerNode:(ASDisplayNode *)playerNode
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_playerNode = playerNode;
|
||||
|
||||
[self setNeedsLayout];
|
||||
@@ -670,7 +669,7 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (void)setPlayer:(AVPlayer *)player
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_player = player;
|
||||
player.muted = _muted;
|
||||
((AVPlayerLayer *)_playerNode.layer).player = player;
|
||||
@@ -678,13 +677,13 @@ static NSString * const kStatus = @"status";
|
||||
|
||||
- (BOOL)shouldBePlaying
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _shouldBePlaying;
|
||||
}
|
||||
|
||||
- (void)setShouldBePlaying:(BOOL)shouldBePlaying
|
||||
{
|
||||
ASDN::MutexLocker l(_videoLock);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_shouldBePlaying = shouldBePlaying;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user