-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
优先选择偏好类型数据源,不需要等其他源查询完毕 #1002
base: main
Are you sure you want to change the base?
优先选择偏好类型数据源,不需要等其他源查询完毕 #1002
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -47,8 +47,11 @@ import me.him188.ani.utils.coroutines.cancellableCoroutineScope | |||||||
import me.him188.ani.utils.logging.error | ||||||||
import me.him188.ani.utils.logging.info | ||||||||
import me.him188.ani.utils.logging.logger | ||||||||
import me.him188.ani.utils.platform.collections.EnumMap | ||||||||
import me.him188.ani.utils.platform.collections.ImmutableEnumMap | ||||||||
import kotlin.coroutines.CoroutineContext | ||||||||
import kotlin.coroutines.EmptyCoroutineContext | ||||||||
import kotlin.jvm.JvmInline | ||||||||
|
||||||||
/** | ||||||||
* [MediaFetcher], 为支持从多个 [MediaSource] 并行获取 [Media] 的综合查询工具. | ||||||||
|
@@ -338,10 +341,27 @@ class MediaSourceMediaFetcher( | |||||||
} | ||||||||
|
||||||||
override val hasCompleted = if (mediaSourceResults.isEmpty()) { | ||||||||
flowOf(true) | ||||||||
flowOf(CompletedConditions.AllCompleted) | ||||||||
} else { | ||||||||
combine(mediaSourceResults.map { it.state }) { states -> | ||||||||
states.all { it is MediaSourceFetchState.Completed || it is MediaSourceFetchState.Disabled } | ||||||||
val map = MediaSourceKind.entries.map { kind -> | ||||||||
val stateList = mediaSourceResults.filter { it.kind == kind }.map { it.state } | ||||||||
combine(stateList) { states -> | ||||||||
kind to when { | ||||||||
states.all { it is MediaSourceFetchState.Disabled } -> null | ||||||||
states.all { it is MediaSourceFetchState.Completed || it is MediaSourceFetchState.Disabled } -> true | ||||||||
else -> false | ||||||||
Comment on lines
+350
to
+352
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 为什么要有 |
||||||||
} | ||||||||
}.onStart { | ||||||||
if (stateList.isEmpty()) emit(kind to null) | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
combine(map) { pairs -> | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 目前两个 combine 的算法会导致启动数倍多的协程 用一个 combine 就足够解决问题了, 让 combine 的 lambda 返回 |
||||||||
CompletedConditions( | ||||||||
ImmutableEnumMap<MediaSourceKind, _> { kind -> | ||||||||
pairs.find { it.first == kind }?.second | ||||||||
}, | ||||||||
) | ||||||||
}.flowOn(flowContext) | ||||||||
} | ||||||||
} | ||||||||
|
@@ -358,3 +378,26 @@ class MediaSourceMediaFetcher( | |||||||
private const val ENABLE_WATCHDOG = false | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
@JvmInline | ||||||||
value class CompletedConditions( | ||||||||
Comment on lines
+382
to
+383
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
这个东西看起来会用在被 box 的地方, 那其实不需要 |
||||||||
val values: EnumMap<MediaSourceKind, Boolean?> | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make it private |
||||||||
) { | ||||||||
fun allCompleted() = values.values.all { it ?: true } | ||||||||
|
||||||||
operator fun get(kind: MediaSourceKind): Boolean? = try { | ||||||||
values[kind] | ||||||||
} catch (e: NoSuchElementException) { | ||||||||
null | ||||||||
} | ||||||||
|
||||||||
fun copy( | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 未使用, 没必要有 |
||||||||
values: EnumMap<MediaSourceKind, Boolean?> = this.values, | ||||||||
): CompletedConditions = CompletedConditions(values) | ||||||||
|
||||||||
companion object { | ||||||||
val AllCompleted = CompletedConditions( | ||||||||
ImmutableEnumMap { true }, | ||||||||
) | ||||||||
} | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
目前这样改会为那些原本总是期待所有数据源加载完成的代码增加计算量 (计算是否完成并构造 EnumMap 等), 导致性能变差
这是可以避免的, 我觉得可能要做一个另外的属性来支持中间状态