From f1e9e7266c75fbc2807929d627b148d259fa3493 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 5 Aug 2017 14:59:15 -0400 Subject: [PATCH] Add script caching --- src/main/kotlin/net/shadowfacts/ekt/EKT.kt | 51 ++++++++++++++------- src/test/kotlin/net/shadowfacts/ekt/Test.kt | 2 +- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/net/shadowfacts/ekt/EKT.kt b/src/main/kotlin/net/shadowfacts/ekt/EKT.kt index 93b1c1e..25ec9d1 100644 --- a/src/main/kotlin/net/shadowfacts/ekt/EKT.kt +++ b/src/main/kotlin/net/shadowfacts/ekt/EKT.kt @@ -40,7 +40,7 @@ _result.toString() manager.getEngineByExtension("kts") } - fun render(template: String, dumpGeneratedScript: File? = null, dataProvider: DataProviderContext.() -> Unit): String { + fun render(template: String, scriptCache: File? = null, data: Map): String { @Suppress("NAME_SHADOWING") var template = template template = template.replace("$", "\${'$'}") @@ -62,21 +62,47 @@ _result.toString() } }) - val script = scriptPrefix + template + scriptSuffix +// Hack to allow data to be accessed by name from template instead of via bindings map + val unwrapBindings = data.keys.map { + val type = data[it]!!.type + "val $it = (bindings[\"$it\"] as net.shadowfacts.ekt.EKT.TypedValue).value as $type" + }.joinToString("\n") - dumpGeneratedScript?.apply { + val script = unwrapBindings + scriptPrefix + template + scriptSuffix + + scriptCache?.apply { + if (!parentFile.exists()) parentFile.mkdirs() if (!exists()) createNewFile() writeText(script) } - val data = DataProviderContext() - data.dataProvider() - - return eval(script, data.map) as String + return eval(script, data) as String } - fun render(template: File, dumpGeneratedScript: File? = null, dataProvider: DataProviderContext.() -> Unit): String { - return render(template.readText(), dumpGeneratedScript, dataProvider) + fun render(template: String, scriptCache: File? = null, dataProvider: DataProviderContext.() -> Unit): String { + val ctx = DataProviderContext() + ctx.dataProvider() + return render(template, scriptCache, ctx.map) + } + + fun render(template: File, scriptCacheDir: File? = null, data: Map): String { + val cacheFile = if (scriptCacheDir != null) { + File(scriptCacheDir, template.nameWithoutExtension + ".kts") + } else { + null + } + + if (cacheFile != null && cacheFile.exists()) { + return eval(cacheFile.readText(), data) as String + } else { + return render(template.readText(), cacheFile, data) + } + } + + fun render(template: File, scriptCacheDir: File? = null, dataProvider: DataProviderContext.() -> Unit): String { + val ctx = DataProviderContext() + ctx.dataProvider() + return render(template, scriptCacheDir, ctx.map) } internal fun eval(script: String, data: Map = mapOf()): Any? { @@ -84,13 +110,6 @@ _result.toString() val bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE) bindings.putAll(data) -// Hack to allow data to be accessed by name from template instead of via bindings map - val unwrapBindings = data.keys.map { - val type = data[it]!!.type - "val $it = (bindings[\"$it\"] as net.shadowfacts.ekt.EKT.TypedValue).value as $type" - }.joinToString("\n") - engine.eval(unwrapBindings) - return engine.eval(script) } diff --git a/src/test/kotlin/net/shadowfacts/ekt/Test.kt b/src/test/kotlin/net/shadowfacts/ekt/Test.kt index 8ad96d9..83989f4 100644 --- a/src/test/kotlin/net/shadowfacts/ekt/Test.kt +++ b/src/test/kotlin/net/shadowfacts/ekt/Test.kt @@ -6,7 +6,7 @@ import java.io.File * @author shadowfacts */ fun main(args: Array) { - val res = EKT.render(File("template.ekt"), dumpGeneratedScript = File("script.kts")) { + val res = EKT.render(File("template.ekt"), scriptCacheDir = File("cache/")) { "list" to (listOf(1, 2, 3) asType "List") }