Add script caching

This commit is contained in:
Shadowfacts 2017-08-05 14:59:15 -04:00
parent 05b7cd3892
commit f1e9e7266c
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
2 changed files with 36 additions and 17 deletions

View File

@ -40,7 +40,7 @@ _result.toString()
manager.getEngineByExtension("kts") manager.getEngineByExtension("kts")
} }
fun render(template: String, dumpGeneratedScript: File? = null, dataProvider: DataProviderContext.() -> Unit): String { fun render(template: String, scriptCache: File? = null, data: Map<String, TypedValue>): String {
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
var template = template var template = template
template = template.replace("$", "\${'$'}") 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() if (!exists()) createNewFile()
writeText(script) writeText(script)
} }
val data = DataProviderContext() return eval(script, data) as String
data.dataProvider()
return eval(script, data.map) as String
} }
fun render(template: File, dumpGeneratedScript: File? = null, dataProvider: DataProviderContext.() -> Unit): String { fun render(template: String, scriptCache: File? = null, dataProvider: DataProviderContext.() -> Unit): String {
return render(template.readText(), dumpGeneratedScript, dataProvider) val ctx = DataProviderContext()
ctx.dataProvider()
return render(template, scriptCache, ctx.map)
}
fun render(template: File, scriptCacheDir: File? = null, data: Map<String, TypedValue>): 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<String, TypedValue> = mapOf()): Any? { internal fun eval(script: String, data: Map<String, TypedValue> = mapOf()): Any? {
@ -84,13 +110,6 @@ _result.toString()
val bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE) val bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE)
bindings.putAll(data) 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) return engine.eval(script)
} }

View File

@ -6,7 +6,7 @@ import java.io.File
* @author shadowfacts * @author shadowfacts
*/ */
fun main(args: Array<String>) { fun main(args: Array<String>) {
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<Int>") "list" to (listOf(1, 2, 3) asType "List<Int>")
} }