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 object AutoSystem : 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 futureConfigure: ScheduledFuture<*>? = null private var futureAwilight: ScheduledFuture<*>? = null private var futureTitle: ScheduledFuture<*>? = null private var futureLevel: ScheduledFuture<*>? = null private var futureAbility: ScheduledFuture<*>? = null private var futureAbilityClass: ScheduledFuture<*>? = null private var futureEdge: ScheduledFuture<*>? = null fun dispose() { ws.close() ses.shutdown() } fun handleSystem() { Thread { 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) var isAvailable = true while (isAvailable) { try { val tws = ws.take() tws.pollEvents().forEach { fun loadConfigure() { futureConfigure?.cancel(true) futureConfigure = ses.schedule({ 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") && !VoteSystem.isLoading) { futureVote?.cancel(true) futureVote = ses.schedule( { VoteSystem.loadVote() }, 1, TimeUnit.SECONDS ) } } "Title" -> { if (FilenameUtils.isExtension(fileName, "json") && !TitleSystem.isLoading) { futureTitle?.cancel(true) futureTitle = ses.schedule( { TitleSystem.loadTitle() }, 1, TimeUnit.SECONDS ) } } "Level" -> { if (!LevelSystem.isLoading) { futureLevel?.cancel(true) futureLevel = ses.schedule( { LevelSystem.loadLevel() }, 1, TimeUnit.SECONDS ) } } "Ability" -> { if (FilenameUtils.isExtension(fileName, "json") && !AbilitySystem.isLoading) { futureAbility?.cancel(true) futureAbility = ses.schedule( { AbilitySystem.loadAbility() }, 1, TimeUnit.SECONDS ) } } "Ability Class" -> { if (!AbilityClassSystem.isLoading) { futureAbilityClass?.cancel(true) futureAbilityClass = ses.schedule( { AbilityClassSystem.loadAbilityClass() }, 1, TimeUnit.SECONDS ) } } "Edge" -> { if (!EdgeSystem.isLoading) { futureEdge?.cancel(true) futureEdge = ses.schedule( { 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 (e: ClosedWatchServiceException) { isAvailable = false } catch (e: InterruptedException) { isAvailable = false } } }.apply { isDaemon = true }.start() } }