diff --git a/orx-olive/src/main/kotlin/KtsObjectLoader.kt b/orx-olive/src/main/kotlin/KtsObjectLoader.kt deleted file mode 100644 index 0f1e5f0f..00000000 --- a/orx-olive/src/main/kotlin/KtsObjectLoader.kt +++ /dev/null @@ -1,35 +0,0 @@ -package org.openrndr.extra.olive - -import java.io.InputStream -import java.io.Reader -import javax.script.ScriptEngineManager - -internal class LoadException(message: String? = null, cause: Throwable? = null) : RuntimeException(message, cause) - -internal class KtsObjectLoader(classLoader: ClassLoader? = Thread.currentThread().contextClassLoader) { - - private val engine = ScriptEngineManager(classLoader).getEngineByExtension("kts") - - init { - if (engine == null) { - throw RuntimeException("could not create scripting engine") - } - } - - inline fun safeEval(noinline evaluation: () -> R?) = try { - evaluation() - } catch (e: Exception) { - throw LoadException("Cannot load script", e) - } - - inline fun Any?.castOrError() = takeIf { it is T }?.let { it as T } - ?: throw IllegalArgumentException("Cannot cast $this to expected type ${T::class}") - - inline fun load(script: String): T = safeEval { engine.eval(script) }.castOrError() - - inline fun load(reader: Reader): T = safeEval { engine.eval(reader) }.castOrError() - - inline fun load(inputStream: InputStream): T = load(inputStream.reader()) - - inline fun loadAll(vararg inputStream: InputStream): List = inputStream.map(::load) -} \ No newline at end of file diff --git a/orx-olive/src/main/kotlin/Olive.kt b/orx-olive/src/main/kotlin/Olive.kt index 064fdfcc..79a8d978 100644 --- a/orx-olive/src/main/kotlin/Olive.kt +++ b/orx-olive/src/main/kotlin/Olive.kt @@ -89,15 +89,13 @@ class Olive

(val resources: Resources? = null) : Extension { watcher = program.watchFile(File(script)) { try { - val script = it.readText() - val func = KtsObjectLoader().load Unit>(script) + val func = loadFromScriptUnit>(it) program.extensions.clear() program.extensions.addAll(originalExtensions) trackedListeners.forEach { l -> l.restoreListeners(store) } session?.end() - session = Session.root.fork() @Suppress("UNCHECKED_CAST") diff --git a/orx-olive/src/main/kotlin/ScriptObjectLoader.kt b/orx-olive/src/main/kotlin/ScriptObjectLoader.kt new file mode 100644 index 00000000..1612e0ca --- /dev/null +++ b/orx-olive/src/main/kotlin/ScriptObjectLoader.kt @@ -0,0 +1,59 @@ +package org.openrndr.extra.olive + +import java.io.File +import java.io.InputStream +import java.io.Reader +import java.net.MalformedURLException +import java.net.URL +import javax.script.ScriptEngineManager + +class LoadException(message: String? = null, cause: Throwable? = null) : RuntimeException(message, cause) + +class ScriptObjectLoader(classLoader: ClassLoader? = Thread.currentThread().contextClassLoader) { + val engine = ScriptEngineManager(classLoader).getEngineByExtension("kts") + + init { + require(engine != null) { "could not create scripting engine" } + } + + fun safeEval(evaluation: () -> R?) = try { + evaluation() + } catch (e: Exception) { + throw LoadException("Cannot load script", e) + } + + inline fun Any?.castOrError() = takeIf { it is T }?.let { it as T } + ?: throw IllegalArgumentException("Cannot cast $this to expected type ${T::class}") + + inline fun load(script: String): T = safeEval { engine.eval(script) }.castOrError() + + inline fun load(reader: Reader): T = safeEval { engine.eval(reader) }.castOrError() + + inline fun load(inputStream: InputStream): T = load(inputStream.reader()) + + inline fun loadAll(vararg inputStream: InputStream): List = inputStream.map(::load) +} + +/** + * Load an object from script. + */ +inline fun loadFromScript(fileOrUrl: String, loader: ScriptObjectLoader = ScriptObjectLoader()): T { + val isUrl = try { + URL(fileOrUrl); true + } catch (e: MalformedURLException) { + false + } + + val script = if (isUrl) { + URL(fileOrUrl).readText() + } else { + File(fileOrUrl).readText() + } + return loader.load(script) +} + +/** + * Load an object from script file + */ +inline fun loadFromScript(file: File, loader: ScriptObjectLoader = ScriptObjectLoader()): T = + loader.load(file.readText())