Add orx-file-monitor

This commit is contained in:
Edwin Jakobs
2019-03-29 16:59:16 +01:00
parent 3e289b289b
commit a88c53abea
5 changed files with 199 additions and 67 deletions

View File

@@ -4,7 +4,7 @@ plugins {
allprojects { allprojects {
group 'org.openrndr.extra' group 'org.openrndr.extra'
version '0.0.20' version '0.0.22'
} }
repositories { repositories {
@@ -13,7 +13,7 @@ repositories {
} }
ext { ext {
openrndrVersion = "0.3.32-rc4" openrndrVersion = "0.3.33-rc1"
} }
subprojects { subprojects {

View File

@@ -0,0 +1,37 @@
# orx-file-watcher
A file watcher for OPENRNDR
## Usage
Monitoring a single file.
```kotlin
application {
program {
val watchedText = watchFile(File("someFile.txt")) {
it.readText()
}
extend {
val theText = watchedText()
}
}
}
```
Making a map of monitored files.
```kotlin
application {
program {
val watchedTexts = mutableMap<String, ()->String>()
watchedTexts["text"] = watchFile(File("someFile.txt")) {
it.readText()
}
extend {
val theText = watchedTexts.getValue("text")()
}
}
}
```

View File

@@ -0,0 +1,93 @@
package org.operndr.extras.filewatcher
import com.sun.nio.file.SensitivityWatchEventModifier
import org.openrndr.Program
import org.openrndr.launch
import java.io.File
import java.nio.file.FileSystems
import java.nio.file.Path
import java.nio.file.StandardWatchEventKinds
import java.nio.file.WatchKey
import kotlin.concurrent.thread
class FileWatcher(private val program: Program, val file: File, private val onChange: (File) -> Unit) {
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 }
}
internal fun triggerChange() {
program.launch {
onChange(file)
}
}
}
fun <T> watchFile(program: Program, file: File, transducer: (File) -> T): () -> T {
var result = transducer(file)
FileWatcher(program, file) {
try {
result = transducer(file)
} catch (e: Throwable) {
e.printStackTrace()
}
}
return {
result
}
}
@JvmName("programWatchFile")
fun <T> Program.watchFile(file: File, transducer: (File) -> T): () -> T = watchFile(this, file, transducer)
private val watching = mutableMapOf<Path, MutableList<FileWatcher>>()
private val pathKeys = mutableMapOf<Path, WatchKey>()
private val keyPaths = mutableMapOf<WatchKey, Path>()
private val watchService by lazy {
FileSystems.getDefault().newWatchService()
}
private val watchThread by lazy {
thread(isDaemon = true) {
while (true) {
val key = watchService.take()
val path = keyPaths[key]
key.pollEvents().forEach {
val contextPath = it.context() as Path
val fullPath = path?.resolve(contextPath)
watching[fullPath]?.forEach {
it.triggerChange()
}
}
key.reset()
}
}
}
fun main() {
val a = watchFile(Program(), File("README.md")) {
it.readText()
}
while (true) {
println(a())
Thread.sleep(2000)
}
}

View File

@@ -2,6 +2,7 @@ rootProject.name = 'orx'
include 'orx-camera', include 'orx-camera',
'orx-compositor', 'orx-compositor',
'orx-file-watcher',
'orx-filter-extension', 'orx-filter-extension',
'orx-integral-image', 'orx-integral-image',
'orx-jumpflood', 'orx-jumpflood',
@@ -13,3 +14,4 @@ include 'orx-camera',