diff --git a/orx-file-watcher/src/main/kotlin/FileWatcher.kt b/orx-file-watcher/src/main/kotlin/FileWatcher.kt index 3fd21ac8..c2d148a4 100644 --- a/orx-file-watcher/src/main/kotlin/FileWatcher.kt +++ b/orx-file-watcher/src/main/kotlin/FileWatcher.kt @@ -11,22 +11,26 @@ import java.nio.file.WatchKey import kotlin.concurrent.thread class FileWatcher(private val program: Program, val file: File, private val onChange: (File) -> Unit) { + val path = file.absoluteFile.toPath() + val parent = path.parent + val key = pathKeys.getOrPut(parent) { + parent.register( + watchService, arrayOf(StandardWatchEventKinds.ENTRY_MODIFY), + SensitivityWatchEventModifier.HIGH + ) + } init { watchThread - val path = file.absoluteFile.toPath() - val parent = path.parent - val key = pathKeys.getOrPut(parent) { - parent.register( - watchService, arrayOf(StandardWatchEventKinds.ENTRY_MODIFY), - SensitivityWatchEventModifier.HIGH - ) - } watching.getOrPut(path) { mutableListOf() }.add(this) keyPaths.getOrPut(key) { parent } } + fun stop() { + watching[path]?.remove(this) + } + internal fun triggerChange() { program.launch { onChange(file) @@ -34,20 +38,45 @@ class FileWatcher(private val program: Program, val file: File, private val onCh } } +private val watchers = mutableMapOf< ()->Any, FileWatcher>() + fun watchFile(program: Program, file: File, transducer: (File) -> T): () -> T { var result = transducer(file) - FileWatcher(program, file) { + val watcher = FileWatcher(program, file) { try { result = transducer(file) } catch (e: Throwable) { e.printStackTrace() } } - return { + + val function = { result } + + @Suppress("UNCHECKED_CAST") + watchers[function as ()->Any] = watcher + return function } +/** + * Stops the watcher + */ +fun (()->T).stop() { + @Suppress("UNCHECKED_CAST") + watchers[this as ()->Any]?.stop() + +} + +/** + * Triggers reload + */ +fun (()->T).triggerChange() { + @Suppress("UNCHECKED_CAST") + watchers[this as ()->Any]?.triggerChange() +} + + @JvmName("programWatchFile") fun Program.watchFile(file: File, transducer: (File) -> T): () -> T = watchFile(this, file, transducer) @@ -67,9 +96,8 @@ private val watchThread by lazy { key.pollEvents().forEach { val contextPath = it.context() as Path val fullPath = path?.resolve(contextPath) - watching[fullPath]?.forEach { - - it.triggerChange() + watching[fullPath]?.forEach { w -> + w.triggerChange() } } key.reset() @@ -82,12 +110,12 @@ fun main() { it.readText() } - + a.stop() + a.triggerChange() while (true) { println(a()) Thread.sleep(2000) - } }