Refactors loading operations to inherit from Roxas’ RSTLoadOperation
This commit is contained in:
parent
882c6e74e6
commit
54da484423
@ -47,7 +47,6 @@
|
||||
BF3540081C5DAFAD00C1184C /* PauseTransitionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540071C5DAFAD00C1184C /* PauseTransitionCoordinator.swift */; };
|
||||
BF59425C1E09BB810051894B /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5942581E09BB810051894B /* Action.swift */; };
|
||||
BF5942641E09BBB10051894B /* LoadControllerSkinImageOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5942611E09BBB10051894B /* LoadControllerSkinImageOperation.swift */; };
|
||||
BF5942651E09BBB10051894B /* LoadImageOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5942621E09BBB10051894B /* LoadImageOperation.swift */; };
|
||||
BF5942661E09BBB10051894B /* LoadImageURLOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5942631E09BBB10051894B /* LoadImageURLOperation.swift */; };
|
||||
BF59426A1E09BBD00051894B /* GridCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5942681E09BBD00051894B /* GridCollectionViewCell.swift */; };
|
||||
BF59426B1E09BBD00051894B /* GridCollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5942691E09BBD00051894B /* GridCollectionViewLayout.swift */; };
|
||||
@ -153,7 +152,6 @@
|
||||
BF3540071C5DAFAD00C1184C /* PauseTransitionCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PauseTransitionCoordinator.swift; path = "Pause Menu/Segues/PauseTransitionCoordinator.swift"; sourceTree = "<group>"; };
|
||||
BF5942581E09BB810051894B /* Action.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Action.swift; path = Components/Action.swift; sourceTree = "<group>"; };
|
||||
BF5942611E09BBB10051894B /* LoadControllerSkinImageOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LoadControllerSkinImageOperation.swift; path = Components/Loading/LoadControllerSkinImageOperation.swift; sourceTree = "<group>"; };
|
||||
BF5942621E09BBB10051894B /* LoadImageOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LoadImageOperation.swift; path = Components/Loading/LoadImageOperation.swift; sourceTree = "<group>"; };
|
||||
BF5942631E09BBB10051894B /* LoadImageURLOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LoadImageURLOperation.swift; path = Components/Loading/LoadImageURLOperation.swift; sourceTree = "<group>"; };
|
||||
BF5942681E09BBD00051894B /* GridCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GridCollectionViewCell.swift; path = "Components/Collection View/GridCollectionViewCell.swift"; sourceTree = "<group>"; };
|
||||
BF5942691E09BBD00051894B /* GridCollectionViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GridCollectionViewLayout.swift; path = "Components/Collection View/GridCollectionViewLayout.swift"; sourceTree = "<group>"; };
|
||||
@ -306,9 +304,8 @@
|
||||
BF5942601E09BBA80051894B /* Loading */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF5942611E09BBB10051894B /* LoadControllerSkinImageOperation.swift */,
|
||||
BF5942621E09BBB10051894B /* LoadImageOperation.swift */,
|
||||
BF5942631E09BBB10051894B /* LoadImageURLOperation.swift */,
|
||||
BF5942611E09BBB10051894B /* LoadControllerSkinImageOperation.swift */,
|
||||
);
|
||||
name = Loading;
|
||||
sourceTree = "<group>";
|
||||
@ -752,7 +749,6 @@
|
||||
BF13A7561D5D29B0000BB055 /* PreviewGameViewController.swift in Sources */,
|
||||
BF6866171DCAC8B900BF2D06 /* ControllerSkin+Configuring.swift in Sources */,
|
||||
BF59427D1E09BC830051894B /* ControllerSkin.swift in Sources */,
|
||||
BF5942651E09BBB10051894B /* LoadImageOperation.swift in Sources */,
|
||||
BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */,
|
||||
BF1173501DA32CF600047DF8 /* ControllersSettingsViewController.swift in Sources */,
|
||||
BFFC461E1D59823500AF2CC6 /* GamesPresentationController.swift in Sources */,
|
||||
|
||||
@ -10,6 +10,17 @@ import UIKit
|
||||
|
||||
import DeltaCore
|
||||
|
||||
import Roxas
|
||||
|
||||
extension LoadControllerSkinImageOperation
|
||||
{
|
||||
enum Error: Swift.Error
|
||||
{
|
||||
case doesNotExist
|
||||
case unsupportedTraits
|
||||
}
|
||||
}
|
||||
|
||||
class ControllerSkinImageCacheKey: NSObject
|
||||
{
|
||||
let controllerSkin: ControllerSkin
|
||||
@ -36,7 +47,7 @@ class ControllerSkinImageCacheKey: NSObject
|
||||
}
|
||||
}
|
||||
|
||||
class LoadControllerSkinImageOperation: LoadImageOperation<ControllerSkinImageCacheKey>
|
||||
class LoadControllerSkinImageOperation: RSTLoadOperation<UIImage, ControllerSkinImageCacheKey>
|
||||
{
|
||||
let controllerSkin: ControllerSkin
|
||||
let traits: DeltaCore.ControllerSkin.Traits
|
||||
@ -52,9 +63,23 @@ class LoadControllerSkinImageOperation: LoadImageOperation<ControllerSkinImageCa
|
||||
super.init(cacheKey: cacheKey)
|
||||
}
|
||||
|
||||
override func loadImage() -> UIImage?
|
||||
override func loadResult(completion: @escaping (UIImage?, Swift.Error?) -> Void)
|
||||
{
|
||||
let image = self.controllerSkin.image(for: self.traits, preferredSize: self.size)
|
||||
return image
|
||||
guard self.controllerSkin.supports(self.traits) else {
|
||||
completion(nil, Error.unsupportedTraits)
|
||||
return
|
||||
}
|
||||
|
||||
guard let image = self.controllerSkin.image(for: self.traits, preferredSize: self.size) else {
|
||||
completion(nil, Error.doesNotExist)
|
||||
return
|
||||
}
|
||||
|
||||
// Force decompression of image
|
||||
UIGraphicsBeginImageContextWithOptions(CGSize(width: 1, height: 1), true, 1.0)
|
||||
image.draw(at: CGPoint.zero)
|
||||
UIGraphicsEndImageContext()
|
||||
|
||||
completion(image, nil)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,69 +0,0 @@
|
||||
//
|
||||
// LoadImageOperation.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 2/26/16.
|
||||
// Copyright © 2016 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ImageIO
|
||||
|
||||
import Roxas
|
||||
|
||||
class LoadImageOperation<CacheKeyType: AnyObject>: RSTOperation
|
||||
{
|
||||
var completionHandler: ((UIImage?) -> Void)? {
|
||||
didSet {
|
||||
self.completionBlock = {
|
||||
rst_dispatch_sync_on_main_thread() {
|
||||
self.completionHandler?(self.image)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var imageCache: NSCache<CacheKeyType, UIImage>? {
|
||||
didSet {
|
||||
// Ensures if an image is cached, it will be returned immediately, to prevent temporary flash of placeholder image
|
||||
self.isImmediate = self.imageCache?.object(forKey: self.cacheKey) != nil
|
||||
}
|
||||
}
|
||||
|
||||
private let cacheKey: CacheKeyType
|
||||
private var image: UIImage?
|
||||
|
||||
init(cacheKey: CacheKeyType)
|
||||
{
|
||||
self.cacheKey = cacheKey
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
override func main()
|
||||
{
|
||||
guard !self.isCancelled else { return }
|
||||
|
||||
if let cachedImage = self.imageCache?.object(forKey: self.cacheKey)
|
||||
{
|
||||
self.image = cachedImage
|
||||
return
|
||||
}
|
||||
|
||||
guard let loadedImage = self.loadImage() else { return }
|
||||
|
||||
// Force decompression of image
|
||||
UIGraphicsBeginImageContextWithOptions(CGSize(width: 1, height: 1), true, 1.0)
|
||||
loadedImage.draw(at: CGPoint.zero)
|
||||
UIGraphicsEndImageContext()
|
||||
|
||||
self.imageCache?.setObject(loadedImage, forKey: self.cacheKey)
|
||||
|
||||
self.image = loadedImage
|
||||
}
|
||||
|
||||
func loadImage() -> UIImage?
|
||||
{
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -9,25 +9,100 @@
|
||||
import UIKit
|
||||
import ImageIO
|
||||
|
||||
import SDWebImage
|
||||
|
||||
import Roxas
|
||||
|
||||
class LoadImageURLOperation: LoadImageOperation<NSURL>
|
||||
extension LoadImageURLOperation
|
||||
{
|
||||
public let url: URL
|
||||
enum Error: Swift.Error
|
||||
{
|
||||
case doesNotExist
|
||||
case invalid
|
||||
case downloadFailed(Swift.Error)
|
||||
}
|
||||
}
|
||||
|
||||
class LoadImageURLOperation: RSTLoadOperation<UIImage, NSURL>
|
||||
{
|
||||
let url: URL
|
||||
|
||||
override var isAsynchronous: Bool {
|
||||
return !self.url.isFileURL
|
||||
}
|
||||
|
||||
private var downloadOperation: SDWebImageOperation?
|
||||
|
||||
init(url: URL)
|
||||
{
|
||||
self.url = url
|
||||
|
||||
super.init(cacheKey: url as NSURL)
|
||||
}
|
||||
|
||||
override func loadImage() -> UIImage?
|
||||
override func cancel()
|
||||
{
|
||||
super.cancel()
|
||||
|
||||
self.downloadOperation?.cancel()
|
||||
}
|
||||
|
||||
override func loadResult(completion: @escaping (UIImage?, Swift.Error?) -> Void)
|
||||
{
|
||||
let callback = { (image: UIImage?, error: Error?) in
|
||||
|
||||
if let image = image, !self.isCancelled
|
||||
{
|
||||
// Force decompression of image
|
||||
UIGraphicsBeginImageContextWithOptions(CGSize(width: 1, height: 1), true, 1.0)
|
||||
image.draw(at: CGPoint.zero)
|
||||
UIGraphicsEndImageContext()
|
||||
}
|
||||
|
||||
completion(image, error)
|
||||
}
|
||||
|
||||
if self.url.isFileURL
|
||||
{
|
||||
self.loadLocalImage(completion: callback)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.loadRemoteImage(completion: callback)
|
||||
}
|
||||
}
|
||||
|
||||
private func loadLocalImage(completion: @escaping (UIImage?, Error?) -> Void)
|
||||
{
|
||||
let options: NSDictionary = [kCGImageSourceShouldCache as NSString: true]
|
||||
|
||||
guard let imageSource = CGImageSourceCreateWithURL(self.url as CFURL, options), let quartzImage = CGImageSourceCreateImageAtIndex(imageSource, 0, options) else { return nil }
|
||||
guard let imageSource = CGImageSourceCreateWithURL(self.url as CFURL, options) else {
|
||||
completion(nil, .doesNotExist)
|
||||
return
|
||||
}
|
||||
|
||||
guard let quartzImage = CGImageSourceCreateImageAtIndex(imageSource, 0, options) else {
|
||||
completion(nil, .invalid)
|
||||
return
|
||||
}
|
||||
|
||||
let image = UIImage(cgImage: quartzImage)
|
||||
return image
|
||||
completion(image, nil)
|
||||
}
|
||||
|
||||
private func loadRemoteImage(completion: @escaping (UIImage?, Error?) -> Void)
|
||||
{
|
||||
let manager = SDWebImageManager.shared()
|
||||
|
||||
self.downloadOperation = manager?.downloadImage(with: self.url, options: [.retryFailed, .continueInBackground], progress: nil, completed: { (image, error, cacheType, finished, imageURL) in
|
||||
if let error = error
|
||||
{
|
||||
completion(nil, .downloadFailed(error))
|
||||
}
|
||||
else
|
||||
{
|
||||
completion(image, nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,8 +236,8 @@ private extension SaveStatesViewController
|
||||
if !ignoreOperations
|
||||
{
|
||||
let imageOperation = LoadImageURLOperation(url: saveState.imageFileURL)
|
||||
imageOperation.imageCache = self.imageCache
|
||||
imageOperation.completionHandler = { image in
|
||||
imageOperation.resultsCache = self.imageCache
|
||||
imageOperation.resultHandler = { (image, error) in
|
||||
|
||||
if let image = image
|
||||
{
|
||||
|
||||
@ -95,8 +95,8 @@ private extension ControllerSkinsViewController
|
||||
let size = UIScreen.main.defaultControllerSkinSize
|
||||
|
||||
let imageOperation = LoadControllerSkinImageOperation(controllerSkin: controllerSkin, traits: self.traits, size: size)
|
||||
imageOperation.imageCache = self.imageCache
|
||||
imageOperation.completionHandler = { image in
|
||||
imageOperation.resultsCache = self.imageCache
|
||||
imageOperation.resultHandler = { (image, error) in
|
||||
|
||||
guard let image = image else { return }
|
||||
|
||||
@ -159,7 +159,7 @@ extension ControllerSkinsViewController: UITableViewDataSourcePrefetching
|
||||
let size = UIScreen.main.defaultControllerSkinSize
|
||||
|
||||
let imageOperation = LoadControllerSkinImageOperation(controllerSkin: controllerSkin, traits: self.traits, size: size)
|
||||
imageOperation.imageCache = self.imageCache
|
||||
imageOperation.resultsCache = self.imageCache
|
||||
|
||||
self.imageOperationQueue.addOperation(imageOperation, forKey: indexPath as NSCopying)
|
||||
}
|
||||
|
||||
2
External/Roxas
vendored
2
External/Roxas
vendored
@ -1 +1 @@
|
||||
Subproject commit ecb29e0050fe9335845698c896c4cd8ce60df0da
|
||||
Subproject commit 0057bde6337f90b5747eec1baf94a1360e78c23e
|
||||
Loading…
Reference in New Issue
Block a user