Three plans for Phase 8 (分页质量、缓存与性能采样): - 08-01: Pagination cache key struct and manager stub (QUAL-01) - 08-02: Unified 1080x1920 max-size constraint for all images, footnote width-only sizing (QUAL-02, QUAL-03, QUAL-04) - 08-03: Pagination timing instrumentation with [EPUB][Perf] diagnostic output (QUAL-04) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
123 lines
5.6 KiB
Markdown
123 lines
5.6 KiB
Markdown
---
|
|
phase: 08-pagination-quality-cache-performance
|
|
plan: 01
|
|
type: execute
|
|
wave: 1
|
|
depends_on: []
|
|
files_modified:
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift
|
|
autonomous: true
|
|
requirements:
|
|
- QUAL-01
|
|
must_haves:
|
|
truths:
|
|
- "Cache key struct exists that captures viewport + typography configuration"
|
|
- "Cache lookup and store methods exist on the cache type"
|
|
- "Build succeeds with new cache file in project"
|
|
artifacts:
|
|
- path: "Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift"
|
|
provides: "Cache key struct and cache manager stub"
|
|
exports: ["RDEPUBTextRendererCache", "RDEPUBPaginationCacheKey"]
|
|
key_links:
|
|
- from: "Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift"
|
|
to: "RDEPUBDTCoreTextRenderer"
|
|
via: "import (future wiring)"
|
|
pattern: "RDEPUBTextRendererCache"
|
|
---
|
|
|
|
<objective>
|
|
Create the pagination cache infrastructure: a cache key struct that captures viewport dimensions and typography configuration, plus a cache manager stub with lookup/store/invalidate methods. This is the structural foundation that plan 08-02 and future work will wire into the actual rendering pipeline.
|
|
|
|
Purpose: Prevents the same chapter from being fully re-typeset when viewport and typography config haven't changed (QUAL-01).
|
|
|
|
Output: `RDEPUBTextRendererCache.swift` with cache key struct and manager stub.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
@.planning/phases/08-pagination-quality-cache-performance/08-CONTEXT.md
|
|
@.planning/phases/08-pagination-quality-cache-performance/08-RESEARCH.md
|
|
|
|
<interfaces>
|
|
<!-- Existing types the executor needs to know about -->
|
|
|
|
From Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift:
|
|
- `RDEPUBTextChapterRenderRequest` — contains `style: RDEPUBTextRenderStyle`, `context` with baseURL
|
|
- `RDEPUBTextRenderStyle` — has `font: UIFont`, `lineSpacing: CGFloat`, `textColor: UIColor?`, `backgroundColor: UIColor?`
|
|
|
|
From Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift:
|
|
- `RDEPUBTextRenderStyle` properties used in rendering: `font.pointSize`, `font.familyName`, `font.fontName`, `lineSpacing`
|
|
</interfaces>
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Create cache key struct and cache manager stub</name>
|
|
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift</files>
|
|
<read_first>
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift (understand render request and style types)
|
|
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift (understand what configuration affects pagination output)
|
|
</read_first>
|
|
<action>
|
|
Create `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift` with:
|
|
|
|
1. `RDEPUBPaginationCacheKey` struct — captures the inputs that determine pagination output:
|
|
- `chapterID: String` (unique chapter identifier, e.g. href or file path)
|
|
- `viewportSize: CGSize` (the available page dimensions)
|
|
- `fontDescriptor: String` (font family + name + pointSize, concatenated)
|
|
- `lineSpacing: CGFloat`
|
|
- `textColorHash: Int?` (hash of textColor, if present)
|
|
- Implement `Equatable` conformance (auto-synthesize is fine)
|
|
|
|
2. `RDEPUBTextRendererCache` class:
|
|
- `static let shared = RDEPUBTextRendererCache()`
|
|
- `private var cache: [RDEPUBPaginationCacheKey: [NSAttributedString]]` — maps key to array of page attributed strings
|
|
- `func cachedPages(for key: RDEPUBPaginationCacheKey) -> [NSAttributedString]?` — returns cached pages or nil
|
|
- `func store(pages: [NSAttributedString], for key: RDEPUBPaginationCacheKey)` — stores pages
|
|
- `func invalidate(for key: RDEPUBPaginationCacheKey)` — removes a specific entry
|
|
- `func invalidateAll()` — clears entire cache
|
|
- `var entryCount: Int` — read-only count of cached entries (for diagnostics)
|
|
|
|
Make the class `final` and `Sendable`-safe (use a lock or `@MainActor` annotation since rendering is main-thread). Use `NSLock` for thread safety.
|
|
|
|
Do NOT wire this cache into the rendering pipeline yet — that is future work. This plan only creates the infrastructure.
|
|
</action>
|
|
<verify>
|
|
<automated>xcodebuild build -project ReadViewDemo/ReadViewDemo.xcodeproj -scheme ReadViewDemo -destination 'platform=iOS Simulator,name=iPhone 16' 2>&1 | tail -5</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift` exists
|
|
- File contains `struct RDEPUBPaginationCacheKey: Equatable` with properties: chapterID, viewportSize, fontDescriptor, lineSpacing, textColorHash
|
|
- File contains `final class RDEPUBTextRendererCache` with static `shared` instance
|
|
- Class has methods: `cachedPages(for:)`, `store(pages:for:)`, `invalidate(for:)`, `invalidateAll()`
|
|
- Class has computed property `entryCount: Int`
|
|
- Build succeeds (xcodebuild exits 0)
|
|
</acceptance_criteria>
|
|
<done>Cache key struct and cache manager stub exist, build compiles successfully</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
- Build succeeds with new file
|
|
- Cache types are properly defined and accessible from other modules in the same target
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- RDEPUBPaginationCacheKey captures all inputs that affect pagination output
|
|
- RDEPUBTextRendererCache provides a thread-safe, singleton cache surface ready for wiring
|
|
- No existing code is modified — this is purely additive
|
|
</success_criteria>
|
|
|
|
<output>
|
|
Create `.planning/phases/08-pagination-quality-cache-performance/08-01-SUMMARY.md` when done
|
|
</output>
|