feat: chapter runtime refactoring and related updates
- Refactor chapter runtime: replace window coordinator/snapshot with warmup orchestrator - Update EPUB core: parser, reading session, JS bridge, navigator layout - Update reader controller: data source, location resolution, persistence - Update chapter runtime: data cache, loader, runtime store, disk cache, warmup orchestrator - Remove deprecated navigation state machine and pagination state - Update text rendering: book cache, HTML normalizer - Update UI: text content view, dark image adjuster, text selection controller - Update settings and reader configuration - Add CODE_REVIEW.md and AUDIT_FINAL.md documentation - Update pod dependencies (remove SSAlertSwift, SnapKit) - Update podspec and pod configuration files Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,6 @@ enum RDEPUBPendingPageMapUpdateKind {
|
||||
|
||||
struct RDEPUBPendingPageMapUpdate {
|
||||
let pageMap: RDEPUBBookPageMap
|
||||
let source: RDEPUBPaginationStateSource
|
||||
let kind: RDEPUBPendingPageMapUpdateKind
|
||||
}
|
||||
|
||||
@@ -22,10 +21,6 @@ final class RDEPUBPresentationRuntime {
|
||||
|
||||
private unowned let reconciliationCoordinator: RDEPUBPageMapReconciliationCoordinator
|
||||
|
||||
let navigationStateMachine = RDEPUBNavigationStateMachine()
|
||||
|
||||
private(set) var paginationState = RDEPUBPaginationState()
|
||||
|
||||
init(
|
||||
context: RDEPUBReaderContext,
|
||||
locationCoordinator: RDEPUBReaderLocationCoordinator,
|
||||
@@ -43,19 +38,14 @@ final class RDEPUBPresentationRuntime {
|
||||
restoreLocation: RDEPUBLocation?,
|
||||
finishPagination: (RDEPUBLocation?) -> Void
|
||||
) {
|
||||
navigationStateMachine.transition(to: .presentingWindow)
|
||||
context.textBook = nil
|
||||
context.bookPageMap = bookPageMap
|
||||
context.pendingPageMapUpdates.removeAll()
|
||||
context.replaceActiveSnapshot(makeSnapshot(from: bookPageMap))
|
||||
paginationState.activePageMap = bookPageMap
|
||||
paginationState.pendingPageMapUpdates.removeAll()
|
||||
paginationState.source = .initialPartial
|
||||
finishPagination(restoreLocation)
|
||||
}
|
||||
|
||||
func refreshBookPageMapInPlace(_ bookPageMap: RDEPUBBookPageMap) {
|
||||
navigationStateMachine.transition(to: .reconcilingFullMap)
|
||||
RDEPUBBackgroundTrace.log(
|
||||
"Reconciliation",
|
||||
"refreshBookPageMapInPlace: enqueued reconcileFullMap chapters=\(bookPageMap.totalChapters) pages=\(bookPageMap.totalPages)"
|
||||
@@ -63,7 +53,6 @@ final class RDEPUBPresentationRuntime {
|
||||
enqueuePendingPageMapUpdate(
|
||||
RDEPUBPendingPageMapUpdate(
|
||||
pageMap: bookPageMap,
|
||||
source: .pendingFullMap,
|
||||
kind: .reconcileFullMap
|
||||
)
|
||||
)
|
||||
@@ -99,7 +88,6 @@ final class RDEPUBPresentationRuntime {
|
||||
enqueuePendingPageMapUpdate(
|
||||
RDEPUBPendingPageMapUpdate(
|
||||
pageMap: bookPageMap,
|
||||
source: .asyncExtension,
|
||||
kind: .extendPartial(
|
||||
currentPageNumber: currentPageNumber,
|
||||
currentLocation: currentLocation
|
||||
@@ -109,28 +97,19 @@ final class RDEPUBPresentationRuntime {
|
||||
}
|
||||
|
||||
func applySettingsPreviewPageMap(_ bookPageMap: RDEPUBBookPageMap) {
|
||||
navigationStateMachine.transition(to: .presentingWindow)
|
||||
context.bookPageMap = bookPageMap
|
||||
context.replaceActiveSnapshot(makeSnapshot(from: bookPageMap))
|
||||
paginationState.activePageMap = bookPageMap
|
||||
paginationState.source = .settingsPreview
|
||||
}
|
||||
|
||||
func queueForwardAppendedPageMap(_ bookPageMap: RDEPUBBookPageMap) {
|
||||
enqueuePendingPageMapUpdate(
|
||||
RDEPUBPendingPageMapUpdate(
|
||||
pageMap: bookPageMap,
|
||||
source: .asyncExtension,
|
||||
kind: .appendForward
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func clear() {
|
||||
paginationState = RDEPUBPaginationState()
|
||||
navigationStateMachine.transition(to: .idle)
|
||||
}
|
||||
|
||||
func makeSnapshot(from bookPageMap: RDEPUBBookPageMap) -> RDEPUBReadingSession.PaginationSnapshot {
|
||||
let pages = bookPageMap.entries.flatMap { entry in
|
||||
(0..<entry.pageCount).map { localPageIndex in
|
||||
@@ -162,7 +141,7 @@ final class RDEPUBPresentationRuntime {
|
||||
let currentLocation = locationCoordinator.currentVisibleLocation()
|
||||
|
||||
context.textBook = nil
|
||||
applyPageMapToLiveModel(newPageMap, source: .fullReplacement)
|
||||
applyPageMapToLiveModel(newPageMap)
|
||||
|
||||
if let currentLocation {
|
||||
if rebindVisibleLocation(currentLocation, readerView: readerView, controller: controller) == false {
|
||||
@@ -201,7 +180,6 @@ final class RDEPUBPresentationRuntime {
|
||||
updates.append(update)
|
||||
}
|
||||
context.pendingPageMapUpdates = updates
|
||||
paginationState.pendingPageMapUpdates = updates
|
||||
commitPendingPageMapUpdateIfNeeded()
|
||||
}
|
||||
|
||||
@@ -219,7 +197,6 @@ final class RDEPUBPresentationRuntime {
|
||||
) -> Bool {
|
||||
switch update.kind {
|
||||
case .reconcileFullMap:
|
||||
navigationStateMachine.transition(to: .reconcilingFullMap)
|
||||
let decision = reconciliationCoordinator.evaluateTakeover(
|
||||
candidatePageMap: update.pageMap,
|
||||
candidateSegment: nil,
|
||||
@@ -248,7 +225,7 @@ final class RDEPUBPresentationRuntime {
|
||||
|
||||
case .extendPartial(_, let currentLocation):
|
||||
removePendingPageMapUpdate(at: index)
|
||||
applyPageMapToLiveModel(update.pageMap, source: update.source)
|
||||
applyPageMapToLiveModel(update.pageMap)
|
||||
if let currentLocation,
|
||||
rebindVisibleLocation(currentLocation, readerView: readerView, controller: controller) {
|
||||
return true
|
||||
@@ -266,7 +243,7 @@ final class RDEPUBPresentationRuntime {
|
||||
|
||||
case .appendForward:
|
||||
removePendingPageMapUpdate(at: index)
|
||||
applyPageMapToLiveModel(update.pageMap, source: update.source)
|
||||
applyPageMapToLiveModel(update.pageMap)
|
||||
readerView.reloadPageCountOnly()
|
||||
return true
|
||||
}
|
||||
@@ -305,7 +282,7 @@ final class RDEPUBPresentationRuntime {
|
||||
if context.bookPageMap != nil,
|
||||
context.runtime?.prepareOnDemandChapter(
|
||||
forAbsolutePageNumber: targetPageNumber,
|
||||
allowSynchronousLoad: true
|
||||
allowSynchronousLoad: false
|
||||
) == false {
|
||||
return false
|
||||
}
|
||||
@@ -317,16 +294,10 @@ final class RDEPUBPresentationRuntime {
|
||||
return true
|
||||
}
|
||||
|
||||
private func applyPageMapToLiveModel(
|
||||
_ pageMap: RDEPUBBookPageMap,
|
||||
source: RDEPUBPaginationStateSource
|
||||
) {
|
||||
navigationStateMachine.transition(to: .presentingWindow)
|
||||
private func applyPageMapToLiveModel(_ pageMap: RDEPUBBookPageMap) {
|
||||
context.bookPageMap = pageMap
|
||||
context.replaceActiveSnapshot(makeSnapshot(from: pageMap))
|
||||
discardSupersededPendingPageMapUpdates(afterApplying: pageMap)
|
||||
paginationState.activePageMap = pageMap
|
||||
paginationState.source = source
|
||||
}
|
||||
|
||||
private func removePendingPageMapUpdate(at index: Int) {
|
||||
@@ -334,7 +305,6 @@ final class RDEPUBPresentationRuntime {
|
||||
guard updates.indices.contains(index) else { return }
|
||||
updates.remove(at: index)
|
||||
context.pendingPageMapUpdates = updates
|
||||
paginationState.pendingPageMapUpdates = updates
|
||||
}
|
||||
|
||||
private func discardSupersededPendingPageMapUpdates(afterApplying liveMap: RDEPUBBookPageMap) {
|
||||
@@ -346,7 +316,6 @@ final class RDEPUBPresentationRuntime {
|
||||
)
|
||||
}
|
||||
context.pendingPageMapUpdates = updates
|
||||
paginationState.pendingPageMapUpdates = updates
|
||||
}
|
||||
|
||||
private func pendingPriority(for kind: RDEPUBPendingPageMapUpdateKind) -> Int {
|
||||
@@ -384,4 +353,4 @@ final class RDEPUBPresentationRuntime {
|
||||
&& candidate.pageMap.totalPages >= existing.pageMap.totalPages
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user