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 package org.openrndr.extra.olive
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import mu.KotlinLogging
import org.openrndr.Extension import org.openrndr.Extension
import org.openrndr.Program import org.openrndr.Program
import org.openrndr.draw.Session import org.openrndr.draw.Session
import org.openrndr.events.Event import org.openrndr.events.Event
import org.openrndr.launch
import org.operndr.extras.filewatcher.stop import org.operndr.extras.filewatcher.stop
import org.operndr.extras.filewatcher.triggerChange import org.operndr.extras.filewatcher.triggerChange
import org.operndr.extras.filewatcher.watchFile import org.operndr.extras.filewatcher.watchFile
import java.io.File import java.io.File
private val logger = KotlinLogging.logger {}
private fun <T> Event<T>.saveListeners(store: MutableMap<Event<*>, List<(Any) -> Unit>>) { private fun <T> Event<T>.saveListeners(store: MutableMap<Event<*>, List<(Any) -> Unit>>) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
store[this] = listeners.map { it } as List<(Any) -> Unit> 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)) { watcher = program.watchFile(File(script)) {
try { 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.launch {
program.extensions.addAll(originalExtensions) val func = futureFunc.await()
program.extensions.clear()
program.extensions.addAll(originalExtensions)
trackedListeners.forEach { l -> l.restoreListeners(store) } trackedListeners.forEach { l -> l.restoreListeners(store) }
session?.end() session?.end()
session = Session.root.fork() session = Session.root.fork()
@Suppress("UNCHECKED_CAST")
func(program as P)
Unit
}
Unit
@Suppress("UNCHECKED_CAST")
func(program as P)
} catch (e: Throwable) { } catch (e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }

View File

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