// // StatusContentCacheService.swift // Mastodon // // Created by MainasuK Cirno on 2021-6-17. // import UIKit import Combine final class StatusContentCacheService { var disposeBag = Set() let cache = NSCache() let workingQueue = DispatchQueue(label: "org.joinmastodon.app.BlurhashImageCacheService.working-queue", qos: .userInitiated, attributes: .concurrent) func parseResult(content: String, emojiDict: MastodonStatusContent.EmojiDict) -> MastodonStatusContent.ParseResult? { let key = Key(content: content, emojiDict: emojiDict) return cache.object(forKey: key)?.parseResult } func prefetch(content: String, emojiDict: MastodonStatusContent.EmojiDict) { let key = Key(content: content, emojiDict: emojiDict) guard cache.object(forKey: key) == nil else { return } MastodonStatusContent.parseResult(content: content, emojiDict: emojiDict) .sink { [weak self] parseResult in guard let self = self else { return } guard let parseResult = parseResult else { return } let wrapper = ParseResultWrapper(parseResult: parseResult) self.cache.setObject(wrapper, forKey: key) } .store(in: &disposeBag) } } extension StatusContentCacheService { class Key: NSObject { let content: String let emojiDict: MastodonStatusContent.EmojiDict init(content: String, emojiDict: MastodonStatusContent.EmojiDict) { self.content = content self.emojiDict = emojiDict } override func isEqual(_ object: Any?) -> Bool { guard let object = object as? Key else { return false } return object.content == content && object.emojiDict == emojiDict } override var hash: Int { return content.hashValue ^ emojiDict.hashValue } } class ParseResultWrapper: NSObject { let parseResult: MastodonStatusContent.ParseResult init(parseResult: MastodonStatusContent.ParseResult) { self.parseResult = parseResult } override func isEqual(_ object: Any?) -> Bool { guard let object = object as? ParseResultWrapper else { return false } return object.parseResult == parseResult } override var hash: Int { return parseResult.hashValue } } }