Add threaded script loading to orx-olive

This commit is contained in:
Edwin Jakobs
2020-02-08 13:55:10 +01:00
parent c30c71ac0d
commit 26ea9a48f6
2 changed files with 39 additions and 9 deletions

View File

@@ -1,14 +1,21 @@
package org.openrndr.extra.olive
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import mu.KotlinLogging
import org.openrndr.Extension
import org.openrndr.Program
import org.openrndr.draw.Session
import org.openrndr.events.Event
import org.openrndr.launch
import org.operndr.extras.filewatcher.stop
import org.operndr.extras.filewatcher.triggerChange
import org.operndr.extras.filewatcher.watchFile
import java.io.File
private val logger = KotlinLogging.logger {}
private fun <T> Event<T>.saveListeners(store: MutableMap<Event<*>, List<(Any) -> Unit>>) {
@Suppress("UNCHECKED_CAST")
store[this] = listeners.map { it } as List<(Any) -> Unit>
@@ -89,17 +96,30 @@ class Olive<P : Program>(val resources: Resources? = null) : Extension {
watcher = program.watchFile(File(script)) {
try {
val func = loadFromScript<P.()->Unit>(it)
val futureFunc = GlobalScope.async {
val start = System.currentTimeMillis()
val f = loadFromScript<P.() -> Unit>(it)
val end = System.currentTimeMillis()
logger.info { "loading script took ${end - start}ms" }
f
}
program.extensions.clear()
program.extensions.addAll(originalExtensions)
program.launch {
val func = futureFunc.await()
program.extensions.clear()
program.extensions.addAll(originalExtensions)
trackedListeners.forEach { l -> l.restoreListeners(store) }
session?.end()
session = Session.root.fork()
trackedListeners.forEach { l -> l.restoreListeners(store) }
session?.end()
session = Session.root.fork()
@Suppress("UNCHECKED_CAST")
func(program as P)
Unit
}
Unit
@Suppress("UNCHECKED_CAST")
func(program as P)
} catch (e: Throwable) {
e.printStackTrace()
}

View File

@@ -1,5 +1,6 @@
package org.openrndr.extra.olive
import mu.KotlinLogging
import java.io.File
import java.io.InputStream
import java.io.Reader
@@ -7,10 +8,18 @@ import java.net.MalformedURLException
import java.net.URL
import javax.script.ScriptEngineManager
private val logger = KotlinLogging.logger {}
class LoadException(message: String? = null, cause: Throwable? = null) : RuntimeException(message, cause)
class ScriptObjectLoader(classLoader: ClassLoader? = Thread.currentThread().contextClassLoader) {
val engine = ScriptEngineManager(classLoader).getEngineByExtension("kts")
val engine = run {
val start = System.currentTimeMillis()
val engine = ScriptEngineManager(classLoader).getEngineByExtension("kts")
val end = System.currentTimeMillis()
logger.info { "creating scripting engine took ${end-start}ms" }
engine
}
init {
require(engine != null) { "could not create scripting engine" }
@@ -34,6 +43,7 @@ class ScriptObjectLoader(classLoader: ClassLoader? = Thread.currentThread().cont
inline fun <reified T> loadAll(vararg inputStream: InputStream): List<T> = inputStream.map(::load)
}
/**
* Load an object from script.
*/