Skip to content

Commit

Permalink
初步完善 Parallel 工具
Browse files Browse the repository at this point in the history
  • Loading branch information
Bkm016 committed Jan 6, 2025
1 parent 5b18490 commit 163c89f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group=taboolib
version=6.2.2-test-1
version=6.2.2
kotlin.incremental=true
kotlin.incremental.java=true
kotlin.caching.enabled=true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package taboolib.platform.bukkit

import org.bukkit.Bukkit
import org.bukkit.event.player.AsyncPlayerPreLoginEvent
import org.tabooproject.reflex.ClassMethod
import org.tabooproject.reflex.ReflexClass
import taboolib.common.Inject
import taboolib.common.LifeCycle
import taboolib.common.TabooLib
import taboolib.common.inject.ClassVisitor
import taboolib.common.platform.Awake
import taboolib.common.platform.function.pluginId
import taboolib.common.platform.function.registerBukkitListener
import taboolib.common.util.t
import java.util.*
import java.util.concurrent.CompletableFuture
Expand Down Expand Up @@ -54,8 +57,8 @@ import java.util.concurrent.Executors
* 同时,为了解决并行数据加载完成之前,玩家提前进入服务器的问题
* 将会借助 Exchanges 系统选举出一个主插件,负责在所有并行任务完成之前阻止玩家进入服务器
*
* 注意别引用到别个插件的 parallel 函数。
* 这个工具仅适用于 Bukkit 插件环境,不适用于 BungeeCord 插件环境
* 注意别引用到其他插件的 parallel 函数。
* 这个工具仅适用于 Bukkit 插件环境,不适用于 BungeeCord 及其他环境
*
* 还有一种 @Parallel 注解,可以直接使一个方法成为并行任务
* ```
Expand All @@ -79,7 +82,7 @@ object ParallelSystem : ClassVisitor(0) {

fun registerTask(id: String, dependOn: List<String>, lifeCycle: LifeCycle, block: () -> Unit): CompletableFuture<Unit> {
// 不允许在 INIT 之后注册
if (TabooLib.getCurrentLifeCycle() >= LifeCycle.INIT) {
if (TabooLib.getCurrentLifeCycle() > LifeCycle.INIT) {
error(
"""
并行任务必须在 INIT 或更早的生命周期下注册。
Expand Down Expand Up @@ -113,24 +116,36 @@ object ParallelSystem : ClassVisitor(0) {
try {
task.block()
task.future.complete(null)
} catch (e: Exception) {
} catch (e: Throwable) {
e.printStackTrace()
task.future.completeExceptionally(e)
}
}
} else {
// 有依赖的任务,等待依赖完成后执行
val dependencies = task.dependOn.map { dependTaskId ->
globalTaskMap[dependTaskId] ?: CompletableFuture.completedFuture(null)
// 软依赖
if (dependTaskId.endsWith('?')) {
val id = dependTaskId.substring(0, dependTaskId.length - 1)
globalTaskMap[id] ?: CompletableFuture.completedFuture(null)
} else {
globalTaskMap[dependTaskId] ?: error(
"""
并行任务 ${task.id} 的依赖不存在:$dependTaskId
Parallel task ${task.id} depends not found: $dependTaskId
""".t()
)
}
}
CompletableFuture.allOf(*dependencies.toTypedArray())
.thenRunAsync({
try {
task.block()
task.future.complete(null)
} catch (e: Exception) {
task.future.completeExceptionally(e)
}
}, executorService)
CompletableFuture.allOf(*dependencies.toTypedArray()).thenRunAsync({
try {
task.block()
task.future.complete(null)
} catch (e: Throwable) {
e.printStackTrace()
task.future.completeExceptionally(e)
}
}, executorService)
}
}
}
Expand Down Expand Up @@ -163,6 +178,25 @@ object ParallelSystem : ClassVisitor(0) {
TabooLib.registerLifeCycleTask(LifeCycle.ACTIVE, 0) { runTask(LifeCycle.ACTIVE) }
}

@Awake(LifeCycle.ENABLE)
private fun onEnable() {
// 首个执行到 ENABLE 阶段的插件负责拦截玩家进入
if (Exchanges.contains("parallel_main_plugin")) {
return
}
Exchanges["parallel_main_plugin"] = pluginId
registerBukkitListener(AsyncPlayerPreLoginEvent::class.java) {
if (globalTaskMap.values.any { !it.isDone }) {
it.disallow(
AsyncPlayerPreLoginEvent.Result.KICK_OTHER, """
服务器正在启动。
Server is starting.
""".t()
)
}
}
}

class Task(val id: String, val dependOn: List<String>, val lifeCycle: LifeCycle, val block: () -> Any?) {

val future = CompletableFuture<Unit>()
Expand All @@ -171,7 +205,7 @@ object ParallelSystem : ClassVisitor(0) {

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class Parallel(val id: String = "", val dependOn: Array<String> = [], val lifeCycle: LifeCycle = LifeCycle.ENABLE)
annotation class Parallel(val id: String = "", val dependOn: Array<String> = [], val runOn: LifeCycle = LifeCycle.ENABLE)

/**
* 注册一个并行任务
Expand Down

0 comments on commit 163c89f

Please sign in to comment.