mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-04 11:50:38 +00:00
Right now when an image node enters preload state, we kick off an image request with the default priority. Then when it enters display state, we change the priority to "imminent" which is mapped to the default priority as well. This means that requests from preload and display nodes have the same priority and are put to the same pool. The right behavior would be that preload requests should have a lower priority from the beginning. Another problem is that, due to the execution order of -didEnter(Preload|Display|Visible)State calls, a node may kick off a low priority request when it enters preload state even though it knows that it's also visible. By the time -didEnterVisibleState is called, the low priority request may have already been consumed and the download/data task won't pick up the new higher priority, or some work needs to be done to move it to another queue. A better behavior would be to always use the current interface state to determine the priority. This means that visible nodes will kick off high priority requests as soon as -didEnterPreloadState is called. The last (and smaller) issue is that a node marks its request as preload/low priority as soon as it exits visible state. I'd argue that this is too agressive. It may be reasonble for nodes in the trailing direction. Even so, we already handle this case by (almost always) have smaller trailing buffers. So this diff makes sure that nodes that exited visible state will have imminent/default priority if they remain in the display range. All of these new behaviors are wrapped in an experiment and will be tested carefully before being rolled out. * Add imports * Fix build failure * Encapsulate common logics into methods * Address comments
241 lines
10 KiB
Objective-C
241 lines
10 KiB
Objective-C
//
|
|
// ASImageProtocols.h
|
|
// Texture
|
|
//
|
|
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
|
|
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
|
|
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
|
|
#import <UIKit/UIKit.h>
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
@protocol ASAnimatedImageProtocol;
|
|
|
|
@protocol ASImageContainerProtocol <NSObject>
|
|
|
|
- (nullable UIImage *)asdk_image;
|
|
- (nullable NSData *)asdk_animatedImageData;
|
|
|
|
@end
|
|
|
|
typedef void(^ASImageCacherCompletion)(id <ASImageContainerProtocol> _Nullable imageFromCache);
|
|
|
|
@protocol ASImageCacheProtocol <NSObject>
|
|
|
|
/**
|
|
@abstract Attempts to fetch an image with the given URL from the cache.
|
|
@param URL The URL of the image to retrieve from the cache.
|
|
@param callbackQueue The queue to call `completion` on.
|
|
@param completion The block to be called when the cache has either hit or missed.
|
|
@discussion If `URL` is nil, `completion` will be invoked immediately with a nil image. This method should not block
|
|
the calling thread as it is likely to be called from the main thread.
|
|
*/
|
|
- (void)cachedImageWithURL:(NSURL *)URL
|
|
callbackQueue:(dispatch_queue_t)callbackQueue
|
|
completion:(ASImageCacherCompletion)completion;
|
|
|
|
@optional
|
|
|
|
/**
|
|
@abstract Attempts to fetch an image with the given URL from a memory cache.
|
|
@param URL The URL of the image to retrieve from the cache.
|
|
@discussion This method exists to support synchronous rendering of nodes. Before the layer is drawn, this method
|
|
is called to attempt to get the image out of the cache synchronously. This allows drawing to occur on the main thread
|
|
if displaysAsynchronously is set to NO or recursivelyEnsureDisplaySynchronously: has been called.
|
|
|
|
This method *should* block the calling thread to fetch the image from a fast memory cache. It is OK to return nil from
|
|
this method and instead support only cachedImageWithURL:callbackQueue:completion: however, synchronous rendering will
|
|
not be possible.
|
|
*/
|
|
- (nullable id <ASImageContainerProtocol>)synchronouslyFetchedCachedImageWithURL:(NSURL *)URL;
|
|
|
|
/**
|
|
@abstract Called during clearPreloadedData. Allows the cache to optionally trim items.
|
|
@note Depending on your caches implementation you may *not* wish to respond to this method. It is however useful
|
|
if you have a memory and disk cache in which case you'll likely want to clear out the memory cache.
|
|
*/
|
|
- (void)clearFetchedImageFromCacheWithURL:(NSURL *)URL;
|
|
|
|
@end
|
|
|
|
/**
|
|
@param image The image that was downloaded, if the image could be successfully downloaded; nil otherwise.
|
|
@param error An error describing why the download of `URL` failed, if the download failed; nil otherwise.
|
|
@param downloadIdentifier The identifier for the download task that completed.
|
|
@param userInfo Any additional info that your downloader would like to communicate through Texture.
|
|
*/
|
|
typedef void(^ASImageDownloaderCompletion)(id <ASImageContainerProtocol> _Nullable image, NSError * _Nullable error, id _Nullable downloadIdentifier, id _Nullable userInfo);
|
|
|
|
/**
|
|
@param progress The progress of the download, in the range of (0.0, 1.0), inclusive.
|
|
*/
|
|
typedef void(^ASImageDownloaderProgress)(CGFloat progress);
|
|
typedef void(^ASImageDownloaderProgressImage)(UIImage *progressImage, CGFloat progress, id _Nullable downloadIdentifier);
|
|
|
|
typedef NS_ENUM(NSUInteger, ASImageDownloaderPriority) {
|
|
ASImageDownloaderPriorityPreload = 0,
|
|
ASImageDownloaderPriorityImminent,
|
|
ASImageDownloaderPriorityVisible
|
|
};
|
|
|
|
@protocol ASImageDownloaderProtocol <NSObject>
|
|
|
|
@required
|
|
|
|
/**
|
|
@abstract Downloads an image with the given URL.
|
|
@param URL The URL of the image to download.
|
|
@param callbackQueue The queue to call `downloadProgressBlock` and `completion` on.
|
|
@param downloadProgress The block to be invoked when the download of `URL` progresses.
|
|
@param completion The block to be invoked when the download has completed, or has failed.
|
|
@discussion This method is likely to be called on the main thread, so any custom implementations should make sure to background any expensive download operations.
|
|
@result An opaque identifier to be used in canceling the download, via `cancelImageDownloadForIdentifier:`. You must
|
|
retain the identifier if you wish to use it later.
|
|
*/
|
|
- (nullable id)downloadImageWithURL:(NSURL *)URL
|
|
callbackQueue:(dispatch_queue_t)callbackQueue
|
|
downloadProgress:(nullable ASImageDownloaderProgress)downloadProgress
|
|
completion:(ASImageDownloaderCompletion)completion;
|
|
|
|
/**
|
|
@abstract Cancels an image download.
|
|
@param downloadIdentifier The opaque download identifier object returned from
|
|
`downloadImageWithURL:callbackQueue:downloadProgress:completion:`.
|
|
@discussion This method has no effect if `downloadIdentifier` is nil.
|
|
*/
|
|
- (void)cancelImageDownloadForIdentifier:(id)downloadIdentifier;
|
|
|
|
@optional
|
|
|
|
/**
|
|
@abstract Downloads an image with the given URL.
|
|
@param URL The URL of the image to download.
|
|
@param priority The priority at which the image should be downloaded.
|
|
@param callbackQueue The queue to call `downloadProgressBlock` and `completion` on.
|
|
@param downloadProgress The block to be invoked when the download of `URL` progresses.
|
|
@param completion The block to be invoked when the download has completed, or has failed.
|
|
@discussion This method is likely to be called on the main thread, so any custom implementations should make sure to background any expensive download operations.
|
|
@note If this method is implemented, it will be called instead of the required method (`downloadImageWithURL:callbackQueue:downloadProgress:completion:`).
|
|
@result An opaque identifier to be used in canceling the download, via `cancelImageDownloadForIdentifier:`. You must
|
|
retain the identifier if you wish to use it later.
|
|
*/
|
|
- (nullable id)downloadImageWithURL:(NSURL *)URL
|
|
priority:(ASImageDownloaderPriority)priority
|
|
callbackQueue:(dispatch_queue_t)callbackQueue
|
|
downloadProgress:(nullable ASImageDownloaderProgress)downloadProgress
|
|
completion:(ASImageDownloaderCompletion)completion;
|
|
|
|
/**
|
|
@abstract Cancels an image download, however indicating resume data should be stored in case of redownload.
|
|
@param downloadIdentifier The opaque download identifier object returned from
|
|
`downloadImageWithURL:callbackQueue:downloadProgress:completion:`.
|
|
@discussion This method has no effect if `downloadIdentifier` is nil. If implemented, this method
|
|
may be called instead of `cancelImageDownloadForIdentifier:` in cases where ASDK believes there's a chance
|
|
the image download will be resumed (currently when an image exits preload range). You can use this to store
|
|
any data that has already been downloaded for use in resuming the download later.
|
|
*/
|
|
- (void)cancelImageDownloadWithResumePossibilityForIdentifier:(id)downloadIdentifier;
|
|
|
|
/**
|
|
@abstract Return an object that conforms to ASAnimatedImageProtocol
|
|
@param animatedImageData Data that represents an animated image.
|
|
*/
|
|
- (nullable id <ASAnimatedImageProtocol>)animatedImageWithData:(NSData *)animatedImageData;
|
|
|
|
|
|
/**
|
|
@abstract Sets block to be called when a progress image is available.
|
|
@param progressBlock The block to be invoked when the download has a progressive render of an image available.
|
|
@param callbackQueue The queue to call `progressImageBlock` on.
|
|
@param downloadIdentifier The opaque download identifier object returned from
|
|
`downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:`.
|
|
*/
|
|
- (void)setProgressImageBlock:(nullable ASImageDownloaderProgressImage)progressBlock
|
|
callbackQueue:(dispatch_queue_t)callbackQueue
|
|
withDownloadIdentifier:(id)downloadIdentifier;
|
|
|
|
/**
|
|
@abstract Called to indicate what priority an image should be downloaded at.
|
|
@param priority The priority at which the image should be downloaded.
|
|
@param downloadIdentifier The opaque download identifier object returned from
|
|
`downloadImageWithURL:callbackQueue:downloadProgressBlock:completion:`.
|
|
*/
|
|
- (void)setPriority:(ASImageDownloaderPriority)priority
|
|
withDownloadIdentifier:(id)downloadIdentifier;
|
|
|
|
@end
|
|
|
|
@protocol ASAnimatedImageProtocol <NSObject>
|
|
|
|
@optional
|
|
|
|
/**
|
|
@abstract A block which receives the cover image. Should be called when the objects cover image is ready.
|
|
*/
|
|
@property (nonatomic) void (^coverImageReadyCallback)(UIImage *coverImage);
|
|
|
|
/**
|
|
@abstract Returns whether the supplied data contains a supported animated image format.
|
|
@param data the data to check if contains a supported animated image.
|
|
*/
|
|
- (BOOL)isDataSupported:(NSData *)data;
|
|
|
|
|
|
@required
|
|
|
|
/**
|
|
@abstract Return the objects's cover image.
|
|
*/
|
|
@property (nonatomic, readonly) UIImage *coverImage;
|
|
/**
|
|
@abstract Return a boolean to indicate that the cover image is ready.
|
|
*/
|
|
@property (nonatomic, readonly) BOOL coverImageReady;
|
|
/**
|
|
@abstract Return the total duration of the animated image's playback.
|
|
*/
|
|
@property (nonatomic, readonly) CFTimeInterval totalDuration;
|
|
/**
|
|
@abstract Return the interval at which playback should occur. Will be set to a CADisplayLink's frame interval.
|
|
*/
|
|
@property (nonatomic, readonly) NSUInteger frameInterval;
|
|
/**
|
|
@abstract Return the total number of loops the animated image should play or 0 to loop infinitely.
|
|
*/
|
|
@property (nonatomic, readonly) size_t loopCount;
|
|
/**
|
|
@abstract Return the total number of frames in the animated image.
|
|
*/
|
|
@property (nonatomic, readonly) size_t frameCount;
|
|
/**
|
|
@abstract Return YES when playback is ready to occur.
|
|
*/
|
|
@property (nonatomic, readonly) BOOL playbackReady;
|
|
/**
|
|
@abstract Return any error that has occured. Playback will be paused if this returns non-nil.
|
|
*/
|
|
@property (nonatomic, readonly) NSError *error;
|
|
/**
|
|
@abstract Should be called when playback is ready.
|
|
*/
|
|
@property (nonatomic) dispatch_block_t playbackReadyCallback;
|
|
|
|
/**
|
|
@abstract Return the image at a given index.
|
|
*/
|
|
- (CGImageRef)imageAtIndex:(NSUInteger)index;
|
|
/**
|
|
@abstract Return the duration at a given index.
|
|
*/
|
|
- (CFTimeInterval)durationAtIndex:(NSUInteger)index;
|
|
/**
|
|
@abstract Clear any cached data. Called when playback is paused.
|
|
*/
|
|
- (void)clearAnimatedImageCache;
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|