Add cancel / triggerChange extension methods to watcher functions
This commit is contained in:
@@ -11,22 +11,26 @@ import java.nio.file.WatchKey
|
|||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
class FileWatcher(private val program: Program, val file: File, private val onChange: (File) -> Unit) {
|
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 {
|
init {
|
||||||
watchThread
|
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) {
|
watching.getOrPut(path) {
|
||||||
mutableListOf()
|
mutableListOf()
|
||||||
}.add(this)
|
}.add(this)
|
||||||
keyPaths.getOrPut(key) { parent }
|
keyPaths.getOrPut(key) { parent }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
|
watching[path]?.remove(this)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun triggerChange() {
|
internal fun triggerChange() {
|
||||||
program.launch {
|
program.launch {
|
||||||
onChange(file)
|
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 <T> watchFile(program: Program, file: File, transducer: (File) -> T): () -> T {
|
fun <T> watchFile(program: Program, file: File, transducer: (File) -> T): () -> T {
|
||||||
var result = transducer(file)
|
var result = transducer(file)
|
||||||
FileWatcher(program, file) {
|
val watcher = FileWatcher(program, file) {
|
||||||
try {
|
try {
|
||||||
result = transducer(file)
|
result = transducer(file)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
|
val function = {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
watchers[function as ()->Any] = watcher
|
||||||
|
return function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the watcher
|
||||||
|
*/
|
||||||
|
fun <T> (()->T).stop() {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
watchers[this as ()->Any]?.stop()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers reload
|
||||||
|
*/
|
||||||
|
fun <T> (()->T).triggerChange() {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
watchers[this as ()->Any]?.triggerChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@JvmName("programWatchFile")
|
@JvmName("programWatchFile")
|
||||||
fun <T> Program.watchFile(file: File, transducer: (File) -> T): () -> T = watchFile(this, file, transducer)
|
fun <T> Program.watchFile(file: File, transducer: (File) -> T): () -> T = watchFile(this, file, transducer)
|
||||||
|
|
||||||
@@ -67,9 +96,8 @@ private val watchThread by lazy {
|
|||||||
key.pollEvents().forEach {
|
key.pollEvents().forEach {
|
||||||
val contextPath = it.context() as Path
|
val contextPath = it.context() as Path
|
||||||
val fullPath = path?.resolve(contextPath)
|
val fullPath = path?.resolve(contextPath)
|
||||||
watching[fullPath]?.forEach {
|
watching[fullPath]?.forEach { w ->
|
||||||
|
w.triggerChange()
|
||||||
it.triggerChange()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key.reset()
|
key.reset()
|
||||||
@@ -82,12 +110,12 @@ fun main() {
|
|||||||
it.readText()
|
it.readText()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.stop()
|
||||||
|
a.triggerChange()
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
println(a())
|
println(a())
|
||||||
Thread.sleep(2000)
|
Thread.sleep(2000)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user