Remove all RDEPUBBackgroundTrace.log and bare print diagnostic calls
Keep only the evaluateFullPageMapTakeover: fullReplace diagnostic log in RDEPUBPageMapReconciliationCoordinator.swift for future debugging. Simplified RDEPUBBackgroundTrace to just the log method (removed measure and debug gating). Removed all [EPUB][...], [ReadViewDemo], and [EPUB][Pagination] print statements across the project. Also includes earlier bug fixes: - Fix stale currentPageNumber in extendPartial commit - Fix pageCurl rebindVisiblePage during transition - Fix keepCurrentWindow not removing pending update from queue - Fix right-aligned text (巫鸿 bug) via avoidPageBreakInside, tail merger, and continuation paragraph normalization - Add text-indent reset for aligned blocks in CSS compatibility layer Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8c5059e72f
commit
15b15d0e11
@ -199,6 +199,8 @@ public struct RDEPUBBookmark: Codable, Equatable {
|
||||
|
||||
public var location: RDEPUBLocation
|
||||
|
||||
public var rangeInfo: String?
|
||||
|
||||
public var chapterTitle: String?
|
||||
|
||||
public var note: String?
|
||||
@ -209,6 +211,7 @@ public struct RDEPUBBookmark: Codable, Equatable {
|
||||
id: String = UUID().uuidString,
|
||||
bookIdentifier: String? = nil,
|
||||
location: RDEPUBLocation,
|
||||
rangeInfo: String? = nil,
|
||||
chapterTitle: String? = nil,
|
||||
note: String? = nil,
|
||||
createdAt: Date = Date()
|
||||
@ -216,6 +219,7 @@ public struct RDEPUBBookmark: Codable, Equatable {
|
||||
self.id = id
|
||||
self.bookIdentifier = bookIdentifier
|
||||
self.location = location
|
||||
self.rangeInfo = rangeInfo?.nilIfEmpty
|
||||
self.chapterTitle = chapterTitle?.nilIfEmpty
|
||||
self.note = note?.nilIfEmpty
|
||||
self.createdAt = createdAt
|
||||
@ -288,7 +292,7 @@ public struct RDEPUBAnnotation: Codable, Equatable {
|
||||
kind: .bookmark,
|
||||
location: bookmark.location,
|
||||
text: nil,
|
||||
rangeInfo: nil,
|
||||
rangeInfo: bookmark.rangeInfo,
|
||||
color: nil,
|
||||
chapterTitle: bookmark.chapterTitle,
|
||||
note: bookmark.note,
|
||||
@ -302,6 +306,7 @@ public struct RDEPUBAnnotation: Codable, Equatable {
|
||||
id: id,
|
||||
bookIdentifier: bookIdentifier,
|
||||
location: location,
|
||||
rangeInfo: rangeInfo,
|
||||
chapterTitle: chapterTitle,
|
||||
note: note,
|
||||
createdAt: createdAt
|
||||
|
||||
@ -22,10 +22,6 @@ struct RDEPUBChapterTailNormalizer {
|
||||
previous.diagnostics.append(note)
|
||||
compacted.append(previous)
|
||||
} else {
|
||||
|
||||
#if DEBUG
|
||||
print("[EPUB][Pagination] href=\(href) dropped leading/intermediate whitespace frame \(NSStringFromRange(frame.contentRange))")
|
||||
#endif
|
||||
}
|
||||
continue
|
||||
}
|
||||
@ -41,9 +37,6 @@ struct RDEPUBChapterTailNormalizer {
|
||||
previousFrame.diagnostics.append(note)
|
||||
normalized.append(previousFrame)
|
||||
} else {
|
||||
#if DEBUG
|
||||
print("[EPUB][Pagination] href=\(href) dropped trailing frame \(NSStringFromRange(lastFrame.contentRange))")
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -187,16 +187,8 @@ public final class RDEPUBTextBookBuilder {
|
||||
let renderDuration = CFAbsoluteTimeGetCurrent() - renderStart
|
||||
|
||||
let plainText = rendered.attributedString.string.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if item.href.lowercased().contains("cover") {
|
||||
#if DEBUG
|
||||
print("[EPUB][Cover] rendered href=\(item.href) textLength=\(plainText.count) attrLength=\(rendered.attributedString.length) attachments=\(attachmentCount(in: rendered.attributedString))")
|
||||
#endif
|
||||
}
|
||||
if shouldSkipChapter(item: item, content: rendered.attributedString, text: plainText) {
|
||||
if item.href.lowercased().contains("cover") {
|
||||
#if DEBUG
|
||||
print("[EPUB][Cover] skipped href=\(item.href)")
|
||||
#endif
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -287,12 +279,6 @@ public final class RDEPUBTextBookBuilder {
|
||||
]
|
||||
: normalizedFrames
|
||||
|
||||
if item.href.lowercased().contains("cover") {
|
||||
#if DEBUG
|
||||
print("[EPUB][Cover] paginated href=\(item.href) pages=\(effectiveFrames.count) firstRange=\(effectiveFrames.first.map { NSStringFromRange($0.contentRange) } ?? "none")")
|
||||
#endif
|
||||
}
|
||||
|
||||
let chapterAttributedContent = content.copy() as! NSAttributedString
|
||||
let pages = effectiveFrames.enumerated().map { localPageIndex, frame in
|
||||
let range = frame.contentRange
|
||||
|
||||
@ -51,9 +51,6 @@ struct RDEPUBAttachmentNormalizer {
|
||||
|
||||
if !didLogFootnoteAttachment {
|
||||
didLogFootnoteAttachment = true
|
||||
#if DEBUG
|
||||
print("[EPUB][Attachment] footnote original=\(RDEPUBHTMLNormalizer.string(from: originalSize)) display=\(RDEPUBHTMLNormalizer.string(from: attachment.displaySize)) font=\(pointSize)")
|
||||
#endif
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -77,9 +74,6 @@ struct RDEPUBAttachmentNormalizer {
|
||||
|
||||
if !didLogCoverAttachment {
|
||||
didLogCoverAttachment = true
|
||||
#if DEBUG
|
||||
print("[EPUB][Attachment] cover original=\(RDEPUBHTMLNormalizer.string(from: originalSize)) display=\(RDEPUBHTMLNormalizer.string(from: attachment.displaySize))")
|
||||
#endif
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -38,10 +38,6 @@ extension RDEPUBReaderController: RDReaderDataSource, RDReaderPageProvider, RDRe
|
||||
readerView.currentPage < 0 || readerView.currentPage == pageNum
|
||||
) && !readerView.isPageCurlTransitioning
|
||||
if resolvedPage == nil, shouldAllowSynchronousFallback {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"sync fallback requested page=\(pageNum + 1) currentPage=\(readerView.currentPage + 1) totalKnown=\(pageCountOfReaderView(readerView: readerView))"
|
||||
)
|
||||
_ = runtime.prepareOnDemandChapter(
|
||||
forAbsolutePageNumber: pageNum + 1,
|
||||
allowSynchronousLoad: true
|
||||
@ -84,10 +80,6 @@ extension RDEPUBReaderController: RDReaderDataSource, RDReaderPageProvider, RDRe
|
||||
guard let readerView, let contentView else { return }
|
||||
readerView.updateSelectionPagingSuppression(for: contentView, isSuppressed: isSuppressed)
|
||||
}
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"configureLoading page=\(pageNum + 1) currentPage=\(readerView.currentPage + 1) totalKnown=\(pageCountOfReaderView(readerView: readerView)) hasMap=\(readerContext.bookPageMap != nil)"
|
||||
)
|
||||
contentView.configureLoading(
|
||||
pageNumber: pageNum + 1,
|
||||
totalPages: pageCountOfReaderView(readerView: readerView),
|
||||
@ -369,15 +361,7 @@ extension RDEPUBReaderController: RDReaderDataSource, RDReaderPageProvider, RDRe
|
||||
}
|
||||
}
|
||||
let effectivePageNum = readerView.currentPage >= 0 ? readerView.currentPage : pageNum
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"PageEvent",
|
||||
"pageNum callback raw=\(pageNum + 1) effective=\(effectivePageNum + 1) previousCurrent=\(previousCurrentPage + 1) readerCurrent=\(readerView.currentPage + 1) totalPages=\(pageCountOfReaderView(readerView: readerView)) display=\(readerView.currentDisplayType)"
|
||||
)
|
||||
if previousCurrentPage != readerView.currentPage, effectivePageNum != pageNum {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"PageEvent",
|
||||
"pageNum callback aborted dueToCurrentPageMutation raw=\(pageNum + 1) effective=\(effectivePageNum + 1)"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -94,6 +94,35 @@ extension RDEPUBReaderController {
|
||||
return location
|
||||
}
|
||||
|
||||
func currentVisibleRangeInfo() -> String? {
|
||||
guard let pageNumber = currentPageNumber else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let resolvedPage = resolvedRuntimePage(forPageNumber: pageNumber) {
|
||||
let startOffset = resolvedPage.page.pageStartOffset
|
||||
let endOffset = max(startOffset + 1, resolvedPage.page.pageEndOffset + 1)
|
||||
return RDEPUBTextOffsetRangeInfo(
|
||||
href: resolvedPage.chapter.href,
|
||||
start: startOffset,
|
||||
end: endOffset
|
||||
).jsonString()
|
||||
}
|
||||
|
||||
guard let textBook,
|
||||
let page = textBook.page(at: pageNumber) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let startOffset = page.pageStartOffset
|
||||
let endOffset = max(startOffset + 1, page.pageEndOffset + 1)
|
||||
return RDEPUBTextOffsetRangeInfo(
|
||||
href: page.href,
|
||||
start: startOffset,
|
||||
end: endOffset
|
||||
).jsonString()
|
||||
}
|
||||
|
||||
func synchronizeTextReadingState(pageNumber: Int, location: RDEPUBLocation) {
|
||||
if let resolvedPage = resolvedRuntimePage(forPageNumber: pageNumber) {
|
||||
readingSession?.updateReadingContext(
|
||||
|
||||
@ -214,9 +214,7 @@ public final class RDURLReaderController: UIViewController {
|
||||
?? readerController.textBook?.pages.count
|
||||
?? readerController.activePages.count
|
||||
let numPages = readerController.readerView.numberOfPages()
|
||||
print("[ReadViewDemo] performDemoPageNavigation(\(pageNumber)): knownPages=\(knownPages), readerView.numberOfPages=\(numPages), currentPage=\(readerController.readerView.currentPage)")
|
||||
let moved = readerController.go(toPageNumber: pageNumber, animated: animated)
|
||||
print("[ReadViewDemo] performDemoPageNavigation(\(pageNumber)): moved=\(moved), after currentPage=\(readerController.readerView.currentPage)")
|
||||
if moved {
|
||||
emitDemoState(prefix: "page=\(pageNumber)")
|
||||
}
|
||||
@ -264,7 +262,6 @@ public final class RDURLReaderController: UIViewController {
|
||||
if pendingDemoPageRequest.attemptCount >= maxPendingDemoPageAttempts {
|
||||
self.pendingDemoPageRequest = nil
|
||||
isRetryingPendingDemoPage = false
|
||||
print("[ReadViewDemo] automation page=\(pendingDemoPageRequest.pageNumber) failed after \(pendingDemoPageRequest.attemptCount) attempts")
|
||||
return
|
||||
}
|
||||
|
||||
@ -280,7 +277,6 @@ public final class RDURLReaderController: UIViewController {
|
||||
let href = location?.href ?? "nil"
|
||||
let progression = location.map { String(format: "%.4f", $0.navigationProgression) } ?? "nil"
|
||||
let page = readerController.currentPageNumber.map(String.init) ?? "nil"
|
||||
print("[ReadViewDemo] automation \(prefix) -> page \(page) href \(href) progression \(progression)")
|
||||
}
|
||||
|
||||
private func installDemoStateLabel() {
|
||||
@ -370,7 +366,6 @@ public final class RDURLReaderController: UIViewController {
|
||||
if let logPrefix {
|
||||
logDemoState(prefix: logPrefix)
|
||||
} else if logIfChanged, state != lastEmittedDemoState {
|
||||
print("[ReadViewDemo] automation \(state)")
|
||||
}
|
||||
lastEmittedDemoState = state
|
||||
}
|
||||
|
||||
@ -2,59 +2,9 @@ import Foundation
|
||||
|
||||
enum RDEPUBBackgroundTrace {
|
||||
|
||||
static var isEnabled: Bool {
|
||||
#if DEBUG
|
||||
return _enabled
|
||||
#else
|
||||
return false
|
||||
#endif
|
||||
}
|
||||
|
||||
static var _enabled = true
|
||||
|
||||
static func log(_ scope: String, _ message: String) {
|
||||
guard isEnabled else { return }
|
||||
let threadRole = Thread.isMainThread ? "main" : "bg"
|
||||
|
||||
let threadName = resolvedThreadName()
|
||||
|
||||
let queueLabel = resolvedQueueLabel()
|
||||
print("[EPUB][\(scope)][\(threadRole)][queue=\(queueLabel)][thread=\(threadName)] \(message)")
|
||||
let queueLabel = String(validatingUTF8: __dispatch_queue_get_label(nil)) ?? "unknown"
|
||||
print("[EPUB][\(scope)][\(threadRole)][queue=\(queueLabel)] \(message)")
|
||||
}
|
||||
|
||||
static func measure<T>(_ scope: String, _ message: String, work: () throws -> T) rethrows -> T {
|
||||
guard isEnabled else { return try work() }
|
||||
let startedAt = CFAbsoluteTimeGetCurrent()
|
||||
log(scope, "START \(message)")
|
||||
do {
|
||||
|
||||
let result = try work()
|
||||
|
||||
let elapsedMs = Int((CFAbsoluteTimeGetCurrent() - startedAt) * 1000)
|
||||
log(scope, "END \(message) elapsedMs=\(elapsedMs)")
|
||||
return result
|
||||
} catch {
|
||||
|
||||
let elapsedMs = Int((CFAbsoluteTimeGetCurrent() - startedAt) * 1000)
|
||||
log(scope, "FAIL \(message) elapsedMs=\(elapsedMs) error=\(error)")
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
private static func resolvedThreadName() -> String {
|
||||
|
||||
if let name = Thread.current.name, !name.isEmpty {
|
||||
return name
|
||||
}
|
||||
|
||||
if Thread.isMainThread {
|
||||
return "main"
|
||||
}
|
||||
|
||||
return String(describing: Unmanaged.passUnretained(Thread.current).toOpaque())
|
||||
}
|
||||
|
||||
private static func resolvedQueueLabel() -> String {
|
||||
String(validatingUTF8: __dispatch_queue_get_label(nil)) ?? "unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,10 +47,7 @@ final class RDEPUBChapterLoader {
|
||||
priority: LoadPriority = .navigation,
|
||||
completion: @escaping (Result<RDEPUBRuntimeChapter, Error>) -> Void
|
||||
) {
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "request spine=\(spineIndex) priority=\(priority)")
|
||||
|
||||
if let cached = store.chapterData(for: spineIndex) {
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "cache hit spine=\(spineIndex) priority=\(priority)")
|
||||
if let context {
|
||||
scheduleDeferredCFIMapBuildIfNeeded(
|
||||
for: cached,
|
||||
@ -78,10 +75,6 @@ final class RDEPUBChapterLoader {
|
||||
|
||||
switch registration {
|
||||
case .joined(let existingPriority, let effectivePriority):
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"ChapterLoader",
|
||||
"dedupe spine=\(spineIndex) existingPriority=\(existingPriority) requestedPriority=\(priority) effectivePriority=\(effectivePriority)"
|
||||
)
|
||||
return
|
||||
case .created:
|
||||
break
|
||||
@ -98,39 +91,26 @@ final class RDEPUBChapterLoader {
|
||||
return
|
||||
}
|
||||
let queuePriority = self.pendingPriority(for: spineIndex) ?? priority
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "queue start spine=\(spineIndex) priority=\(queuePriority)")
|
||||
let cacheKey = self.makeCacheKey(spineIndex: spineIndex, context: context)
|
||||
|
||||
let precomputedPageRanges = store.pageCount(for: cacheKey)?.pageRanges
|
||||
let diskSummary: RDEPUBChapterSummary?
|
||||
if precomputedPageRanges == nil {
|
||||
diskSummary = self.summaryDiskCache?.read(for: cacheKey)
|
||||
if diskSummary != nil {
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "磁盘摘要缓存命中 spine=\(spineIndex)")
|
||||
} else {
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "缓存未命中 spine=\(spineIndex)")
|
||||
}
|
||||
} else {
|
||||
diskSummary = nil
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "页数缓存命中 spine=\(spineIndex)")
|
||||
}
|
||||
let diskPageRanges = diskSummary?.pageRanges.map { $0.nsRange }
|
||||
let availablePageRanges = precomputedPageRanges ?? diskPageRanges
|
||||
|
||||
do {
|
||||
|
||||
let chapter = try RDEPUBBackgroundTrace.measure(
|
||||
"ChapterLoader",
|
||||
"buildChapter spine=\(spineIndex) priority=\(queuePriority) cachedRanges=\(availablePageRanges?.count ?? 0)"
|
||||
) {
|
||||
try self.buildChapter(
|
||||
spineIndex: spineIndex,
|
||||
availablePageRanges: availablePageRanges,
|
||||
diskSummary: diskSummary,
|
||||
context: context
|
||||
)
|
||||
}
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "buildChapter OK: spine=\(spineIndex) pages=\(chapter.pages.count)")
|
||||
let chapter = try self.buildChapter(
|
||||
spineIndex: spineIndex,
|
||||
availablePageRanges: availablePageRanges,
|
||||
diskSummary: diskSummary,
|
||||
context: context
|
||||
)
|
||||
|
||||
store.insertChapter(chapter)
|
||||
let pc = RDEPUBRuntimePageCount(
|
||||
@ -174,8 +154,6 @@ final class RDEPUBChapterLoader {
|
||||
self.resolvePendingLoad(spineIndex: spineIndex, result: .success(chapter))
|
||||
}
|
||||
} catch {
|
||||
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "buildChapter FAILED: spine=\(spineIndex) error=\(error)")
|
||||
store.endPendingChapterLoad(for: spineIndex)
|
||||
store.markBuilding(false)
|
||||
self.resolvePendingLoad(spineIndex: spineIndex, result: .failure(error))
|
||||
@ -217,10 +195,6 @@ final class RDEPUBChapterLoader {
|
||||
semaphore.signal()
|
||||
}
|
||||
if case .joined(let existingPriority, let effectivePriority) = registration {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"ChapterLoader",
|
||||
"sync join spine=\(spineIndex) existingPriority=\(existingPriority) effectivePriority=\(effectivePriority)"
|
||||
)
|
||||
semaphore.wait()
|
||||
return try result!.get()
|
||||
}
|
||||
@ -230,45 +204,40 @@ final class RDEPUBChapterLoader {
|
||||
|
||||
var result: Result<RDEPUBRuntimeChapter, Error>?
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "sync request spine=\(spineIndex)")
|
||||
store.chapterLoadQueue.async {
|
||||
do {
|
||||
result = try RDEPUBBackgroundTrace.measure(
|
||||
"ChapterLoader",
|
||||
"sync buildChapter spine=\(spineIndex)"
|
||||
) {
|
||||
try autoreleasepool { () -> Result<RDEPUBRuntimeChapter, Error> in
|
||||
let cacheKey = self.makeCacheKey(spineIndex: spineIndex, context: context)
|
||||
let precomputedPageRanges = store.pageCount(for: cacheKey)?.pageRanges
|
||||
let diskSummary: RDEPUBChapterSummary?
|
||||
if precomputedPageRanges == nil {
|
||||
diskSummary = self.summaryDiskCache?.read(for: cacheKey)
|
||||
} else {
|
||||
diskSummary = nil
|
||||
}
|
||||
let chapter = try self.buildChapter(
|
||||
spineIndex: spineIndex,
|
||||
availablePageRanges: precomputedPageRanges ?? diskSummary?.pageRanges.map(\.nsRange),
|
||||
diskSummary: diskSummary,
|
||||
context: context
|
||||
)
|
||||
store.insertChapter(chapter)
|
||||
let pageCount = RDEPUBRuntimePageCount(
|
||||
cacheKey: cacheKey,
|
||||
spineIndex: spineIndex,
|
||||
pageRanges: chapter.pageRanges,
|
||||
pageCount: chapter.pages.count,
|
||||
renderSignature: cacheKey.renderSignature
|
||||
)
|
||||
store.insertPageCount(pageCount, for: cacheKey)
|
||||
self.scheduleDeferredCFIMapBuildIfNeeded(
|
||||
for: chapter,
|
||||
cacheKey: cacheKey,
|
||||
store: store
|
||||
)
|
||||
return .success(chapter)
|
||||
let chapter: RDEPUBRuntimeChapter = try autoreleasepool {
|
||||
let cacheKey = self.makeCacheKey(spineIndex: spineIndex, context: context)
|
||||
let precomputedPageRanges = store.pageCount(for: cacheKey)?.pageRanges
|
||||
let diskSummary: RDEPUBChapterSummary?
|
||||
if precomputedPageRanges == nil {
|
||||
diskSummary = self.summaryDiskCache?.read(for: cacheKey)
|
||||
} else {
|
||||
diskSummary = nil
|
||||
}
|
||||
let chapter = try self.buildChapter(
|
||||
spineIndex: spineIndex,
|
||||
availablePageRanges: precomputedPageRanges ?? diskSummary?.pageRanges.map(\.nsRange),
|
||||
diskSummary: diskSummary,
|
||||
context: context
|
||||
)
|
||||
store.insertChapter(chapter)
|
||||
let pageCount = RDEPUBRuntimePageCount(
|
||||
cacheKey: cacheKey,
|
||||
spineIndex: spineIndex,
|
||||
pageRanges: chapter.pageRanges,
|
||||
pageCount: chapter.pages.count,
|
||||
renderSignature: cacheKey.renderSignature
|
||||
)
|
||||
store.insertPageCount(pageCount, for: cacheKey)
|
||||
self.scheduleDeferredCFIMapBuildIfNeeded(
|
||||
for: chapter,
|
||||
cacheKey: cacheKey,
|
||||
store: store
|
||||
)
|
||||
return chapter
|
||||
}
|
||||
result = .success(chapter)
|
||||
} catch {
|
||||
result = .failure(error)
|
||||
}
|
||||
@ -332,7 +301,6 @@ final class RDEPUBChapterLoader {
|
||||
|
||||
if let pageRanges = availablePageRanges {
|
||||
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "轻量路径 spine=\(spineIndex) 缓存页数=\(pageRanges.count)")
|
||||
return try buildChapterFromCachedPageRanges(
|
||||
spineIndex: spineIndex,
|
||||
pageRanges: pageRanges,
|
||||
@ -346,7 +314,6 @@ final class RDEPUBChapterLoader {
|
||||
)
|
||||
}
|
||||
|
||||
RDEPUBBackgroundTrace.log("ChapterLoader", "完整路径 spine=\(spineIndex)")
|
||||
let builder = context.makeTextBookBuilder(layoutConfig: layoutConfig)
|
||||
guard let result = try builder.buildChapter(
|
||||
parser: parser,
|
||||
@ -410,10 +377,6 @@ final class RDEPUBChapterLoader {
|
||||
effectivePageRanges = sanitizedCachedRanges
|
||||
metadataSource = diskSummary?.pageMetadataList
|
||||
} else {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"ChapterLoader",
|
||||
"缓存页范围失效,回退重分页 spine=\(spineIndex) cached=\(pageRanges.count) valid=\(sanitizedCachedRanges.count) textLength=\(typesetString.length)"
|
||||
)
|
||||
effectivePageRanges = typesetString.rd_paginatedFrames(size: pageSize, config: layoutConfig).map(\.contentRange)
|
||||
metadataSource = nil
|
||||
}
|
||||
|
||||
@ -83,10 +83,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
windowRadius: context.configuration.chapterWindowRadius
|
||||
)
|
||||
presentationRuntime.navigationStateMachine.transition(to: .preparingChapter(spineIndex: spineIndex))
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"prepareOnDemandChapter page=\(pageNumber) absoluteIndex=\(absolutePageIndex) spine=\(spineIndex)"
|
||||
)
|
||||
|
||||
if !chapterReady {
|
||||
guard allowSynchronousLoad else {
|
||||
@ -104,7 +100,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
)
|
||||
} catch {
|
||||
clearPendingPreparePageNumber(pageNumber)
|
||||
RDEPUBBackgroundTrace.log("Runtime", "prepareOnDemandChapter FAILED: spine=\(spineIndex) error=\(error)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -151,10 +146,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
return
|
||||
}
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"extendPartialBookPageMap currentPage=\(currentPageNumber) totalPages=\(currentMap.totalPages) appendSpines=\(spineIndicesToAppend) direction=\(isNearEnd ? "forward" : "backward")"
|
||||
)
|
||||
|
||||
let currentLocation = locationCoordinator.currentVisibleLocation()
|
||||
let loadedChaptersLock = NSLock()
|
||||
@ -174,8 +165,8 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
loadedChaptersLock.lock()
|
||||
loadedChapters[spineIndex] = chapter
|
||||
loadedChaptersLock.unlock()
|
||||
case .failure(let error):
|
||||
RDEPUBBackgroundTrace.log("Runtime", "extendPartialBookPageMap skip spine=\(spineIndex) error=\(error)")
|
||||
case .failure:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,7 +207,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
guard shouldSchedulePrefetch(for: spineIndex) else { continue }
|
||||
|
||||
store.addPrefetchTarget(spineIndex)
|
||||
RDEPUBBackgroundTrace.log("Runtime", "initial open prefetch forward spine=\(spineIndex)")
|
||||
loader.loadChapter(spineIndex: spineIndex, store: store, priority: .prefetch) { [weak self] result in
|
||||
guard let self, case .success = result else { return }
|
||||
self.appendLoadedForwardChaptersToCurrentPageMapIfPossible()
|
||||
@ -363,10 +353,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
}
|
||||
|
||||
let newMap = RDEPUBBookPageMap(entries: normalizedEntries)
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"extendPartialBookPageMap applied chapters=\(newMap.totalChapters) pages=\(newMap.totalPages)"
|
||||
)
|
||||
presentationRuntime.queueExtendedPartialPageMap(
|
||||
newMap,
|
||||
currentPageNumber: currentPageNumber,
|
||||
@ -380,16 +366,8 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
completion: ((Bool) -> Void)?
|
||||
) {
|
||||
guard beginAsynchronousChapterPreparation(for: spineIndex) else {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"prepareOnDemandChapter async deduped spine=\(spineIndex) page=\(triggerPageNumber)"
|
||||
)
|
||||
return
|
||||
}
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"prepareOnDemandChapter async spine=\(spineIndex) page=\(triggerPageNumber)"
|
||||
)
|
||||
loader.loadChapter(
|
||||
spineIndex: spineIndex,
|
||||
store: store,
|
||||
@ -406,10 +384,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
self.refreshVisibleContentIfNeeded(afterPreparing: spineIndex, triggerPageNumber: triggerPageNumber)
|
||||
case .failure(let error):
|
||||
self.clearPendingPreparePageNumber(triggerPageNumber)
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"prepareOnDemandChapter async FAILED: spine=\(spineIndex) error=\(error)"
|
||||
)
|
||||
completion?(false)
|
||||
}
|
||||
}
|
||||
@ -429,10 +403,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
for adjacentSpineIndex in store.windowSpineIndices where adjacentSpineIndex != spineIndex {
|
||||
guard shouldSchedulePrefetch(for: adjacentSpineIndex) else { continue }
|
||||
store.addPrefetchTarget(adjacentSpineIndex)
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"schedule prefetch currentSpine=\(spineIndex) adjacentSpine=\(adjacentSpineIndex)"
|
||||
)
|
||||
loader.loadChapter(
|
||||
spineIndex: adjacentSpineIndex,
|
||||
store: store,
|
||||
@ -468,10 +438,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
for targetSpineIndex in targets {
|
||||
guard shouldSchedulePrefetch(for: targetSpineIndex) else { continue }
|
||||
store.addPrefetchTarget(targetSpineIndex)
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"boundary prefetch currentSpine=\(spineIndex) targetSpine=\(targetSpineIndex) remainingPages=\(remainingPages)"
|
||||
)
|
||||
loader.loadChapter(spineIndex: targetSpineIndex, store: store, priority: .prefetch) { [weak self] result in
|
||||
guard let self, case .success = result else { return }
|
||||
self.appendLoadedForwardChaptersToCurrentPageMapIfPossible()
|
||||
@ -544,10 +510,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
let newMap = RDEPUBBookPageMap(entries: newEntries)
|
||||
guard newMap.totalPages > currentMap.totalPages else { return }
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"appendLoadedForwardChapters currentPage=\(currentPageNumber) trailingBefore=\(trailingPages) trailingAfter=\(newMap.totalPages - currentPageNumber) chapters=\(newMap.totalChapters) pages=\(newMap.totalPages)"
|
||||
)
|
||||
|
||||
presentationRuntime.queueForwardAppendedPageMap(newMap)
|
||||
}
|
||||
@ -574,10 +536,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
if !allowSynchronousLoad && !chapterReady {
|
||||
let inserted = pendingPreparePageNumbers.insert(pageNumber).inserted
|
||||
if !inserted {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"prepareOnDemandChapter page deduped page=\(pageNumber) spine=\(spineIndex) chapterReady=false"
|
||||
)
|
||||
return false
|
||||
}
|
||||
return nil
|
||||
@ -586,10 +544,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
pendingPreparePageNumbers.remove(pageNumber)
|
||||
if let lastTimestamp = recentPrepareTimestamps[pageNumber],
|
||||
now - lastTimestamp <= prepareRequestDebounceInterval {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"prepareOnDemandChapter page debounced page=\(pageNumber) spine=\(spineIndex) chapterReady=\(chapterReady)"
|
||||
)
|
||||
return chapterReady
|
||||
}
|
||||
|
||||
@ -616,10 +570,6 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
return
|
||||
}
|
||||
if readerView.isPageCurlTransitioning {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"defer refreshVisibleContent spine=\(spineIndex) triggerPage=\(triggerPageNumber) reason=pageCurlTransition"
|
||||
)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
|
||||
self?.refreshVisibleContentIfNeeded(
|
||||
afterPreparing: spineIndex,
|
||||
@ -630,26 +580,14 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
}
|
||||
let visiblePageNumber = readerView.currentPage + 1
|
||||
if visiblePageNumber == triggerPageNumber {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"refreshVisibleContent matchedTrigger spine=\(spineIndex) triggerPage=\(triggerPageNumber) visiblePage=\(visiblePageNumber)"
|
||||
)
|
||||
refreshVisibleContentPreservingLocation()
|
||||
return
|
||||
}
|
||||
guard visiblePageNumber > 0,
|
||||
let visibleSpineIndex = bookPageMap.spineIndex(forAbsolutePage: visiblePageNumber - 1),
|
||||
visibleSpineIndex == spineIndex else {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"skip refreshVisibleContent spine=\(spineIndex) triggerPage=\(triggerPageNumber) visiblePage=\(visiblePageNumber)"
|
||||
)
|
||||
return
|
||||
}
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"refreshVisibleContent matchedVisibleSpine spine=\(spineIndex) triggerPage=\(triggerPageNumber) visiblePage=\(visiblePageNumber)"
|
||||
)
|
||||
refreshVisibleContentPreservingLocation()
|
||||
}
|
||||
|
||||
@ -677,16 +615,8 @@ final class RDEPUBChapterWarmupOrchestrator {
|
||||
chapters.append(chapter)
|
||||
} catch {
|
||||
if spineIndex == targetSpineIndex {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"ensureNavigationTarget FAILED target spine=\(spineIndex) error=\(error)"
|
||||
)
|
||||
return []
|
||||
}
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"ensureNavigationTarget skip adjacent spine=\(spineIndex) error=\(error)"
|
||||
)
|
||||
}
|
||||
}
|
||||
return chapters
|
||||
|
||||
@ -46,10 +46,6 @@ final class RDEPUBChapterWindowCoordinator {
|
||||
self.isSwitchingChapter = false
|
||||
self.buildSnapshotAroundCurrent(chapter: chapter)
|
||||
case .failure(let error):
|
||||
#if DEBUG
|
||||
print("[EPUB][WindowCoord] loadChapter failed at spine=\(initialSpineIndex): \(error), trying next")
|
||||
#endif
|
||||
|
||||
let nextIndex = initialSpineIndex + 1
|
||||
if nextIndex < totalSpineCount {
|
||||
self.store.setCurrentChapter(
|
||||
@ -70,9 +66,6 @@ final class RDEPUBChapterWindowCoordinator {
|
||||
|
||||
private func buildSnapshotAroundCurrent(chapter: RDEPUBRuntimeChapter) {
|
||||
guard let current = store.currentSpineIndex else {
|
||||
#if DEBUG
|
||||
print("[EPUB][WindowCoord] buildSnapshot: currentSpineIndex is nil, ABORT")
|
||||
#endif
|
||||
return
|
||||
}
|
||||
let chapters = store.windowSpineIndices.compactMap { spineIndex -> RDEPUBRuntimeChapter? in
|
||||
@ -82,9 +75,6 @@ final class RDEPUBChapterWindowCoordinator {
|
||||
return store.chapterData(for: spineIndex)
|
||||
}
|
||||
let snapshot = RDEPUBChapterWindowSnapshot.from(chapters: chapters, anchorSpineIndex: current)
|
||||
#if DEBUG
|
||||
print("[EPUB][WindowCoord] snapshot: chapters=\(snapshot.chapters.count) pages=\(snapshot.pageCount) anchorPage=\(snapshot.anchorPageOffset)")
|
||||
#endif
|
||||
currentSnapshot = snapshot
|
||||
isApplyingSnapshot = true
|
||||
onSnapshotChanged?(snapshot)
|
||||
@ -213,20 +203,9 @@ final class RDEPUBChapterWindowCoordinator {
|
||||
}
|
||||
|
||||
private func handle(error: Error) {
|
||||
|
||||
#if DEBUG
|
||||
print("[RDEPUBChapterWindowCoordinator] chapter load error: \(error)")
|
||||
#endif
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else { return }
|
||||
self.context.hideLoading()
|
||||
|
||||
if self.currentSnapshot == nil {
|
||||
#if DEBUG
|
||||
print("[RDEPUBChapterWindowCoordinator] No snapshot after error, page will be blank")
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -69,10 +69,6 @@ final class RDEPUBBackgroundCoverageStore {
|
||||
segments[index] = mergedSegment
|
||||
currentMemoryBytes = currentMemoryBytes - existing.estimatedMemoryBytes + mergedSegment.estimatedMemoryBytes
|
||||
merged = true
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"CoverageStore",
|
||||
"merged segments: \(existing.lowerSpineIndex)-\(existing.upperSpineIndex) + \(segment.lowerSpineIndex)-\(segment.upperSpineIndex)"
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -84,11 +80,6 @@ final class RDEPUBBackgroundCoverageStore {
|
||||
}
|
||||
|
||||
lastAccessTime[segment.lowerSpineIndex] = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"CoverageStore",
|
||||
"added segment \(segment.lowerSpineIndex)-\(segment.upperSpineIndex) total=\(segments.count) memory=\(currentMemoryBytes)B"
|
||||
)
|
||||
}
|
||||
|
||||
func findSegment(containing spineIndex: Int) -> RDEPUBBackgroundCoverageSegment? {
|
||||
@ -138,10 +129,6 @@ final class RDEPUBBackgroundCoverageStore {
|
||||
activeWindowSpineIndices: Set<Int>,
|
||||
protectedSpineIndices: Set<Int>
|
||||
) {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"CoverageStore",
|
||||
"memory warning: clearing cold segments, current=\(currentMemoryBytes)B"
|
||||
)
|
||||
|
||||
clearColdSegments(
|
||||
activeWindowSpineIndices: activeWindowSpineIndices,
|
||||
@ -167,11 +154,6 @@ final class RDEPUBBackgroundCoverageStore {
|
||||
segments.removeAll { $0.lowerSpineIndex == segment.lowerSpineIndex }
|
||||
}
|
||||
}
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"CoverageStore",
|
||||
"after cleanup: segments=\(segments.count) memory=\(currentMemoryBytes)B"
|
||||
)
|
||||
}
|
||||
|
||||
private func evictIfNeeded(forNewSegment newSegment: RDEPUBBackgroundCoverageSegment) {
|
||||
@ -201,11 +183,6 @@ final class RDEPUBBackgroundCoverageStore {
|
||||
let evicted = segments.remove(at: oldestIndex)
|
||||
currentMemoryBytes -= evicted.estimatedMemoryBytes
|
||||
lastAccessTime.removeValue(forKey: evicted.lowerSpineIndex)
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"CoverageStore",
|
||||
"evicted segment \(evicted.lowerSpineIndex)-\(evicted.upperSpineIndex)"
|
||||
)
|
||||
}
|
||||
|
||||
private func canMerge(_ lhs: RDEPUBBackgroundCoverageSegment, _ rhs: RDEPUBBackgroundCoverageSegment) -> Bool {
|
||||
|
||||
@ -93,10 +93,6 @@ final class RDEPUBBackgroundPriorityManager {
|
||||
currentGeneration += 1
|
||||
coldCursor = 0
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"PriorityManager",
|
||||
"addWarmAnchor spine=\(spineIndex) generation=\(currentGeneration) anchors=\(warmAnchors.count)"
|
||||
)
|
||||
}
|
||||
|
||||
func makeMetadataPriorityOrder(
|
||||
|
||||
@ -121,10 +121,6 @@ final class RDEPUBJumpSessionManager {
|
||||
lastPageDirection = nil
|
||||
lastActivityTime = now
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"JumpSession",
|
||||
"created anchor=\(anchorSpineIndex) protected=\(protectedIndices.count) seq=\(nextSequenceNumber)"
|
||||
)
|
||||
|
||||
return session
|
||||
}
|
||||
@ -163,20 +159,12 @@ final class RDEPUBJumpSessionManager {
|
||||
|
||||
if now >= session.expiresAt {
|
||||
if isIdle || (now - lastActivityTime) >= policy.idleGracePeriod {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"JumpSession",
|
||||
"end: timeout seq=\(session.sequenceNumber)"
|
||||
)
|
||||
return .timeout
|
||||
}
|
||||
}
|
||||
|
||||
if !session.protectedSpineIndices.contains(currentSpineIndex) {
|
||||
if consecutivePageCount >= policy.exitPageThreshold {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"JumpSession",
|
||||
"end: navigated-away seq=\(session.sequenceNumber) pages=\(consecutivePageCount)"
|
||||
)
|
||||
return .navigatedAway
|
||||
}
|
||||
} else {
|
||||
@ -189,10 +177,6 @@ final class RDEPUBJumpSessionManager {
|
||||
|
||||
func endSession(_ reason: RDEPUBJumpSession.EndReason) {
|
||||
guard let session = activeSession else { return }
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"JumpSession",
|
||||
"ended seq=\(session.sequenceNumber) reason=\(reason)"
|
||||
)
|
||||
activeSession = nil
|
||||
consecutivePageCount = 0
|
||||
lastPageDirection = nil
|
||||
|
||||
@ -125,10 +125,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
context.paginationToken == token else { return }
|
||||
|
||||
if let restoredPageMap = self.restoreBookPageMapIfPossible() {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"full cache restore hit chapters=\(restoredPageMap.totalChapters) pages=\(restoredPageMap.totalPages)"
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
guard context.paginationToken == token,
|
||||
context.controller != nil,
|
||||
@ -140,13 +136,8 @@ final class RDEPUBMetadataParseWorker {
|
||||
|
||||
let prewarmStart = CFAbsoluteTimeGetCurrent()
|
||||
let prewarmMs = Int((CFAbsoluteTimeGetCurrent() - prewarmStart) * 1000)
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "prewarmHashMs=\(prewarmMs) chapters=\(self.allBuildableIndices.count)")
|
||||
|
||||
let restored = self.summaryDiskCache?.readAll(keys: self.catalog)
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"begin token=\(token.uuidString) buildableChapters=\(self.allBuildableIndices.count) concurrency=\(self.workerCount)"
|
||||
)
|
||||
let cachedSummaries = restored?.summaries ?? [:]
|
||||
let cachedSpineIndices = Set(cachedSummaries.keys)
|
||||
let resultLock = NSLock()
|
||||
@ -157,10 +148,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
)
|
||||
|
||||
if !cachedSpineIndices.isEmpty {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"resumeFromCache cachedChapters=\(cachedSpineIndices.count) total=\(self.allBuildableIndices.count)"
|
||||
)
|
||||
let cachedMap = self.buildPageMap(summaries: parseState.summariesBySpineIndex)
|
||||
DispatchQueue.main.async {
|
||||
guard context.paginationToken == token,
|
||||
@ -178,10 +165,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
currentSpineIndex: currentSpineIndex,
|
||||
cachedSpineIndices: cachedSpineIndices
|
||||
)
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"prioritized hot=\(prioritizedSpineIndices.prefix(10).count) total=\(prioritizedSpineIndices.count)"
|
||||
)
|
||||
} else {
|
||||
prioritizedSpineIndices = self.allBuildableIndices.filter { !cachedSpineIndices.contains($0) }
|
||||
}
|
||||
@ -192,7 +175,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
guard !cancellationController.isCancelled,
|
||||
context.controller != nil,
|
||||
context.paginationToken == token else {
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "abort before queue start")
|
||||
return
|
||||
}
|
||||
|
||||
@ -222,7 +204,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
return
|
||||
}
|
||||
do {
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "正在解析 spine=\(spineIndex) \(offset + 1)/\(uncachedSpineIndices.count)")
|
||||
|
||||
let renderResult: RDEPUBChapterSummary? = try autoreleasepool { () -> RDEPUBChapterSummary? in
|
||||
guard context.controller != nil,
|
||||
@ -246,7 +227,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
context.paginationToken == token,
|
||||
!cancellationController.isCancelled,
|
||||
operation?.isCancelled != true else {
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "drop rendered chapter due to cancellation spine=\(spineIndex)")
|
||||
return nil
|
||||
}
|
||||
let renderElapsed = (CFAbsoluteTimeGetCurrent() - renderStart) * 1000
|
||||
@ -272,7 +252,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
context.paginationToken == token,
|
||||
!cancellationController.isCancelled,
|
||||
operation?.isCancelled != true else {
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "skip disk write due to cancellation spine=\(spineIndex)")
|
||||
return nil
|
||||
}
|
||||
let writeStart = CFAbsoluteTimeGetCurrent()
|
||||
@ -285,10 +264,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
completedChapters += 1
|
||||
timingLock.unlock()
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"spine=\(spineIndex) renderMs=\(Int(renderElapsed)) writeMs=\(Int(writeElapsed))"
|
||||
)
|
||||
return summary
|
||||
}
|
||||
|
||||
@ -335,7 +310,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
timingLock.lock()
|
||||
failedChapters += 1
|
||||
timingLock.unlock()
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "buildChapter FAILED: spine=\(spineIndex) error=\(error)")
|
||||
|
||||
self.scheduleRetry(
|
||||
spineIndex: spineIndex,
|
||||
@ -364,29 +338,18 @@ final class RDEPUBMetadataParseWorker {
|
||||
let failed = failedChapters
|
||||
timingLock.unlock()
|
||||
let avgRenderMs = rendered > 0 ? renderTotal / rendered : 0
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"timing wallClockMs=\(wallClockMs) chapters=\(rendered) failed=\(failed) " +
|
||||
"prewarmHashMs=\(prewarmMs) renderTotalMs=\(renderTotal) writeTotalMs=\(writeTotal) " +
|
||||
"mergeTotalMs=\(mergeTotal) avgRenderMs=\(avgRenderMs) concurrency=\(self.workerCount)"
|
||||
)
|
||||
context.lastMetadataParseWallClockMs = wallClockMs
|
||||
context.lastMetadataParseConcurrency = self.workerCount
|
||||
|
||||
guard context.controller != nil,
|
||||
context.paginationToken == token,
|
||||
!cancellationController.isCancelled else {
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "abort: reader dismissed or token changed")
|
||||
return
|
||||
}
|
||||
|
||||
let finalMergeStart = CFAbsoluteTimeGetCurrent()
|
||||
let pageMap = self.buildPageMap(summaries: parseState.summariesBySpineIndex)
|
||||
let finalMergeMs = Int((CFAbsoluteTimeGetCurrent() - finalMergeStart) * 1000)
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"complete chapters=\(pageMap.totalChapters) pages=\(pageMap.totalPages) finalMergeMs=\(finalMergeMs)"
|
||||
)
|
||||
|
||||
if let coverageStore = context.runtime?.backgroundCoverageStore {
|
||||
let resolvedSpineIndices = Set(parseState.summariesBySpineIndex.keys)
|
||||
@ -434,18 +397,10 @@ final class RDEPUBMetadataParseWorker {
|
||||
cancellationController: RDEPUBMetadataParseCancellationController
|
||||
) {
|
||||
guard retryCount < Self.maxRetryCount else {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"spine=\(spineIndex) max retries reached, marking as deferredFailure"
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
let delay = Self.retryDelays[min(retryCount, Self.retryDelays.count - 1)]
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"scheduling retry for spine=\(spineIndex) attempt=\(retryCount + 1) delay=\(delay)s"
|
||||
)
|
||||
|
||||
DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + delay) { [weak self] in
|
||||
guard let self else { return }
|
||||
@ -470,7 +425,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
guard context.controller != nil,
|
||||
context.paginationToken == self.token,
|
||||
!cancellationController.isCancelled else {
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "drop retry result due to cancellation spine=\(spineIndex)")
|
||||
return
|
||||
}
|
||||
|
||||
@ -494,7 +448,6 @@ final class RDEPUBMetadataParseWorker {
|
||||
guard context.controller != nil,
|
||||
context.paginationToken == self.token,
|
||||
!cancellationController.isCancelled else {
|
||||
RDEPUBBackgroundTrace.log("MetadataParse", "skip retry disk write due to cancellation spine=\(spineIndex)")
|
||||
return
|
||||
}
|
||||
self.summaryDiskCache?.write(summary: summary, for: cacheKey)
|
||||
@ -520,15 +473,7 @@ final class RDEPUBMetadataParseWorker {
|
||||
}
|
||||
}
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"retry succeeded for spine=\(spineIndex) attempt=\(retryCount + 1)"
|
||||
)
|
||||
} catch {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"MetadataParse",
|
||||
"retry failed for spine=\(spineIndex) attempt=\(retryCount + 1) error=\(error)"
|
||||
)
|
||||
|
||||
self.scheduleRetry(
|
||||
spineIndex: spineIndex,
|
||||
|
||||
@ -67,10 +67,9 @@ final class RDEPUBNavigationStateMachine {
|
||||
isValid = false
|
||||
}
|
||||
if !isValid {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"NavigationStateMachine",
|
||||
"WARNING: unexpected transition \(oldState) → \(newState)"
|
||||
)
|
||||
#if DEBUG
|
||||
assertionFailure("Unexpected navigation state transition: \(oldState) → \(newState)")
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -28,10 +28,8 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
|
||||
guard let currentWindow else {
|
||||
if let candidatePageMap {
|
||||
RDEPUBBackgroundTrace.log("Reconciliation", "evaluateTakeover: no currentWindow, fullReplace candidateChapters=\(candidatePageMap.totalChapters) candidatePages=\(candidatePageMap.totalPages)")
|
||||
return .fullReplace(candidatePageMap)
|
||||
}
|
||||
RDEPUBBackgroundTrace.log("Reconciliation", "evaluateTakeover: no currentWindow, no candidate")
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
|
||||
@ -54,10 +52,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
let coverageRatio = Double(protectedIndices.intersection(candidateIndices).count) /
|
||||
Double(protectedIndices.count)
|
||||
if coverageRatio < 0.8 {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"evaluateTakeover: blocked by jumpSession protection coverage=\(String(format: "%.2f", coverageRatio)) currentSpine=\(currentSpineIndex) protected=\(protectedIndices)"
|
||||
)
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
}
|
||||
@ -72,10 +66,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
let hasPrev = candidateSegment.contains(spineIndex: currentSpineIndex - 1)
|
||||
let hasNext = candidateSegment.contains(spineIndex: currentSpineIndex + 1)
|
||||
if !hasPrev || !hasNext {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"evaluateTakeover: blocked by missing adjacent coverage (segment) currentSpine=\(currentSpineIndex) hasPrev=\(hasPrev) hasNext=\(hasNext)"
|
||||
)
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
}
|
||||
@ -85,10 +75,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
if let candidateSegment {
|
||||
let currentRenderSignature = context.currentRenderSignature()
|
||||
if candidateSegment.renderSignature != currentRenderSignature {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"evaluateTakeover: blocked by render signature mismatch"
|
||||
)
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
}
|
||||
@ -111,7 +97,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
)
|
||||
}
|
||||
|
||||
RDEPUBBackgroundTrace.log("Reconciliation", "evaluateTakeover: no candidate, keepCurrentWindow")
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
|
||||
@ -126,10 +111,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
|
||||
if let currentSpineIndex {
|
||||
if !candidateIndices.contains(currentSpineIndex) {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"evaluateSegmentTakeover: keepCurrentWindow — currentSpine=\(currentSpineIndex) not in candidate"
|
||||
)
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
}
|
||||
@ -139,10 +120,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
let hasNext = candidateIndices.contains(currentSpineIndex + 1) ||
|
||||
currentSpineIndex == lastBuildableSpineIndex
|
||||
if !hasPrev || !hasNext {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"evaluateSegmentTakeover: keepCurrentWindow — missing adjacent spine=\(currentSpineIndex) hasPrev=\(hasPrev) hasNext=\(hasNext)"
|
||||
)
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
}
|
||||
@ -179,10 +156,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
|
||||
if let currentSpineIndex {
|
||||
if !candidateIndices.contains(currentSpineIndex) {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"evaluateFullPageMapTakeover: keepCurrentWindow — currentSpine=\(currentSpineIndex) not in candidate (candidateChapters=\(candidateIndices.count) currentChapters=\(currentEntries) candidatePages=\(candidatePageMap.totalPages) currentPages=\(currentWindow.totalPages))"
|
||||
)
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
}
|
||||
@ -192,10 +165,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
let hasNext = candidateIndices.contains(currentSpineIndex + 1) ||
|
||||
currentSpineIndex == lastBuildableSpineIndex
|
||||
if !hasPrev || !hasNext {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"evaluateFullPageMapTakeover: keepCurrentWindow — missing adjacent spine=\(currentSpineIndex) hasPrev=\(hasPrev) hasNext=\(hasNext) lastBuildable=\(lastBuildableSpineIndex)"
|
||||
)
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
}
|
||||
@ -209,10 +178,6 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
return .fullReplace(candidatePageMap)
|
||||
}
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"evaluateFullPageMapTakeover: keepCurrentWindow — candidateChapters=\(candidateIndices.count) < currentChapters=\(currentEntries)"
|
||||
)
|
||||
return .keepCurrentWindow
|
||||
}
|
||||
|
||||
@ -237,4 +202,4 @@ final class RDEPUBPageMapReconciliationCoordinator {
|
||||
|
||||
return indices
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,7 +71,6 @@ final class RDEPUBPresentationRuntime {
|
||||
|
||||
guard !controller.isRepaginating else { return }
|
||||
guard !readerView.isPageCurlTransitioning else {
|
||||
RDEPUBBackgroundTrace.log("PageMapCommit", "defer commit reason=pageCurlTransition")
|
||||
return
|
||||
}
|
||||
|
||||
@ -226,18 +225,15 @@ final class RDEPUBPresentationRuntime {
|
||||
|
||||
switch decision {
|
||||
case .keepCurrentWindow:
|
||||
RDEPUBBackgroundTrace.log("Reconciliation", "decision: keepCurrentWindow — pending update removed to prevent indefinite retry")
|
||||
removePendingPageMapUpdate(at: index)
|
||||
return false
|
||||
|
||||
case .fullReplace(let newPageMap):
|
||||
RDEPUBBackgroundTrace.log("Reconciliation", "decision: fullReplace")
|
||||
removePendingPageMapUpdate(at: index)
|
||||
applyFullPageMapReplacement(newPageMap, readerView: readerView, controller: controller)
|
||||
return true
|
||||
|
||||
case .expandWindow, .segmentReplace:
|
||||
RDEPUBBackgroundTrace.log("Reconciliation", "decision: unexpected segment decision")
|
||||
removePendingPageMapUpdate(at: index)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -266,6 +266,7 @@ final class RDEPUBReaderAnnotationCoordinator {
|
||||
let newBookmark = RDEPUBBookmark(
|
||||
bookIdentifier: controller.currentBookIdentifier,
|
||||
location: location,
|
||||
rangeInfo: controller.currentVisibleRangeInfo(),
|
||||
chapterTitle: titleForBookmarkLocation(location),
|
||||
note: normalizedBookmarkNote(note)
|
||||
)
|
||||
@ -306,7 +307,11 @@ final class RDEPUBReaderAnnotationCoordinator {
|
||||
guard let bookmark = bookmark(withID: id) else {
|
||||
return false
|
||||
}
|
||||
return controller.restoreReadingLocation(bookmark.location, animated: animated)
|
||||
return controller.restoreReadingLocation(
|
||||
bookmark.location,
|
||||
animated: animated,
|
||||
targetHighlightRangeInfo: bookmark.rangeInfo
|
||||
)
|
||||
}
|
||||
|
||||
func presentBookmarksManager() {
|
||||
@ -320,7 +325,11 @@ final class RDEPUBReaderAnnotationCoordinator {
|
||||
bookmarksController.onSelectBookmark = { [weak self, weak bookmarksController] bookmark in
|
||||
guard let controller = self?.controller else { return }
|
||||
bookmarksController?.dismiss(animated: true) {
|
||||
_ = controller.restoreReadingLocation(bookmark.location, animated: true)
|
||||
_ = controller.restoreReadingLocation(
|
||||
bookmark.location,
|
||||
animated: true,
|
||||
targetHighlightRangeInfo: bookmark.rangeInfo
|
||||
)
|
||||
}
|
||||
}
|
||||
bookmarksController.onDeleteBookmark = { [weak self] bookmark in
|
||||
|
||||
@ -16,9 +16,6 @@ final class RDEPUBReaderAssemblyCoordinator {
|
||||
setupLoadingIndicator(controller.loadingIndicator, in: controller.view)
|
||||
setupErrorLabel(controller.errorLabel, in: controller.view)
|
||||
controller.delegate?.epubReader(controller, configureTopToolView: controller.topToolView)
|
||||
#if DEBUG
|
||||
print("[ReadViewDemo] assembleInterface: pageProvider=\(readerView.pageProvider != nil ? "set" : "nil"), numberOfPages=\(readerView.numberOfPages())")
|
||||
#endif
|
||||
}
|
||||
|
||||
func finishExternalTextBookLaunchIfNeeded() {
|
||||
@ -35,13 +32,7 @@ final class RDEPUBReaderAssemblyCoordinator {
|
||||
}
|
||||
|
||||
if let textBook = controller.textBook {
|
||||
#if DEBUG
|
||||
print("[ReadViewDemo] finishExternalTextBook: applying textBook with \(textBook.pages.count) pages")
|
||||
#endif
|
||||
runtime.applyTextBook(textBook, restoreLocation: restoreLocation)
|
||||
#if DEBUG
|
||||
print("[ReadViewDemo] finishExternalTextBook: after applyTextBook, numberOfPages=\(context.readerView?.numberOfPages() ?? -1)")
|
||||
#endif
|
||||
} else {
|
||||
runtime.finishPagination(restoreLocation: restoreLocation)
|
||||
}
|
||||
|
||||
@ -28,14 +28,8 @@ final class RDEPUBReaderPaginationCoordinator {
|
||||
controller.showLoading()
|
||||
let token = UUID()
|
||||
context.paginationToken = token
|
||||
#if DEBUG
|
||||
print("[EPUB][Pagination] profile=\(publication.readingProfile.rawValue) layout=\(publication.layout.rawValue) spine=\(publication.spine.count)")
|
||||
#endif
|
||||
|
||||
if publication.readingProfile == .textReflowable {
|
||||
#if DEBUG
|
||||
print("[EPUB][Pagination] path=text-reflowable-on-demand")
|
||||
#endif
|
||||
paginateTextPublication(
|
||||
parser: parser,
|
||||
publication: publication,
|
||||
@ -47,9 +41,6 @@ final class RDEPUBReaderPaginationCoordinator {
|
||||
}
|
||||
|
||||
if publication.layout == .fixed {
|
||||
#if DEBUG
|
||||
print("[EPUB][Pagination] path=fixed-layout")
|
||||
#endif
|
||||
let snapshot = readingSession.makePaginationSnapshot(
|
||||
pageCounts: Array(repeating: 1, count: publication.spine.count),
|
||||
preferences: controller.currentPreferences(),
|
||||
@ -60,9 +51,6 @@ final class RDEPUBReaderPaginationCoordinator {
|
||||
}
|
||||
|
||||
let paginator = context.makePaginator()
|
||||
#if DEBUG
|
||||
print("[EPUB][Pagination] path=web-paginator")
|
||||
#endif
|
||||
context.paginator = paginator
|
||||
paginator.calculate(
|
||||
parser: parser,
|
||||
@ -143,31 +131,15 @@ final class RDEPUBReaderPaginationCoordinator {
|
||||
func refreshVisibleContentPreservingLocation() {
|
||||
guard let readerView = context.readerView else { return }
|
||||
if readerView.isPageCurlTransitioning {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"defer refreshVisibleContent currentPage=\(readerView.currentPage + 1) reason=pageCurlTransition"
|
||||
)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
|
||||
self?.refreshVisibleContentPreservingLocation()
|
||||
}
|
||||
return
|
||||
}
|
||||
let restoreLocation = context.currentVisibleLocation() ?? context.persistenceLocation()
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"refreshVisibleContentPreservingLocation currentPage=\(readerView.currentPage + 1) restoreHref=\(restoreLocation?.href ?? "nil") restoreCFI=\(restoreLocation?.cfi ?? "nil")"
|
||||
)
|
||||
if readerView.currentDisplayType == .pageCurl, readerView.currentPage >= 0 {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"refreshVisibleContent using transitionToPage currentPage=\(readerView.currentPage + 1)"
|
||||
)
|
||||
readerView.transitionToPage(pageNum: readerView.currentPage, animated: false)
|
||||
} else {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"LoadingPage",
|
||||
"refreshVisibleContent using reloadData currentPage=\(readerView.currentPage + 1)"
|
||||
)
|
||||
readerView.reloadData()
|
||||
}
|
||||
if let restoreLocation {
|
||||
@ -220,22 +192,9 @@ final class RDEPUBReaderPaginationCoordinator {
|
||||
do {
|
||||
guard context.controller != nil,
|
||||
let runtime = context.runtime else { return }
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"QuickOpen",
|
||||
"begin token=\(token.uuidString) candidates=\(prioritizedCandidates.count) restoreSpine=\(readingSession.initialSpineIndex(for: restoreLocation))"
|
||||
)
|
||||
let runtimeChapter = try RDEPUBBackgroundTrace.measure(
|
||||
"QuickOpen",
|
||||
"loadFirstRenderableRuntimeChapter"
|
||||
) {
|
||||
try self.loadFirstRenderableRuntimeChapter(
|
||||
prioritizedSpineIndices: prioritizedCandidates,
|
||||
runtime: runtime
|
||||
)
|
||||
}
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"QuickOpen",
|
||||
"ready anchorSpine=\(runtimeChapter.spineIndex) pages=\(runtimeChapter.pages.count)"
|
||||
let runtimeChapter = try self.loadFirstRenderableRuntimeChapter(
|
||||
prioritizedSpineIndices: prioritizedCandidates,
|
||||
runtime: runtime
|
||||
)
|
||||
let initialChapters = self.loadInitialInteractiveRuntimeChapters(
|
||||
anchorChapter: runtimeChapter,
|
||||
@ -290,7 +249,6 @@ final class RDEPUBReaderPaginationCoordinator {
|
||||
)
|
||||
} catch {
|
||||
lastError = error
|
||||
RDEPUBBackgroundTrace.log("QuickOpen", "skip spine=\(spineIndex) reason=\(error)")
|
||||
}
|
||||
}
|
||||
throw lastError ?? RDEPUBParserError.emptySpine
|
||||
@ -329,10 +287,6 @@ final class RDEPUBReaderPaginationCoordinator {
|
||||
)
|
||||
selectedChapters.append(chapter)
|
||||
} catch {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"QuickOpen",
|
||||
"lookahead skip spine=\(spineIndex) reason=\(error)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -430,11 +430,6 @@ final class RDEPUBReaderRuntime {
|
||||
}
|
||||
let previewLocation = locationCoordinator.currentVisibleLocation() ?? context.persistenceLocation()
|
||||
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"repaginateCurrentChapterOnly spine=\(currentSpineIndex) generation=\(previewGeneration)"
|
||||
)
|
||||
|
||||
chapterLoader.loadChapter(
|
||||
spineIndex: currentSpineIndex,
|
||||
store: chapterRuntimeStore,
|
||||
@ -468,10 +463,7 @@ final class RDEPUBReaderRuntime {
|
||||
readerView.transitionToPage(pageNum: 0, animated: false)
|
||||
|
||||
case .failure(let error):
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Runtime",
|
||||
"repaginateCurrentChapterOnly FAILED spine=\(currentSpineIndex) generation=\(previewGeneration) error=\(error)"
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -523,7 +515,6 @@ final class RDEPUBReaderRuntime {
|
||||
|
||||
if needsFullRepaginationAfterSettingsClose {
|
||||
needsFullRepaginationAfterSettingsClose = false
|
||||
RDEPUBBackgroundTrace.log("Runtime", "settingsPanelDidDisappear: triggering full repagination")
|
||||
paginationCoordinator.repaginatePreservingCurrentLocation()
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,10 +97,6 @@ extension RDReaderView: UIPageViewControllerDataSource, UIPageViewControllerDele
|
||||
|
||||
public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
|
||||
let resolvedPage = (pageViewController.viewControllers?.first as? RDReaderPageChildViewController)?.pageNum ?? -1
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"PageCurl",
|
||||
"didFinishAnimating finished=\(finished) completed=\(completed) resolvedPage=\(resolvedPage + 1) currentPageBeforeFinish=\(currentPage + 1)"
|
||||
)
|
||||
if completed, let firstVC = pageViewController.viewControllers?.first as? RDReaderPageChildViewController {
|
||||
let pn = firstVC.pageNum
|
||||
if pn != RDReaderView.blankPageNum && pn != RDReaderView.blankEndPageNum {
|
||||
@ -119,17 +115,9 @@ extension RDReaderView: UIPageViewControllerDataSource, UIPageViewControllerDele
|
||||
if let target = pendingViewControllers.first as? RDReaderPageChildViewController,
|
||||
target.pageNum != RDReaderView.blankPageNum,
|
||||
target.pageNum != RDReaderView.blankEndPageNum {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"PageCurl",
|
||||
"willTransitionTo targetPage=\(target.pageNum + 1) currentPage=\(currentPage + 1)"
|
||||
)
|
||||
predictedPageDirection = target.pageNum >= currentPage
|
||||
primePageCache(around: target.pageNum, preferredForward: predictedPageDirection)
|
||||
} else {
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"PageCurl",
|
||||
"willTransitionTo blank target currentPage=\(currentPage + 1)"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user