diff --git a/CHANGELOG.md b/CHANGELOG.md index abf5789..b4de4b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - Device lifecycle message - Low-code constructor +- Automatic description generation for spec properties (JVM only) ### Changed - Property caching moved from core `Device` to the `CachingDevice` diff --git a/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DeviceSpec.kt b/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DeviceSpec.kt index 19e5ab2..cd0d7cc 100644 --- a/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DeviceSpec.kt +++ b/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DeviceSpec.kt @@ -51,7 +51,12 @@ public abstract class DeviceSpec { PropertyDelegateProvider { _: DeviceSpec, property -> val propertyName = name ?: property.name val deviceProperty = object : DevicePropertySpec { - override val descriptor: PropertyDescriptor = PropertyDescriptor(propertyName).apply(descriptorBuilder) + + override val descriptor: PropertyDescriptor = PropertyDescriptor(propertyName).apply { + fromSpec(property) + descriptorBuilder() + } + override val converter: MetaConverter = converter override suspend fun read(device: D): T? = @@ -76,7 +81,10 @@ public abstract class DeviceSpec { override val descriptor: PropertyDescriptor = PropertyDescriptor( propertyName, mutable = true - ).apply(descriptorBuilder) + ).apply { + fromSpec(property) + descriptorBuilder() + } override val converter: MetaConverter = converter override suspend fun read(device: D): T? = @@ -108,7 +116,10 @@ public abstract class DeviceSpec { PropertyDelegateProvider { _: DeviceSpec, property: KProperty<*> -> val actionName = name ?: property.name val deviceAction = object : DeviceActionSpec { - override val descriptor: ActionDescriptor = ActionDescriptor(actionName).apply(descriptorBuilder) + override val descriptor: ActionDescriptor = ActionDescriptor(actionName).apply { + fromSpec(property) + descriptorBuilder() + } override val inputConverter: MetaConverter = inputConverter override val outputConverter: MetaConverter = outputConverter diff --git a/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/fromSpec.kt b/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/fromSpec.kt new file mode 100644 index 0000000..000458e --- /dev/null +++ b/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/fromSpec.kt @@ -0,0 +1,12 @@ +package space.kscience.controls.spec + +import space.kscience.controls.api.ActionDescriptor +import space.kscience.controls.api.PropertyDescriptor +import kotlin.reflect.KProperty + +@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FIELD) +public annotation class Description(val content: String) + +internal expect fun PropertyDescriptor.fromSpec(property: KProperty<*>) + +internal expect fun ActionDescriptor.fromSpec(property: KProperty<*>) \ No newline at end of file diff --git a/controls-core/src/jsMain/kotlin/space/kscience/controls/spec/fromSpec.js.kt b/controls-core/src/jsMain/kotlin/space/kscience/controls/spec/fromSpec.js.kt new file mode 100644 index 0000000..cd77248 --- /dev/null +++ b/controls-core/src/jsMain/kotlin/space/kscience/controls/spec/fromSpec.js.kt @@ -0,0 +1,9 @@ +package space.kscience.controls.spec + +import space.kscience.controls.api.ActionDescriptor +import space.kscience.controls.api.PropertyDescriptor +import kotlin.reflect.KProperty + +internal actual fun PropertyDescriptor.fromSpec(property: KProperty<*>){} + +internal actual fun ActionDescriptor.fromSpec(property: KProperty<*>){} \ No newline at end of file diff --git a/controls-core/src/jvmMain/kotlin/space/kscience/controls/spec/fromSpec.jvm.kt b/controls-core/src/jvmMain/kotlin/space/kscience/controls/spec/fromSpec.jvm.kt new file mode 100644 index 0000000..7ae572f --- /dev/null +++ b/controls-core/src/jvmMain/kotlin/space/kscience/controls/spec/fromSpec.jvm.kt @@ -0,0 +1,18 @@ +package space.kscience.controls.spec + +import space.kscience.controls.api.ActionDescriptor +import space.kscience.controls.api.PropertyDescriptor +import kotlin.reflect.KProperty +import kotlin.reflect.full.findAnnotation + +internal actual fun PropertyDescriptor.fromSpec(property: KProperty<*>) { + property.findAnnotation()?.let { + description = it.content + } +} + +internal actual fun ActionDescriptor.fromSpec(property: KProperty<*>){ + property.findAnnotation()?.let { + description = it.content + } +} \ No newline at end of file diff --git a/controls-core/src/jvmMain/kotlin/space/kscience/controls/spec/propertyReflection.kt b/controls-core/src/jvmMain/kotlin/space/kscience/controls/spec/propertyReflection.kt deleted file mode 100644 index 1d4cb56..0000000 --- a/controls-core/src/jvmMain/kotlin/space/kscience/controls/spec/propertyReflection.kt +++ /dev/null @@ -1,8 +0,0 @@ -package space.kscience.controls.spec - -import space.kscience.controls.api.PropertyDescriptor -import kotlin.reflect.KProperty - -internal fun PropertyDescriptor.fromSpec(property: KProperty<*>){ - property.annotations -} \ No newline at end of file diff --git a/controls-core/src/nativeMain/kotlin/space/kscience/controls/spec/fromSpec.native.kt b/controls-core/src/nativeMain/kotlin/space/kscience/controls/spec/fromSpec.native.kt new file mode 100644 index 0000000..1d1ccc4 --- /dev/null +++ b/controls-core/src/nativeMain/kotlin/space/kscience/controls/spec/fromSpec.native.kt @@ -0,0 +1,9 @@ +package space.kscience.controls.spec + +import space.kscience.controls.api.ActionDescriptor +import space.kscience.controls.api.PropertyDescriptor +import kotlin.reflect.KProperty + +internal actual fun PropertyDescriptor.fromSpec(property: KProperty<*>) {} + +internal actual fun ActionDescriptor.fromSpec(property: KProperty<*>){} \ No newline at end of file