import UIKit /// Keeps pagination cache key generation and cache IO in one BuildPipeline role. struct RDEPUBPaginationCacheCoordinator { private let cache: RDEPUBTextBookCache? private let layoutConfig: RDEPUBTextLayoutConfig init(cache: RDEPUBTextBookCache?, layoutConfig: RDEPUBTextLayoutConfig) { self.cache = cache self.layoutConfig = layoutConfig } func cacheKey( bookID: String, pageSize: CGSize, style: RDEPUBTextRenderStyle ) -> String? { guard let cache else { return nil } return cache.cacheKey( bookID: bookID, fontSize: style.font.pointSize, lineHeightMultiple: style.lineSpacing, contentInsets: layoutConfig.edgeInsets, pageSize: pageSize, layoutConfigSignature: "\(layoutConfig.cacheSignature)|font=\(style.font.fontName)" ) } func load(key: String?) -> [String: RDEPUBTextChapterPaginationCache]? { key.flatMap { cache?.load(key: $0) } } func save(chapters: [RDEPUBTextChapter], key: String?) { guard let key else { return } let paginationCache = chapters.map { chapter in RDEPUBTextChapterPaginationCache( href: chapter.href, pageRanges: chapter.pages.map(\.contentRange), breakReasons: chapter.pages.map(\.metadata.breakReason), semanticHints: Array(Set(chapter.pages.flatMap(\.metadata.semanticHints))) ) } cache?.save(paginationCache, key: key) } }