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

@@ -39,4 +39,4 @@ For example if you want to use the `orx-no-clear` artifact one would use:
dependencies {
compile 'com.github.openrndr.orx:orx-no-clear:v0.0.20'
}
```
```

View File

@@ -1,67 +1,67 @@
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.10'
}
allprojects {
group 'org.openrndr.extra'
version '0.0.20'
}
repositories {
mavenLocal()
mavenCentral()
}
ext {
openrndrVersion = "0.3.32-rc4"
}
subprojects {
apply plugin: 'kotlin'
apply plugin: 'maven'
apply plugin: 'maven-publish'
repositories {
mavenLocal()
mavenCentral()
maven {
url = "https://dl.bintray.com/openrndr/openrndr"
}
}
dependencies {
compile "org.openrndr:openrndr-core:$openrndrVersion"
compile "org.openrndr:openrndr-filter:$openrndrVersion"
compile "org.openrndr:openrndr-shape:$openrndrVersion"
compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '1.0.1'
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar
}
}
}
task sourceJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.kotlin
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.10'
}
allprojects {
group 'org.openrndr.extra'
version '0.0.22'
}
repositories {
mavenLocal()
mavenCentral()
}
ext {
openrndrVersion = "0.3.33-rc1"
}
subprojects {
apply plugin: 'kotlin'
apply plugin: 'maven'
apply plugin: 'maven-publish'
repositories {
mavenLocal()
mavenCentral()
maven {
url = "https://dl.bintray.com/openrndr/openrndr"
}
}
dependencies {
compile "org.openrndr:openrndr-core:$openrndrVersion"
compile "org.openrndr:openrndr-filter:$openrndrVersion"
compile "org.openrndr:openrndr-shape:$openrndrVersion"
compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '1.0.1'
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar
}
}
}
task sourceJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.kotlin
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}

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',
'orx-compositor',
'orx-file-watcher',
'orx-filter-extension',
'orx-integral-image',
'orx-jumpflood',
@@ -13,3 +14,4 @@ include 'orx-camera',