From 950ec6ac7d2d6a9f948bbcfc5f726e78a6d2b82d Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Thu, 27 Feb 2020 13:05:40 +0100 Subject: [PATCH] Add support for resolving shader phrases from delegated properties --- .../src/main/kotlin/PhraseResource.kt | 23 +++++++++++++++++++ .../src/main/kotlin/ShaderPreprocessor.kt | 9 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 orx-shader-phrases/src/main/kotlin/PhraseResource.kt diff --git a/orx-shader-phrases/src/main/kotlin/PhraseResource.kt b/orx-shader-phrases/src/main/kotlin/PhraseResource.kt new file mode 100644 index 00000000..056bcb6f --- /dev/null +++ b/orx-shader-phrases/src/main/kotlin/PhraseResource.kt @@ -0,0 +1,23 @@ +package org.openrndr.extra.shaderphrases + +import org.openrndr.resourceUrl +import java.net.URL +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty + + +/** + * PhraseResource can be used as a delegate + */ +class PhraseResource(private val resourceUrl: String) : ReadOnlyProperty { + override fun getValue(thisRef: R, property: KProperty<*>): String { + return URL(resourceUrl).readText() + } +} + +/** + * PhraseResource delegate builder function + */ +fun phraseResource(resource: String) : PhraseResource { + return PhraseResource(resourceUrl(resource)) +} \ No newline at end of file diff --git a/orx-shader-phrases/src/main/kotlin/ShaderPreprocessor.kt b/orx-shader-phrases/src/main/kotlin/ShaderPreprocessor.kt index 21ac77b8..61465c2b 100644 --- a/orx-shader-phrases/src/main/kotlin/ShaderPreprocessor.kt +++ b/orx-shader-phrases/src/main/kotlin/ShaderPreprocessor.kt @@ -21,13 +21,20 @@ fun preprocessShader(source: String): String { val packageClass = packageClassTokens.joinToString(".") try { + /* Note that JVM-style reflection is used here because of short-comings in the Kotlin reflection + library (as of 1.3.61), most notably reflection support for file facades is missing. */ val c = Class.forName(packageClass) if (c.annotations.any { it.annotationClass == ShaderPhrases::class }) { if (fieldName == "*") { + c.declaredMethods.filter { it.returnType.name == "java.lang.String" }.map { + "/* imported from $packageClass.$it */\n${it.invoke(null)}\n" + }.joinToString("\n") + + c.declaredFields.filter { it.type.name == "java.lang.String" }.map { - "/* imported from $packageClass.$it */\n ${it.get(null)}" + "/* imported from $packageClass.$it */\n${it.get(null)}\n" }.joinToString("\n") } else { + // TODO add method based phrase resolver like in the wildcard case above. try { c.getDeclaredField(fieldName).get(null) } catch (e: NoSuchFieldException) {