mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Clean up ASDisplayNode internal flags.
* Reorganise and rename `_flags` for clarity and consistency. * Remove ambiguity between `implementsDisplay` and `hasClassDisplay`. * Delete useless `hasWillDisplayAsyncLayer` check -- make it a simple subclass override point, as with `didDisplayAsyncLayer:`. * Minor comment cleanup.
This commit is contained in:
@@ -103,22 +103,19 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
// Avoid recursive loops if a subclass implements an init method that calls -initWith*Class:
|
||||
- (void)_initializeInstance
|
||||
{
|
||||
_contentsScaleForDisplay = ASDisplayNodeScreenScale();
|
||||
|
||||
_displaySentinel = [[ASSentinel alloc] init];
|
||||
|
||||
_flags.inWindow = NO;
|
||||
_flags.isInWindow = NO;
|
||||
_flags.displaysAsynchronously = YES;
|
||||
|
||||
// As an optimization, it may be worth a caching system that performs these checks once per class in +initialize (see above).
|
||||
_flags.implementsDisplay = [[self class] respondsToSelector:@selector(drawRect:withParameters:isCancelled:isRasterizing:)] || [self.class respondsToSelector:@selector(displayWithParameters:isCancelled:)];
|
||||
|
||||
_flags.hasClassDisplay = ([[self class] respondsToSelector:@selector(displayWithParameters:isCancelled:)] ? 1 : 0);
|
||||
_flags.hasWillDisplayAsyncLayer = ([self respondsToSelector:@selector(willDisplayAsyncLayer:)] ? 1 : 0);
|
||||
_flags.hasDrawParametersForAsyncLayer = ([self respondsToSelector:@selector(drawParametersForAsyncLayer:)] ? 1 : 0);
|
||||
_flags.implementsDrawRect = ([[self class] respondsToSelector:@selector(drawRect:withParameters:isCancelled:isRasterizing:)] ? 1 : 0);
|
||||
_flags.implementsImageDisplay = ([[self class] respondsToSelector:@selector(displayWithParameters:isCancelled:)] ? 1 : 0);
|
||||
_flags.implementsDrawParameters = ([self respondsToSelector:@selector(drawParametersForAsyncLayer:)] ? 1 : 0);
|
||||
}
|
||||
|
||||
- (id)init
|
||||
@@ -140,7 +137,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
|
||||
[self _initializeInstance];
|
||||
_viewClass = viewClass;
|
||||
_flags.isSynchronous = ![viewClass isSubclassOfClass:[_ASDisplayView class]];
|
||||
_flags.synchronous = ![viewClass isSubclassOfClass:[_ASDisplayView class]];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -154,8 +151,8 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
|
||||
[self _initializeInstance];
|
||||
_layerClass = layerClass;
|
||||
_flags.isSynchronous = ![layerClass isSubclassOfClass:[_ASDisplayLayer class]];
|
||||
_flags.isLayerBacked = YES;
|
||||
_flags.synchronous = ![layerClass isSubclassOfClass:[_ASDisplayLayer class]];
|
||||
_flags.layerBacked = YES;
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -178,7 +175,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
|
||||
_view = nil;
|
||||
_subnodes = nil;
|
||||
if (_flags.isLayerBacked)
|
||||
if (_flags.layerBacked)
|
||||
_layer.delegate = nil;
|
||||
_layer = nil;
|
||||
|
||||
@@ -277,8 +274,8 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
ASDisplayNodeAssert(!_flags.isLayerBacked, @"Call to -view undefined on layer-backed nodes");
|
||||
if (_flags.isLayerBacked) {
|
||||
ASDisplayNodeAssert(!_flags.layerBacked, @"Call to -view undefined on layer-backed nodes");
|
||||
if (_flags.layerBacked) {
|
||||
return nil;
|
||||
}
|
||||
if (!_view) {
|
||||
@@ -293,7 +290,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
if (!_layer) {
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
if (!_flags.isLayerBacked) {
|
||||
if (!_flags.layerBacked) {
|
||||
return self.view.layer;
|
||||
}
|
||||
[self _loadViewOrLayerIsLayerBacked:YES];
|
||||
@@ -304,10 +301,10 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
// Returns nil if our view is not an _ASDisplayView, but will create it if necessary.
|
||||
- (_ASDisplayView *)ensureAsyncView
|
||||
{
|
||||
return _flags.isSynchronous ? nil:(_ASDisplayView *)self.view;
|
||||
return _flags.synchronous ? nil : (_ASDisplayView *)self.view;
|
||||
}
|
||||
|
||||
// Returns nil if the layer is not an _ASDisplayLayer; will not create the view if nil
|
||||
// Returns nil if the layer is not an _ASDisplayLayer; will not create the layer if nil.
|
||||
- (_ASDisplayLayer *)asyncLayer
|
||||
{
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
@@ -317,17 +314,17 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
- (BOOL)isNodeLoaded
|
||||
{
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return (_view != nil || (_flags.isLayerBacked && _layer != nil));
|
||||
return (_view != nil || (_flags.layerBacked && _layer != nil));
|
||||
}
|
||||
|
||||
- (BOOL)isSynchronous
|
||||
{
|
||||
return _flags.isSynchronous;
|
||||
return _flags.synchronous;
|
||||
}
|
||||
|
||||
- (void)setSynchronous:(BOOL)flag
|
||||
{
|
||||
_flags.isSynchronous = flag;
|
||||
_flags.synchronous = flag;
|
||||
}
|
||||
|
||||
- (void)setLayerBacked:(BOOL)isLayerBacked
|
||||
@@ -336,15 +333,15 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
ASDisplayNodeAssert(!_view && !_layer, @"Cannot change isLayerBacked after layer or view has loaded");
|
||||
if (isLayerBacked != _flags.isLayerBacked && !_view && !_layer) {
|
||||
_flags.isLayerBacked = isLayerBacked;
|
||||
if (isLayerBacked != _flags.layerBacked && !_view && !_layer) {
|
||||
_flags.layerBacked = isLayerBacked;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isLayerBacked
|
||||
{
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _flags.isLayerBacked;
|
||||
return _flags.layerBacked;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -360,10 +357,10 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
// - we haven't already
|
||||
// - the width is different from the last time
|
||||
// - the height is different from the last time
|
||||
if (!_flags.sizeCalculated || !CGSizeEqualToSize(constrainedSize, _constrainedSize)) {
|
||||
if (!_flags.isMeasured || !CGSizeEqualToSize(constrainedSize, _constrainedSize)) {
|
||||
_size = [self calculateSizeThatFits:constrainedSize];
|
||||
_constrainedSize = constrainedSize;
|
||||
_flags.sizeCalculated = YES;
|
||||
_flags.isMeasured = YES;
|
||||
}
|
||||
|
||||
ASDisplayNodeAssertTrue(_size.width >= 0.0);
|
||||
@@ -387,7 +384,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
|
||||
// Can't do this for synchronous nodes (using layers that are not _ASDisplayLayer and so we can't control display prevention/cancel)
|
||||
if (_flags.isSynchronous)
|
||||
if (_flags.synchronous)
|
||||
return;
|
||||
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
@@ -467,7 +464,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
||||
- (void)displayImmediately
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(!_flags.isSynchronous, @"this method is designed for asynchronous mode only");
|
||||
ASDisplayNodeAssert(!_flags.synchronous, @"this method is designed for asynchronous mode only");
|
||||
|
||||
[[self asyncLayer] displayImmediately];
|
||||
}
|
||||
@@ -631,6 +628,10 @@ static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNo
|
||||
|
||||
#pragma mark - _ASDisplayLayerDelegate
|
||||
|
||||
- (void)willDisplayAsyncLayer:(_ASDisplayLayer *)layer
|
||||
{
|
||||
}
|
||||
|
||||
- (void)didDisplayAsyncLayer:(_ASDisplayLayer *)layer
|
||||
{
|
||||
// Subclass hook.
|
||||
@@ -648,7 +649,7 @@ static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNo
|
||||
[self __exitHierarchy];
|
||||
}
|
||||
|
||||
ASDisplayNodeAssert(_flags.isLayerBacked, @"We shouldn't get called back here if there is no layer");
|
||||
ASDisplayNodeAssert(_flags.layerBacked, @"We shouldn't get called back here if there is no layer");
|
||||
return (id<CAAction>)[NSNull null];
|
||||
}
|
||||
|
||||
@@ -657,9 +658,9 @@ static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNo
|
||||
static bool disableNotificationsForMovingBetweenParents(ASDisplayNode *from, ASDisplayNode *to)
|
||||
{
|
||||
if (!from || !to) return NO;
|
||||
if (from->_flags.isSynchronous) return NO;
|
||||
if (to->_flags.isSynchronous) return NO;
|
||||
if (from->_flags.inWindow != to->_flags.inWindow) return NO;
|
||||
if (from->_flags.synchronous) return NO;
|
||||
if (to->_flags.synchronous) return NO;
|
||||
if (from->_flags.isInWindow != to->_flags.isInWindow) return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -960,14 +961,14 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
[_supernode _removeSubnode:self];
|
||||
|
||||
if (ASDisplayNodeThreadIsMain()) {
|
||||
if (_flags.isLayerBacked) {
|
||||
if (_flags.layerBacked) {
|
||||
[_layer removeFromSuperlayer];
|
||||
} else {
|
||||
[_view removeFromSuperview];
|
||||
}
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (_flags.isLayerBacked) {
|
||||
if (_flags.layerBacked) {
|
||||
[_layer removeFromSuperlayer];
|
||||
} else {
|
||||
[_view removeFromSuperview];
|
||||
@@ -985,7 +986,7 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
- (void)__incrementVisibilityNotificationsDisabled
|
||||
{
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
const size_t maxVisibilityIncrement = (1ULL<<visibilityNotificationsDisabledBits) - 1ULL;
|
||||
const size_t maxVisibilityIncrement = (1ULL<<VISIBILITY_NOTIFICATIONS_DISABLED_BITS) - 1ULL;
|
||||
ASDisplayNodeAssert(_flags.visibilityNotificationsDisabled < maxVisibilityIncrement, @"Oops, too many increments of the visibility notifications API");
|
||||
if (_flags.visibilityNotificationsDisabled < maxVisibilityIncrement)
|
||||
_flags.visibilityNotificationsDisabled++;
|
||||
@@ -1019,17 +1020,17 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
- (void)__enterHierarchy
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(!_flags.isInEnterHierarchy, @"Should not cause recursive __enterHierarchy");
|
||||
ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"Should not cause recursive __enterHierarchy");
|
||||
if (!self.inWindow && !_flags.visibilityNotificationsDisabled && ![self __hasParentWithVisibilityNotificationsDisabled]) {
|
||||
self.inWindow = YES;
|
||||
_flags.isInEnterHierarchy = YES;
|
||||
_flags.isEnteringHierarchy = YES;
|
||||
if (self.shouldRasterizeDescendants) {
|
||||
// Nodes that are descendants of a rasterized container do not have views or layers, and so cannot receive visibility notifications directly via orderIn/orderOut CALayer actions. Manually send visibility notifications to rasterized descendants.
|
||||
[self _recursiveWillEnterHierarchy];
|
||||
} else {
|
||||
[self willEnterHierarchy];
|
||||
}
|
||||
_flags.isInEnterHierarchy = NO;
|
||||
_flags.isEnteringHierarchy = NO;
|
||||
|
||||
CALayer *layer = self.layer;
|
||||
if (!self.layer.contents) {
|
||||
@@ -1041,20 +1042,20 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
- (void)__exitHierarchy
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(!_flags.isInExitHierarchy, @"Should not cause recursive __exitHierarchy");
|
||||
ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"Should not cause recursive __exitHierarchy");
|
||||
if (self.inWindow && !_flags.visibilityNotificationsDisabled && ![self __hasParentWithVisibilityNotificationsDisabled]) {
|
||||
self.inWindow = NO;
|
||||
|
||||
[self.asyncLayer cancelAsyncDisplay];
|
||||
|
||||
_flags.isInExitHierarchy = YES;
|
||||
_flags.isExitingHierarchy = YES;
|
||||
if (self.shouldRasterizeDescendants) {
|
||||
// Nodes that are descendants of a rasterized container do not have views or layers, and so cannot receive visibility notifications directly via orderIn/orderOut CALayer actions. Manually send visibility notifications to rasterized descendants.
|
||||
[self _recursiveDidExitHierarchy];
|
||||
} else {
|
||||
[self didExitHierarchy];
|
||||
}
|
||||
_flags.isInExitHierarchy = NO;
|
||||
_flags.isExitingHierarchy = NO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1064,9 +1065,9 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
return;
|
||||
}
|
||||
|
||||
_flags.isInEnterHierarchy = YES;
|
||||
_flags.isEnteringHierarchy = YES;
|
||||
[self willEnterHierarchy];
|
||||
_flags.isInEnterHierarchy = NO;
|
||||
_flags.isEnteringHierarchy = NO;
|
||||
|
||||
for (ASDisplayNode *subnode in self.subnodes) {
|
||||
[subnode _recursiveWillEnterHierarchy];
|
||||
@@ -1079,9 +1080,9 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
return;
|
||||
}
|
||||
|
||||
_flags.isInExitHierarchy = YES;
|
||||
_flags.isExitingHierarchy = YES;
|
||||
[self didExitHierarchy];
|
||||
_flags.isInExitHierarchy = NO;
|
||||
_flags.isExitingHierarchy = NO;
|
||||
|
||||
for (ASDisplayNode *subnode in self.subnodes) {
|
||||
[subnode _recursiveDidExitHierarchy];
|
||||
@@ -1139,7 +1140,7 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
{
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
// This will cause -measure: to actually compute the size instead of returning the previously cached size
|
||||
_flags.sizeCalculated = NO;
|
||||
_flags.isMeasured = NO;
|
||||
}
|
||||
|
||||
- (void)didLoad
|
||||
@@ -1150,15 +1151,15 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
- (void)willEnterHierarchy
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(_flags.isInEnterHierarchy, @"You should never call -willEnterHierarchy directly. Appearance is automatically managed by ASDisplayNode");
|
||||
ASDisplayNodeAssert(!_flags.isInExitHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
|
||||
ASDisplayNodeAssert(_flags.isEnteringHierarchy, @"You should never call -willEnterHierarchy directly. Appearance is automatically managed by ASDisplayNode");
|
||||
ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
|
||||
}
|
||||
|
||||
- (void)didExitHierarchy
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(_flags.isInExitHierarchy, @"You should never call -didExitHierarchy directly. Appearance is automatically managed by ASDisplayNode");
|
||||
ASDisplayNodeAssert(!_flags.isInEnterHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
|
||||
ASDisplayNodeAssert(_flags.isExitingHierarchy, @"You should never call -didExitHierarchy directly. Appearance is automatically managed by ASDisplayNode");
|
||||
ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"ASDisplayNode inconsistency. __enterHierarchy and __exitHierarchy are mutually exclusive");
|
||||
|
||||
[self __exitedHierarchy];
|
||||
}
|
||||
@@ -1316,7 +1317,7 @@ static NSInteger incrementIfFound(NSInteger i) {
|
||||
// for the view/layer are still valid.
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
if (_flags.isLayerBacked) {
|
||||
if (_flags.layerBacked) {
|
||||
[_pendingViewState applyToLayer:_layer];
|
||||
} else {
|
||||
[_pendingViewState applyToView:_view];
|
||||
@@ -1403,7 +1404,7 @@ static void _recursiveSetPreventOrCancelDisplay(ASDisplayNode *node, CALayer *la
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
|
||||
// Can't do this for synchronous nodes (using layers that are not _ASDisplayLayer and so we can't control display prevention/cancel)
|
||||
if (_flags.isSynchronous)
|
||||
if (_flags.synchronous)
|
||||
return;
|
||||
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
@@ -1421,7 +1422,7 @@ static void _recursiveSetPreventOrCancelDisplay(ASDisplayNode *node, CALayer *la
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
return _flags.inWindow;
|
||||
return _flags.isInWindow;
|
||||
}
|
||||
|
||||
- (void)setInWindow:(BOOL)inWindow
|
||||
@@ -1429,7 +1430,7 @@ static void _recursiveSetPreventOrCancelDisplay(ASDisplayNode *node, CALayer *la
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
_flags.inWindow = inWindow;
|
||||
_flags.isInWindow = inWindow;
|
||||
}
|
||||
|
||||
+ (dispatch_queue_t)asyncSizingQueue
|
||||
@@ -1507,7 +1508,7 @@ static void _recursiveSetPreventOrCancelDisplay(ASDisplayNode *node, CALayer *la
|
||||
|
||||
- (NSString *)debugDescription
|
||||
{
|
||||
NSString *notableTargetDesc = (_flags.isLayerBacked ? @" [layer]" : @" [view]");
|
||||
NSString *notableTargetDesc = (_flags.layerBacked ? @" [layer]" : @" [view]");
|
||||
if (_view && _viewClass) { // Nonstandard view is loaded
|
||||
notableTargetDesc = [NSString stringWithFormat:@" [%@ : %p]", _view.class, _view];
|
||||
} else if (_layer && _layerClass) { // Nonstandard layer is loaded
|
||||
|
||||
Reference in New Issue
Block a user