mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-03 19:30:09 +00:00
* Fixed license * Update all licenses * Update Dangerfile for new license * Update already updated licenses * Closer… * Closer… * Closer… * Closer… * Closer… * Closer… * Closer… * Closer… * Closer… * Closer… * Closer…
299 lines
11 KiB
Objective-C
299 lines
11 KiB
Objective-C
//
|
|
// ASDisplayNodeInternal.h
|
|
// Texture
|
|
//
|
|
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under the BSD-style license found in the
|
|
// LICENSE file in the /ASDK-Licenses directory of this source tree. An additional
|
|
// grant of patent rights can be found in the PATENTS file in the same directory.
|
|
//
|
|
// Modifications to this file made after 4/13/2017 are: Copyright (c) 2017-present,
|
|
// Pinterest, Inc. Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
|
|
//
|
|
// The following methods are ONLY for use by _ASDisplayLayer, _ASDisplayView, and ASDisplayNode.
|
|
// These methods must never be called or overridden by other classes.
|
|
//
|
|
|
|
#import <atomic>
|
|
#import <AsyncDisplayKit/ASDisplayNode.h>
|
|
#import <AsyncDisplayKit/ASDisplayNode+Beta.h>
|
|
#import <AsyncDisplayKit/ASLayoutElement.h>
|
|
#import <AsyncDisplayKit/ASLayoutTransition.h>
|
|
#import <AsyncDisplayKit/ASThread.h>
|
|
#import <AsyncDisplayKit/_ASTransitionContext.h>
|
|
#import <AsyncDisplayKit/ASWeakSet.h>
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
@protocol _ASDisplayLayerDelegate;
|
|
@class _ASDisplayLayer;
|
|
@class _ASPendingState;
|
|
@class ASSentinel;
|
|
struct ASDisplayNodeFlags;
|
|
|
|
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
|
|
BOOL ASDisplayNodeNeedsSpecialPropertiesHandlingForFlags(ASDisplayNodeFlags flags);
|
|
|
|
/// Get the pending view state for the node, creating one if needed.
|
|
_ASPendingState * ASDisplayNodeGetPendingState(ASDisplayNode * node);
|
|
|
|
typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides)
|
|
{
|
|
ASDisplayNodeMethodOverrideNone = 0,
|
|
ASDisplayNodeMethodOverrideTouchesBegan = 1 << 0,
|
|
ASDisplayNodeMethodOverrideTouchesCancelled = 1 << 1,
|
|
ASDisplayNodeMethodOverrideTouchesEnded = 1 << 2,
|
|
ASDisplayNodeMethodOverrideTouchesMoved = 1 << 3,
|
|
ASDisplayNodeMethodOverrideLayoutSpecThatFits = 1 << 4,
|
|
ASDisplayNodeMethodOverrideFetchData = 1 << 5,
|
|
ASDisplayNodeMethodOverrideClearFetchedData = 1 << 6
|
|
};
|
|
|
|
FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification;
|
|
FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp;
|
|
|
|
// Allow 2^n increments of begin disabling hierarchy notifications
|
|
#define VISIBILITY_NOTIFICATIONS_DISABLED_BITS 4
|
|
|
|
#define TIME_DISPLAYNODE_OPS 0 // If you're using this information frequently, try: (DEBUG || PROFILE)
|
|
|
|
@interface ASDisplayNode ()
|
|
{
|
|
@package
|
|
_ASPendingState *_pendingViewState;
|
|
|
|
UIView *_view;
|
|
CALayer *_layer;
|
|
|
|
struct ASDisplayNodeFlags {
|
|
// public properties
|
|
unsigned synchronous:1;
|
|
unsigned viewEverHadAGestureRecognizerAttached:1;
|
|
unsigned layerBacked:1;
|
|
unsigned displaysAsynchronously:1;
|
|
unsigned shouldRasterizeDescendants:1;
|
|
unsigned shouldBypassEnsureDisplay:1;
|
|
unsigned displaySuspended:1;
|
|
unsigned shouldAnimateSizeChanges:1;
|
|
unsigned hasCustomDrawingPriority:1;
|
|
|
|
// Wrapped view handling
|
|
|
|
// The layer contents should not be cleared in case the node is wrapping a UIImageView.UIImageView is specifically
|
|
// optimized for performance and does not use the usual way to provide the contents of the CALayer via the
|
|
// CALayerDelegate method that backs the UIImageView.
|
|
unsigned canClearContentsOfLayer:1;
|
|
|
|
// Prevent calling setNeedsDisplay on a layer that backs a UIImageView. Usually calling setNeedsDisplay on a CALayer
|
|
// triggers a recreation of the contents of layer unfortunately calling it on a CALayer that backs a UIImageView
|
|
// it goes through the normal flow to assign the contents to a layer via the CALayerDelegate methods. Unfortunately
|
|
// UIImageView does not do recreate the layer contents the usual way, it actually does not implement some of the
|
|
// methods at all instead it throws away the contents of the layer and nothing will show up.
|
|
unsigned canCallSetNeedsDisplayOfLayer:1;
|
|
|
|
// whether custom drawing is enabled
|
|
unsigned implementsInstanceDrawRect:1;
|
|
unsigned implementsDrawRect:1;
|
|
unsigned implementsInstanceImageDisplay:1;
|
|
unsigned implementsImageDisplay:1;
|
|
unsigned implementsDrawParameters:1;
|
|
|
|
// internal state
|
|
unsigned isEnteringHierarchy:1;
|
|
unsigned isExitingHierarchy:1;
|
|
unsigned isInHierarchy:1;
|
|
unsigned visibilityNotificationsDisabled:VISIBILITY_NOTIFICATIONS_DISABLED_BITS;
|
|
unsigned isDeallocating:1;
|
|
} _flags;
|
|
|
|
@protected
|
|
ASDisplayNode * __weak _supernode;
|
|
NSMutableArray<ASDisplayNode *> *_subnodes;
|
|
|
|
ASLayoutElementStyle *_style;
|
|
ASPrimitiveTraitCollection _primitiveTraitCollection;
|
|
|
|
std::atomic_uint _displaySentinel;
|
|
|
|
// This is the desired contentsScale, not the scale at which the layer's contents should be displayed
|
|
CGFloat _contentsScaleForDisplay;
|
|
|
|
UIEdgeInsets _hitTestSlop;
|
|
|
|
#if ASEVENTLOG_ENABLE
|
|
ASEventLog *_eventLog;
|
|
#endif
|
|
|
|
// Main thread only
|
|
BOOL _automaticallyManagesSubnodes;
|
|
_ASTransitionContext *_pendingLayoutTransitionContext;
|
|
NSTimeInterval _defaultLayoutTransitionDuration;
|
|
NSTimeInterval _defaultLayoutTransitionDelay;
|
|
UIViewAnimationOptions _defaultLayoutTransitionOptions;
|
|
|
|
int32_t _transitionID;
|
|
BOOL _transitionInProgress;
|
|
|
|
int32_t _pendingTransitionID;
|
|
ASLayoutTransition *_pendingLayoutTransition;
|
|
std::shared_ptr<ASDisplayNodeLayout> _calculatedDisplayNodeLayout;
|
|
std::shared_ptr<ASDisplayNodeLayout> _pendingDisplayNodeLayout;
|
|
|
|
ASDisplayNodeViewBlock _viewBlock;
|
|
ASDisplayNodeLayerBlock _layerBlock;
|
|
NSMutableArray<ASDisplayNodeDidLoadBlock> *_onDidLoadBlocks;
|
|
Class _viewClass; // nil -> _ASDisplayView
|
|
Class _layerClass; // nil -> _ASDisplayLayer
|
|
|
|
UIImage *_placeholderImage;
|
|
CALayer *_placeholderLayer;
|
|
|
|
// keeps track of nodes/subnodes that have not finished display, used with placeholders
|
|
ASWeakSet *_pendingDisplayNodes;
|
|
|
|
ASDisplayNodeContextModifier _willDisplayNodeContentWithRenderingContext;
|
|
ASDisplayNodeContextModifier _didDisplayNodeContentWithRenderingContext;
|
|
|
|
// Accessibility support
|
|
BOOL _isAccessibilityElement;
|
|
NSString *_accessibilityLabel;
|
|
NSString *_accessibilityHint;
|
|
NSString *_accessibilityValue;
|
|
UIAccessibilityTraits _accessibilityTraits;
|
|
CGRect _accessibilityFrame;
|
|
NSString *_accessibilityLanguage;
|
|
BOOL _accessibilityElementsHidden;
|
|
BOOL _accessibilityViewIsModal;
|
|
BOOL _shouldGroupAccessibilityChildren;
|
|
NSString *_accessibilityIdentifier;
|
|
UIAccessibilityNavigationStyle _accessibilityNavigationStyle;
|
|
NSArray *_accessibilityHeaderElements;
|
|
CGPoint _accessibilityActivationPoint;
|
|
UIBezierPath *_accessibilityPath;
|
|
|
|
// performance measurement
|
|
ASDisplayNodePerformanceMeasurementOptions _measurementOptions;
|
|
NSTimeInterval _layoutSpecTotalTime;
|
|
NSInteger _layoutSpecNumberOfPasses;
|
|
NSTimeInterval _layoutComputationTotalTime;
|
|
NSInteger _layoutComputationNumberOfPasses;
|
|
|
|
#if YOGA
|
|
YGNodeRef _yogaNode;
|
|
ASDisplayNode *_yogaParent;
|
|
NSMutableArray<ASDisplayNode *> *_yogaChildren;
|
|
ASLayout *_yogaCalculatedLayout;
|
|
#endif
|
|
|
|
#if TIME_DISPLAYNODE_OPS
|
|
@public
|
|
NSTimeInterval _debugTimeToCreateView;
|
|
NSTimeInterval _debugTimeToApplyPendingState;
|
|
NSTimeInterval _debugTimeToAddSubnodeViews;
|
|
NSTimeInterval _debugTimeForDidLoad;
|
|
#endif
|
|
}
|
|
|
|
+ (void)scheduleNodeForRecursiveDisplay:(ASDisplayNode *)node;
|
|
|
|
/// The _ASDisplayLayer backing the node, if any.
|
|
@property (nullable, nonatomic, readonly, strong) _ASDisplayLayer *asyncLayer;
|
|
|
|
/// Bitmask to check which methods an object overrides.
|
|
@property (nonatomic, assign, readonly) ASDisplayNodeMethodOverrides methodOverrides;
|
|
|
|
/**
|
|
* Invoked before a call to setNeedsLayout to the underlying view
|
|
*/
|
|
- (void)__setNeedsLayout;
|
|
|
|
/**
|
|
* Invoked after a call to setNeedsDisplay to the underlying view
|
|
*/
|
|
- (void)__setNeedsDisplay;
|
|
|
|
/**
|
|
* Called from [CALayer layoutSublayers:]. Executes the layout pass for the node
|
|
*/
|
|
- (void)__layout;
|
|
|
|
/**
|
|
* Internal method to add / replace / insert subnode and remove from supernode without checking if
|
|
* node has automaticallyManagesSubnodes set to YES.
|
|
*/
|
|
- (void)_addSubnode:(ASDisplayNode *)subnode;
|
|
- (void)_replaceSubnode:(ASDisplayNode *)oldSubnode withSubnode:(ASDisplayNode *)replacementSubnode;
|
|
- (void)_insertSubnode:(ASDisplayNode *)subnode belowSubnode:(ASDisplayNode *)below;
|
|
- (void)_insertSubnode:(ASDisplayNode *)subnode aboveSubnode:(ASDisplayNode *)above;
|
|
- (void)_insertSubnode:(ASDisplayNode *)subnode atIndex:(NSInteger)idx;
|
|
- (void)_removeFromSupernodeIfEqualTo:(ASDisplayNode *)supernode;
|
|
- (void)_removeFromSupernode;
|
|
|
|
// Private API for helper functions / unit tests. Use ASDisplayNodeDisableHierarchyNotifications() to control this.
|
|
- (BOOL)__visibilityNotificationsDisabled;
|
|
- (BOOL)__selfOrParentHasVisibilityNotificationsDisabled;
|
|
- (void)__incrementVisibilityNotificationsDisabled;
|
|
- (void)__decrementVisibilityNotificationsDisabled;
|
|
|
|
/// Helper method to summarize whether or not the node run through the display process
|
|
- (BOOL)_implementsDisplay;
|
|
|
|
/// Display the node's view/layer immediately on the current thread, bypassing the background thread rendering. Will be deprecated.
|
|
- (void)displayImmediately;
|
|
|
|
/// Alternative initialiser for backing with a custom view class. Supports asynchronous display with _ASDisplayView subclasses.
|
|
- (instancetype)initWithViewClass:(Class)viewClass;
|
|
|
|
/// Alternative initialiser for backing with a custom layer class. Supports asynchronous display with _ASDisplayLayer subclasses.
|
|
- (instancetype)initWithLayerClass:(Class)layerClass;
|
|
|
|
@property (nonatomic, assign) CGFloat contentsScaleForDisplay;
|
|
|
|
- (void)applyPendingViewState;
|
|
|
|
/**
|
|
* // TODO: NOT YET IMPLEMENTED
|
|
*
|
|
* @abstract Prevents interface state changes from affecting the node, until disabled.
|
|
*
|
|
* @discussion Useful to avoid flashing after removing a node from the hierarchy and re-adding it.
|
|
* Removing a node from the hierarchy will cause it to exit the Display state, clearing its contents.
|
|
* For some animations, it's desirable to be able to remove a node without causing it to re-display.
|
|
* Once re-enabled, the interface state will be updated to the same value it would have been.
|
|
*
|
|
* @see ASInterfaceState
|
|
*/
|
|
@property (nonatomic, assign) BOOL interfaceStateSuspended;
|
|
|
|
/**
|
|
* This method has proven helpful in a few rare scenarios, similar to a category extension on UIView,
|
|
* but it's considered private API for now and its use should not be encouraged.
|
|
* @param checkViewHierarchy If YES, and no supernode can be found, method will walk up from `self.view` to find a supernode.
|
|
* If YES, this method must be called on the main thread and the node must not be layer-backed.
|
|
*/
|
|
- (nullable ASDisplayNode *)_supernodeWithClass:(Class)supernodeClass checkViewHierarchy:(BOOL)checkViewHierarchy;
|
|
|
|
/**
|
|
* Convenience method to access this node's trait collection struct. Externally, users should interact
|
|
* with the trait collection via ASTraitCollection
|
|
*/
|
|
- (ASPrimitiveTraitCollection)primitiveTraitCollection;
|
|
|
|
/**
|
|
* This is a non-deprecated internal declaration of the property. Public declaration
|
|
* is in ASDisplayNode+Beta.h
|
|
*/
|
|
@property (nonatomic, assign) BOOL shouldRasterizeDescendants;
|
|
|
|
- (void)nodeViewDidAddGestureRecognizer;
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|