mirror of
https://github.com/jie65535/mirai-console-jcf-plugin.git
synced 2025-06-02 17:39:15 +08:00
添加任务调度工具
- 时刻表、任务表 - 循环执行
This commit is contained in:
parent
d5230b926f
commit
8132a1ab4c
149
src/main/kotlin/top/jie65535/jcf/ScheduleHandler.kt
Normal file
149
src/main/kotlin/top/jie65535/jcf/ScheduleHandler.kt
Normal file
@ -0,0 +1,149 @@
|
||||
package top.jie65535.jcf
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.console.command.ConsoleCommandSender.name
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import top.jie65535.jcf.util.LockUtil
|
||||
import java.util.*
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/**
|
||||
* 任务调度
|
||||
*
|
||||
* @property bot 每个 bot 维护一个调度器
|
||||
* @property logger 日志
|
||||
*/
|
||||
class ScheduleHandler(private val bot: Bot, private val logger: MiraiLogger) {
|
||||
// region -- 常量、变量
|
||||
/**
|
||||
* 任务表
|
||||
*/
|
||||
private val taskSet = mutableMapOf<String, (String) -> Unit>()
|
||||
|
||||
/**
|
||||
* 时刻表;
|
||||
* 仅时与分用于校对
|
||||
*/
|
||||
private val periodList = mutableListOf<Calendar>()
|
||||
|
||||
/**
|
||||
* 线程锁:时刻表
|
||||
*/
|
||||
private val periodLock = LockUtil(periodList)
|
||||
|
||||
/**
|
||||
* 线程锁:任务表
|
||||
*/
|
||||
private val taskLock = LockUtil(taskSet)
|
||||
|
||||
// 变量
|
||||
|
||||
/**
|
||||
* 标识:暂停校对和调度
|
||||
*/
|
||||
private var pause = true
|
||||
|
||||
/**
|
||||
* 暂存
|
||||
*/
|
||||
private var swap: Calendar? = null
|
||||
|
||||
/**
|
||||
* 线程:循环执行核对与调度
|
||||
*/
|
||||
private val loopThread = thread(name = "schedule:${bot.id}:${bot.nick}") { loop() }
|
||||
|
||||
// endregion
|
||||
|
||||
// region -- 校对与调度
|
||||
|
||||
/**
|
||||
* 比较时与分是否相等
|
||||
*/
|
||||
private infix fun Calendar.eq(then: Calendar?): Boolean =
|
||||
if (then == null)
|
||||
false
|
||||
else get(Calendar.MINUTE) == then.get(Calendar.MINUTE)
|
||||
&& get(Calendar.HOUR_OF_DAY) == then.get(Calendar.HOUR_OF_DAY)
|
||||
|
||||
/**
|
||||
* 取反 [eq] 函数
|
||||
*/
|
||||
private infix fun Calendar.neq(then: Calendar): Boolean = !eq(then)
|
||||
|
||||
/**
|
||||
* 暂存的时刻重入时刻表
|
||||
*
|
||||
* @param ref 用以校准的指标
|
||||
*/
|
||||
private fun reSwap(ref: Calendar) {
|
||||
if (ref eq swap) {
|
||||
periodLock.withLock { add(swap!!) }
|
||||
swap = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 时辰到?
|
||||
*
|
||||
* @param then 校对时刻
|
||||
*/
|
||||
private fun isThen(then: Calendar): Boolean = periodLock.withLock {
|
||||
var isNow = false
|
||||
val ii = periodList.iterator()
|
||||
while (ii.hasNext()) {
|
||||
val time = ii.next()
|
||||
if (then eq time) {
|
||||
isNow = true
|
||||
swap = time
|
||||
ii.remove()
|
||||
break
|
||||
}
|
||||
}
|
||||
isNow// return value
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待
|
||||
*
|
||||
* @receiver 当前线程
|
||||
* @param time 等待时间(毫秒)
|
||||
* @return 是否继续
|
||||
*/
|
||||
private fun Thread.delay(time: Long): Boolean =
|
||||
try {
|
||||
Thread.sleep(1000 * 20)
|
||||
true
|
||||
} catch (_: Exception) {
|
||||
false
|
||||
}
|
||||
|
||||
/**
|
||||
* 循环执行校准与调度
|
||||
*/
|
||||
private fun loop() {
|
||||
val thread = Thread.currentThread()
|
||||
while (!thread.isInterrupted) {
|
||||
if (pause) continue
|
||||
if (periodList.isEmpty()) continue
|
||||
if (!thread.delay(1000 * 20))
|
||||
break
|
||||
|
||||
val now = Calendar.getInstance()
|
||||
reSwap(now)
|
||||
if (!isThen(now)) continue
|
||||
|
||||
taskLock.withLock {
|
||||
// TODO 异步、限时
|
||||
forEach { (id, task) -> task(id) }
|
||||
}
|
||||
}// while
|
||||
logger.info("线程[$name]已结束")
|
||||
// TODO clean
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region -- TODO 参数与状态
|
||||
|
||||
// endregion
|
||||
}
|
Loading…
Reference in New Issue
Block a user