package net.taehui.twilight.system import net.taehui.twilight.Logger import net.taehui.twilight.TwilightComponent import org.apache.commons.io.FilenameUtils import java.nio.file.* import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit class AutoSystem : AutoCloseable, Logger { private val ses: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor { Executors.defaultThreadFactory().newThread(it).apply { isDaemon = true } } private val ws = FileSystems.getDefault().newWatchService() private var futureVote: ScheduledFuture<*>? = null private var isPendingVote = false private var futureConfigure: ScheduledFuture<*>? = null private var isPendingConfigure = false private var futureAwilight: ScheduledFuture<*>? = null private var futureTitle: ScheduledFuture<*>? = null private var isPendingTitle = false private var futureLevel: ScheduledFuture<*>? = null private var isPendingLevel = false private var futureAbility: ScheduledFuture<*>? = null private var isPendingAbility = false private var futureAbilityClass: ScheduledFuture<*>? = null private var isPendingAbilityClass = false private var futureEdge: ScheduledFuture<*>? = null private var isPendingEdge = false init { Paths.get(".").register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.SYSTEM_ENTRY_PATH.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.DEFAULT_NOTE_ENTRY.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.DEFAULT_UI_ENTRY.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.TITLE_ENTRY_PATH.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.LEVEL_ENTRY_PATH.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.VOTE_ENTRY_PATH.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.ABILITY_ENTRY_PATH.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.ABILITY_CLASS_ENTRY_PATH.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) TwilightComponent.EDGE_ENTRY_PATH.register(ws, StandardWatchEventKinds.ENTRY_MODIFY) Thread { try { while (true) { val tws = ws.take() tws.pollEvents().forEach { fun loadConfigure() { if (isPendingConfigure) { isPendingConfigure = false } else { futureConfigure?.cancel(true) futureConfigure = ses.schedule({ isPendingConfigure = true Configure.loadConfigure() }, 1, TimeUnit.SECONDS) } } val filePath = (tws.watchable() as Path).resolve(it.context() as Path) val fileName = filePath.fileName.toString() when (filePath.parent.fileName.toString()) { "Note", "UI" -> { if (FilenameUtils.isExtension(fileName, "zip") || FilenameUtils.isExtension( fileName, "rar" ) ) { loadConfigure() } } "Vote" -> { if (FilenameUtils.isExtension(fileName, "json")) { if (isPendingVote) { isPendingVote = false } else { futureVote?.cancel(true) futureVote = ses.schedule( { isPendingVote = true VoteSystem.loadVote() }, 1, TimeUnit.SECONDS ) } } } "Title" -> { if (FilenameUtils.isExtension(fileName, "json")) { if (isPendingTitle) { isPendingTitle = false } else { futureTitle?.cancel(true) futureTitle = ses.schedule( { isPendingTitle = true TitleSystem.loadTitle() }, 1, TimeUnit.SECONDS ) } } } "Level" -> { if (isPendingLevel) { isPendingLevel = false } else { futureLevel?.cancel(true) futureLevel = ses.schedule( { isPendingLevel = true LevelSystem.loadLevel() }, 1, TimeUnit.SECONDS ) } } "Ability" -> { when (fileName) { "Default.json" -> { if (isPendingAbility) { isPendingAbility = false } else { futureAbility?.cancel(true) futureAbility = ses.schedule( { isPendingAbility = true AbilitySystem.loadAbility() }, 1, TimeUnit.SECONDS ) }} } } "Ability Class" -> { if (isPendingAbilityClass) { isPendingAbilityClass = false } else { futureAbilityClass?.cancel(true) futureAbilityClass = ses.schedule( { isPendingAbilityClass = true AbilityClassSystem.loadAbilityClass() }, 1, TimeUnit.SECONDS ) } } "Edge" -> { if (isPendingEdge) { isPendingEdge = false } else { futureEdge?.cancel(true) futureEdge = ses.schedule( { isPendingEdge = true EdgeSystem.loadEdge() }, 1, TimeUnit.SECONDS ) } } "System" -> { when (fileName) { "Awilight.py" -> { futureAwilight?.cancel(true) futureAwilight = ses.schedule( { AwilightHandler.loadAwilight() }, 1, TimeUnit.SECONDS ) } } } "." -> { when (fileName) { "Configure.json" -> loadConfigure() } } } } tws.reset() } } catch (_: ClosedWatchServiceException) { } }.apply { isDaemon = true }.start() } override fun close() { ws.close() ses.shutdown() } }