Skip to content
This repository has been archived by the owner on Apr 4, 2022. It is now read-only.

Commit

Permalink
Add isAsynchronous option to ImageDecoding
Browse files Browse the repository at this point in the history
  • Loading branch information
kean committed Jun 3, 2021
1 parent 6374195 commit ca3df01
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 30 deletions.
22 changes: 20 additions & 2 deletions Sources/Core/ImageDecoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ import WatchKit
/// - note: If you need additional information in the decoder, you can pass
/// anything that you might need from the `ImageDecodingContext`.
public protocol ImageDecoding {
/// Return `true` if you want the decoding to be performed on the decoding
/// queue (see `imageDecodingQueue`). If `false`, the decoding will be
/// performed synchronously on the pipeline operation queue. By default, `true`.
var isAsynchronous: Bool { get }

/// Produces an image from the given image data.
func decode(_ data: Data) -> ImageContainer?

Expand All @@ -32,10 +37,15 @@ public protocol ImageDecoding {
func decodePartiallyDownloadedData(_ data: Data) -> ImageContainer?
}

public extension ImageDecoding {
extension ImageDecoding {
/// Returns `true` by default.
public var isAsynchronous: Bool {
true
}

/// The default implementation which simply returns `nil` (no progressive
/// decoding available).
func decodePartiallyDownloadedData(_ data: Data) -> ImageContainer? {
public func decodePartiallyDownloadedData(_ data: Data) -> ImageContainer? {
nil
}
}
Expand Down Expand Up @@ -85,6 +95,10 @@ extension ImageDecoders {

public init() { }

public var isAsynchronous: Bool {
false
}

public init?(data: Data, context: ImageDecodingContext) {
guard let container = _decode(data) else {
return nil
Expand Down Expand Up @@ -201,6 +215,10 @@ extension ImageDecoders {
public struct Empty: ImageDecoding {
public let isProgressive: Bool

public var isAsynchronous: Bool {
false
}

/// - parameter isProgressive: If `false`, returns nil for every progressive
/// scan. `false` by default.
public init(isProgressive: Bool = false) {
Expand Down
11 changes: 0 additions & 11 deletions Sources/Core/ImagePipelineConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,6 @@ extension ImagePipeline {
}
}

static var isFastTrackDecodingEnabled = true

private var isCustomImageCacheProvided = false

var debugIsSyncImageEncoding = false
Expand Down Expand Up @@ -242,12 +240,3 @@ extension ImagePipeline {
}
}
}

// MARK: - Helpers

extension ImagePipeline.Configuration {
/// Fast-track decoding isn't performed on the operation queue.
static func isFastTrackDecodingEnabled(for decoder: ImageDecoding) -> Bool {
isFastTrackDecodingEnabled && (decoder is ImageDecoders.Default || decoder is ImageDecoders.Empty)
}
}
2 changes: 1 addition & 1 deletion Sources/Internal/Tasks/TaskFetchDecodedImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class TaskFetchDecodedImage: ImagePipelineTask<ImageResponse> {
decoder.decode(data, urlResponse: urlResponse, isCompleted: isCompleted, cacheType: nil)
}
}
if ImagePipeline.Configuration.isFastTrackDecodingEnabled(for: decoder) {
if !decoder.isAsynchronous {
self.sendResponse(decode(), isCompleted: isCompleted)
} else {
operation = pipeline.configuration.imageDecodingQueue.add { [weak self] in
Expand Down
2 changes: 1 addition & 1 deletion Sources/Internal/Tasks/TaskLoadImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ final class TaskLoadImage: ImagePipelineTask<ImageResponse> {
decoder.decode(data, urlResponse: nil, isCompleted: true, cacheType: .disk)
}
}
if ImagePipeline.Configuration.isFastTrackDecodingEnabled(for: decoder) {
if !decoder.isAsynchronous {
didDecodeCachedData(decode())
} else {
operation = pipeline.configuration.imageDecodingQueue.add { [weak self] in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@ class ImagePipelineProgressiveDecodingTests: XCTestCase {
$0.isStoringPreviewsInMemoryCache = true
$0.imageProcessingQueue.maxConcurrentOperationCount = 1
}

ImagePipeline.Configuration.isFastTrackDecodingEnabled = false
}

override func tearDown() {
ImagePipeline.Configuration.isFastTrackDecodingEnabled = true
}

// MARK: - Basics
Expand Down Expand Up @@ -288,6 +282,11 @@ class ImagePipelineProgressiveDecodingTests: XCTestCase {
// MARK: Back Pressure

func testBackpressureImageDecoding() {
// GIVEN
pipeline = pipeline.reconfigured {
$0.makeImageDecoder = { _ in MockImageDecoder(name: "a") }
}

let queue = pipeline.configuration.imageDecodingQueue

// When we receive progressive image data at a higher rate that we can
Expand Down
16 changes: 9 additions & 7 deletions Tests/ImagePipelineTests/ImagePipelineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ class ImagePipelineTests: XCTestCase {
$0.dataLoader = dataLoader
$0.imageCache = nil
}

ImagePipeline.Configuration.isFastTrackDecodingEnabled = false
}

override func tearDown() {
ImagePipeline.Configuration.isFastTrackDecodingEnabled = true
}

// MARK: - Completion
Expand Down Expand Up @@ -185,6 +179,10 @@ class ImagePipelineTests: XCTestCase {

func testDecodingPriorityUpdated() {
// Given
pipeline = pipeline.reconfigured {
$0.makeImageDecoder = { _ in MockImageDecoder(name: "test") }
}

let queue = pipeline.configuration.imageDecodingQueue
queue.isSuspended = true

Expand Down Expand Up @@ -246,7 +244,11 @@ class ImagePipelineTests: XCTestCase {
}

func testDecodingOperationCancelled() {
// Given
// GIVEN
pipeline = pipeline.reconfigured {
$0.makeImageDecoder = { _ in MockImageDecoder(name: "test") }
}

let queue = pipeline.configuration.imageDecodingQueue
queue.isSuspended = true

Expand Down
5 changes: 3 additions & 2 deletions Tests/MemoryManagementTests/ImagePipelineMemoryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ class ImagePipelineMemoryTests: XCTestCase {

func testDecodingOperationCancelled() {
expectDeinit {
ImagePipeline.Configuration.isFastTrackDecodingEnabled = false
defer { ImagePipeline.Configuration.isFastTrackDecodingEnabled = true }
pipeline = pipeline.reconfigured {
$0.makeImageDecoder = { _ in MockImageDecoder(name: "test") }
}

// Given
let queue = pipeline.configuration.imageDecodingQueue
Expand Down

0 comments on commit ca3df01

Please sign in to comment.