This commit is contained in:
Horis
2025-11-13 08:16:28 +08:00
parent 92e223171d
commit 43a89baf00
@@ -52,6 +52,7 @@ import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import splitties.init.appCtx import splitties.init.appCtx
import java.util.concurrent.ConcurrentHashMap
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@@ -70,16 +71,14 @@ object ReadBook : CoroutineScope by MainScope() {
var prevTextChapter: TextChapter? = null var prevTextChapter: TextChapter? = null
var curTextChapter: TextChapter? = null var curTextChapter: TextChapter? = null
var nextTextChapter: TextChapter? = null var nextTextChapter: TextChapter? = null
var prevChapterLoadingJob: Coroutine<*>? = null
var curChapterLoadingJob: Coroutine<*>? = null
var nextChapterLoadingJob: Coroutine<*>? = null
var prevChapterLoadingLock = Mutex()
var curChapterLoadingLock = Mutex()
var nextChapterLoadingLock = Mutex()
var bookSource: BookSource? = null var bookSource: BookSource? = null
var msg: String? = null var msg: String? = null
private val loadingChapters = arrayListOf<Int>() private val loadingChapters = arrayListOf<Int>()
private val readRecord = ReadRecord() private val readRecord = ReadRecord()
private val chapterLoadingJobs = ConcurrentHashMap<Int, Coroutine<*>>()
private val prevChapterLoadingLock = Mutex()
private val curChapterLoadingLock = Mutex()
private val nextChapterLoadingLock = Mutex()
var readStartTime: Long = System.currentTimeMillis() var readStartTime: Long = System.currentTimeMillis()
/* 跳转进度前进度记录 */ /* 跳转进度前进度记录 */
@@ -221,9 +220,7 @@ object ReadBook : CoroutineScope by MainScope() {
} }
fun clearTextChapter() { fun clearTextChapter() {
prevChapterLoadingJob?.cancel() clearExpiredChapterLoadingJob(true)
curChapterLoadingJob?.cancel()
nextChapterLoadingJob?.cancel()
prevTextChapter = null prevTextChapter = null
curTextChapter = null curTextChapter = null
nextTextChapter = null nextTextChapter = null
@@ -336,7 +333,7 @@ object ReadBook : CoroutineScope by MainScope() {
if (durChapterIndex < simulatedChapterSize - 1) { if (durChapterIndex < simulatedChapterSize - 1) {
durChapterPos = 0 durChapterPos = 0
durChapterIndex++ durChapterIndex++
prevChapterLoadingJob?.cancel() clearExpiredChapterLoadingJob()
prevTextChapter = curTextChapter prevTextChapter = curTextChapter
curTextChapter = nextTextChapter curTextChapter = nextTextChapter
nextTextChapter = null nextTextChapter = null
@@ -367,7 +364,7 @@ object ReadBook : CoroutineScope by MainScope() {
if (durChapterIndex < simulatedChapterSize - 1) { if (durChapterIndex < simulatedChapterSize - 1) {
durChapterPos = 0 durChapterPos = 0
durChapterIndex++ durChapterIndex++
prevChapterLoadingJob?.cancel() clearExpiredChapterLoadingJob()
prevTextChapter = curTextChapter prevTextChapter = curTextChapter
curTextChapter = nextTextChapter curTextChapter = nextTextChapter
nextTextChapter = null nextTextChapter = null
@@ -399,7 +396,7 @@ object ReadBook : CoroutineScope by MainScope() {
if (durChapterIndex > 0) { if (durChapterIndex > 0) {
durChapterPos = if (toLast) prevTextChapter?.lastReadLength ?: Int.MAX_VALUE else 0 durChapterPos = if (toLast) prevTextChapter?.lastReadLength ?: Int.MAX_VALUE else 0
durChapterIndex-- durChapterIndex--
nextChapterLoadingJob?.cancel() clearExpiredChapterLoadingJob()
nextTextChapter = curTextChapter nextTextChapter = curTextChapter
curTextChapter = prevTextChapter curTextChapter = prevTextChapter
prevTextChapter = null prevTextChapter = null
@@ -697,12 +694,7 @@ object ReadBook : CoroutineScope by MainScope() {
if (canceled || chapter.index !in durChapterIndex - 1..durChapterIndex + 1) { if (canceled || chapter.index !in durChapterIndex - 1..durChapterIndex + 1) {
return return
} }
val offset = chapter.index - durChapterIndex chapterLoadingJobs[chapter.index]?.cancel()
when (offset) {
0 -> curChapterLoadingJob?.cancel()
-1 -> prevChapterLoadingJob?.cancel()
1 -> nextChapterLoadingJob?.cancel()
}
val job = Coroutine.async(this, start = CoroutineStart.LAZY) { val job = Coroutine.async(this, start = CoroutineStart.LAZY) {
val contentProcessor = ContentProcessor.get(book.name, book.origin) val contentProcessor = ContentProcessor.get(book.name, book.origin)
val displayTitle = chapter.getDisplayTitle( val displayTitle = chapter.getDisplayTitle(
@@ -715,7 +707,7 @@ object ReadBook : CoroutineScope by MainScope() {
val textChapter = ChapterProvider.getTextChapterAsync( val textChapter = ChapterProvider.getTextChapterAsync(
this, book, chapter, displayTitle, contents, simulatedChapterSize this, book, chapter, displayTitle, contents, simulatedChapterSize
) )
when (offset) { when (val offset = chapter.index - durChapterIndex) {
0 -> curChapterLoadingLock.withLock { 0 -> curChapterLoadingLock.withLock {
withContext(Main) { withContext(Main) {
ensureActive() ensureActive()
@@ -776,11 +768,7 @@ object ReadBook : CoroutineScope by MainScope() {
}.onSuccess { }.onSuccess {
success?.invoke() success?.invoke()
} }
when (offset) { chapterLoadingJobs[chapter.index] = job
0 -> curChapterLoadingJob = job
-1 -> prevChapterLoadingJob = job
1 -> nextChapterLoadingJob = job
}
job.start() job.start()
} }
@@ -978,6 +966,17 @@ object ReadBook : CoroutineScope by MainScope() {
} }
} }
private fun clearExpiredChapterLoadingJob(clearAll: Boolean = false) {
val iterator = chapterLoadingJobs.iterator()
while (iterator.hasNext()) {
val (index, job) = iterator.next()
if (clearAll || index !in durChapterIndex - 1..durChapterIndex + 1) {
job.cancel()
iterator.remove()
}
}
}
/** /**
* 注册回调 * 注册回调
*/ */
@@ -998,6 +997,7 @@ object ReadBook : CoroutineScope by MainScope() {
downloadScope.coroutineContext.cancelChildren() downloadScope.coroutineContext.cancelChildren()
coroutineContext.cancelChildren() coroutineContext.cancelChildren()
ImageProvider.clear() ImageProvider.clear()
clearExpiredChapterLoadingJob(true)
if (!CacheBookService.isRun) { if (!CacheBookService.isRun) {
CacheBook.close() CacheBook.close()
} }