Merge pull request #55 from YusukeHosonuma/improve/render-performance

improve: use cache for thumbnail image
This commit is contained in:
Yusuke Hosonuma
2020-08-12 19:57:10 +09:00
committed by GitHub
5 changed files with 66 additions and 6 deletions
+16
View File
@@ -43,6 +43,9 @@
E5438E4524E2ACD4007A3EB7 /* BoardThumbnailImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E6EB1524DFF33E0012E911 /* BoardThumbnailImage.swift */; };
E5438E4724E2AD1D007A3EB7 /* BoardPreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5FA934B24C07A5500229AAA /* BoardPreset.swift */; };
E5438E4924E2ADE3007A3EB7 /* LifeGame in Frameworks */ = {isa = PBXBuildFile; productRef = E5438E4824E2ADE3007A3EB7 /* LifeGame */; };
E547C30A24E3F4CF0022DF3A /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E547C30924E3F4CF0022DF3A /* MemoryStorage.swift */; };
E547C30B24E3F4CF0022DF3A /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E547C30924E3F4CF0022DF3A /* MemoryStorage.swift */; };
E547C30C24E3F7710022DF3A /* MemoryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E547C30924E3F4CF0022DF3A /* MemoryStorage.swift */; };
E54904AD24DD5DF0003AE7C7 /* MainGameViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5BA30B724BF05BC002D0564 /* MainGameViewModel.swift */; };
E54904AF24DD5E2D003AE7C7 /* BoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E54904AE24DD5E2D003AE7C7 /* BoardView.swift */; };
E54904B024DD5E2D003AE7C7 /* BoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E54904AE24DD5E2D003AE7C7 /* BoardView.swift */; };
@@ -170,6 +173,7 @@
E5438E3924E2AB0B007A3EB7 /* LifeGameWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LifeGameWidget.swift; sourceTree = "<group>"; };
E5438E3B24E2AB0D007A3EB7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
E5438E3D24E2AB0D007A3EB7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E547C30924E3F4CF0022DF3A /* MemoryStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryStorage.swift; sourceTree = "<group>"; };
E54904AE24DD5E2D003AE7C7 /* BoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoardView.swift; sourceTree = "<group>"; };
E54B7AF024DB0043005E1B55 /* HeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderView.swift; sourceTree = "<group>"; };
E558A97224DB70D00012E443 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
@@ -322,6 +326,14 @@
path = Shared;
sourceTree = "<group>";
};
E547C30824E3F4AA0022DF3A /* Cache */ = {
isa = PBXGroup;
children = (
E547C30924E3F4CF0022DF3A /* MemoryStorage.swift */,
);
path = Cache;
sourceTree = "<group>";
};
E54904AB24DD5D6F003AE7C7 /* BoardSelect */ = {
isa = PBXGroup;
children = (
@@ -588,6 +600,7 @@
E5FA934A24C07A3D00229AAA /* Model */ = {
isa = PBXGroup;
children = (
E547C30824E3F4AA0022DF3A /* Cache */,
E52FE5DB24DC00E100D93764 /* Firestore */,
E5FA934B24C07A5500229AAA /* BoardPreset.swift */,
E5CE237224C199F200BC5820 /* LifeGameContext.swift */,
@@ -931,6 +944,7 @@
E5438E3A24E2AB0B007A3EB7 /* LifeGameWidget.swift in Sources */,
E518C89824E3690600B02027 /* Color+.swift in Sources */,
E56A422824E2BB6800F9AC24 /* BoardDocument.swift in Sources */,
E547C30C24E3F7710022DF3A /* MemoryStorage.swift in Sources */,
E518C89624E368A700B02027 /* UserDefaultGroup.swift in Sources */,
E5438E4724E2AD1D007A3EB7 /* BoardPreset.swift in Sources */,
E5438E4524E2ACD4007A3EB7 /* BoardThumbnailImage.swift in Sources */,
@@ -967,6 +981,7 @@
E507EBEE24CC1106002A6EC4 /* SettingView.swift in Sources */,
E54B7AF124DB0043005E1B55 /* HeaderView.swift in Sources */,
E5BA30B824BF05BC002D0564 /* MainGameViewModel.swift in Sources */,
E547C30A24E3F4CF0022DF3A /* MemoryStorage.swift in Sources */,
E5D9F27324BEBDBD009A526B /* Application.swift in Sources */,
E5B0572824CC3465005EE1AA /* CellView.swift in Sources */,
E5FA935024C07AE300229AAA /* Collection+.swift in Sources */,
@@ -1013,6 +1028,7 @@
E571536A24D51B9F003B4C9E /* UserDefault.swift in Sources */,
E5CE237424C199F200BC5820 /* LifeGameContext.swift in Sources */,
E55F7AA824DD0D9300DBC175 /* ContentView.swift in Sources */,
E547C30B24E3F4CF0022DF3A /* MemoryStorage.swift in Sources */,
E5604AA124CC3ED600EA59C3 /* PreferenceView.swift in Sources */,
E573BD8224D053F90096BF75 /* LifeGameCommands.swift in Sources */,
E518C89424E3684A00B02027 /* UserDefaultSettingGroup.swift in Sources */,
+5 -2
View File
@@ -41,7 +41,9 @@ struct Provider: TimelineProvider {
//
let document = documents.randomElement()!
let data = LifeGameData(title: document.title, board: document.makeBoard().extended(by: .die), url: URL(string: "board:///\(document.id!)")!)
let data = LifeGameData(title: document.title,
board: document.makeBoard().extended(by: .die),
url: URL(string: "board:///\(document.id!)")!, cacheKey: document.id!)
let entry = LifeGameEntry(date: entryDate, relevance: data)
entries.append(entry)
}
@@ -61,6 +63,7 @@ struct LifeGameData {
var title: String
var board: Board<Cell>
var url: URL = URL(string: "board:///0")!
var cacheKey: String?
}
struct LifeGameWidgetEntryView : View {
@@ -71,7 +74,7 @@ struct LifeGameWidgetEntryView : View {
var body: some View {
HStack {
VStack(alignment: .leading) {
BoardThumbnailImage(board: entry.relevance.board, cellColor: cellColor)
BoardThumbnailImage(board: entry.relevance.board, cellColor: cellColor, cacheKey: entry.relevance.cacheKey)
Text(entry.relevance.title)
.font(.system(.footnote, design: .monospaced))
.foregroundColor(.gray)
+24
View File
@@ -0,0 +1,24 @@
//
// MemoryStorage.swift
// LifeGameApp
//
// Created by Yusuke Hosonuma on 2020/08/12.
//
import Foundation
import UIKit
final class ThumbnailImageCacheStorage {
static var shared = ThumbnailImageCacheStorage()
private let cache = NSCache<NSString, UIImage>()
func store(key: String, image: UIImage) {
cache.setObject(image, forKey: key as NSString)
}
func value(forKey key: String) -> UIImage? {
guard let value = cache.object(forKey: key as NSString) else { return nil }
return value
}
}
+2 -2
View File
@@ -18,7 +18,7 @@ struct BoardSelectCell: View {
switch style {
case .grid:
VStack {
BoardThumbnailImage(board: item.makeBoard().extended(by: .die))
BoardThumbnailImage(board: item.makeBoard().extended(by: .die), cacheKey: item.id)
.matchedGeometryEffect(id: "thumbnail-\(item.title)", in: nspace)
HStack {
@@ -54,7 +54,7 @@ struct BoardSelectCell: View {
.foregroundColor(.yellow)
}
Spacer()
BoardThumbnailImage(board: item.makeBoard().extended(by: .die))
BoardThumbnailImage(board: item.makeBoard().extended(by: .die), cacheKey: item.id)
.frame(width: 60, height: 60, alignment: .center)
.matchedGeometryEffect(id: "thumbnail-\(item.title)", in: nspace)
}.padding()
+19 -2
View File
@@ -13,6 +13,9 @@ struct BoardThumbnailImage: View {
var board: Board<Cell>
var cellColor: Color?
var cacheKey: String?
private let cacheStorage = ThumbnailImageCacheStorage.shared
var body: some View {
Image(uiImage: thumbnailImage)
@@ -38,7 +41,21 @@ struct BoardThumbnailImage: View {
}
private var thumbnailImage: UIImage {
let scale = max(2, 200 / board.size)
guard let key = cacheKey else {
return renderImage()
}
if let image = cacheStorage.value(forKey: key) {
return image
} else {
let image = renderImage()
cacheStorage.store(key: key, image: image)
return image
}
}
private func renderImage() -> UIImage {
let scale = max(2, 140 / board.size)
let size = CGSize(width: board.size * scale + 1, height: board.size * scale + 1)
return UIGraphicsImageRenderer(size: size)
@@ -70,7 +87,7 @@ struct BoardThumnailImage_Previews: PreviewProvider {
view(preset: .nebura, colorScheme: .light)
view(preset: .spaceShip, colorScheme: .dark)
}
static func view(preset: BoardPreset, colorScheme: ColorScheme) -> some View {
BoardThumbnailImage(board: preset.board.board)
.previewLayout(.fixed(width: 200.0, height: 200.0))