From 991f77c45a82908de5923ce3665ca687945f01b1 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 31 Dec 2023 13:08:30 +0300 Subject: [PATCH] Merge MetaConverter and MetaSpec --- CHANGELOG.md | 1 + .../kscience/dataforge/properties/Property.kt | 2 -- .../kscience/dataforge/meta/MetaConverter.kt | 3 +-- .../kscience/dataforge/meta/MetaDelegate.kt | 20 +++++++------- .../space/kscience/dataforge/meta/MetaSpec.kt | 3 +++ .../kscience/dataforge/meta/ObservableMeta.kt | 26 +++---------------- .../space/kscience/dataforge/meta/Scheme.kt | 22 ++++++++++++++++ .../meta/descriptors/schemeDescriptor.kt | 3 +++ 8 files changed, 44 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6daac6c..7b9586a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Changed - Descriptor `children` renamed to `nodes` +- `MetaConverter` now inherits `MetaSpec` (former `Specifiction`). So `MetaConverter` could be used more universally. ### Deprecated - `node(key,converter)` in favor of `serializable` delegate diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/Property.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/Property.kt index 7b0280eb..b11fb2e1 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/Property.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/Property.kt @@ -1,6 +1,5 @@ package space.kscience.dataforge.properties -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import space.kscience.dataforge.misc.DFExperimental @@ -14,7 +13,6 @@ public interface Property { } @DFExperimental -@OptIn(ExperimentalCoroutinesApi::class) public fun Property.toFlow(): StateFlow = MutableStateFlow(value).also { stateFlow -> onChange { stateFlow.value = it diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaConverter.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaConverter.kt index 0da36d17..933cc13d 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaConverter.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaConverter.kt @@ -183,7 +183,6 @@ public interface MetaConverter: MetaSpec { } } -public fun MetaConverter.readNullable(item: Meta?): T? = item?.let { read(it) } public fun MetaConverter.convertNullable(obj: T?): Meta? = obj?.let { convert(it) } -public fun MetaConverter.readValue(value: Value): T? = read(Meta(value)) + diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaDelegate.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaDelegate.kt index 70ff460d..a24f7371 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaDelegate.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaDelegate.kt @@ -13,13 +13,13 @@ public fun MetaProvider.node(key: Name? = null): ReadOnlyProperty = } /** - * Use [converter] to read the Meta node + * Use [metaSpec] to read the Meta node */ -public fun MetaProvider.convertable( - converter: MetaConverter, +public fun MetaProvider.spec( + metaSpec: MetaSpec, key: Name? = null, ): ReadOnlyProperty = ReadOnlyProperty { _, property -> - get(key ?: property.name.asName())?.let { converter.read(it) } + get(key ?: property.name.asName())?.let { metaSpec.read(it) } } /** @@ -29,19 +29,19 @@ public fun MetaProvider.convertable( public inline fun MetaProvider.serializable( descriptor: MetaDescriptor? = null, key: Name? = null, -): ReadOnlyProperty = convertable(MetaConverter.serializable(descriptor), key) +): ReadOnlyProperty = spec(MetaConverter.serializable(descriptor), key) @Deprecated("Use convertable", ReplaceWith("convertable(converter, key)")) public fun MetaProvider.node( key: Name? = null, - converter: MetaConverter, -): ReadOnlyProperty = convertable(converter, key) + converter: MetaSpec, +): ReadOnlyProperty = spec(converter, key) /** * Use [converter] to convert a list of same name siblings meta to object */ -public fun Meta.listOfConvertable( - converter: MetaConverter, +public fun Meta.listOfSpec( + converter: MetaSpec, key: Name? = null, ): ReadOnlyProperty> = ReadOnlyProperty{_, property -> val name = key ?: property.name.asName() @@ -52,7 +52,7 @@ public fun Meta.listOfConvertable( public inline fun Meta.listOfSerializable( descriptor: MetaDescriptor? = null, key: Name? = null, -): ReadOnlyProperty> = listOfConvertable(MetaConverter.serializable(descriptor), key) +): ReadOnlyProperty> = listOfSpec(MetaConverter.serializable(descriptor), key) /** * A property delegate that uses custom key diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaSpec.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaSpec.kt index be21cef7..9918d504 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaSpec.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MetaSpec.kt @@ -16,3 +16,6 @@ public interface MetaSpec : Described { public fun read(source: Meta): T = readOrNull(source) ?: error("Meta $source could not be interpreted by $this") } + +public fun MetaSpec.readNullable(item: Meta?): T? = item?.let { read(it) } +public fun MetaSpec.readValue(value: Value): T? = read(Meta(value)) diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableMeta.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableMeta.kt index 5a2b05f7..4a3db511 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableMeta.kt @@ -1,8 +1,10 @@ package space.kscience.dataforge.meta import space.kscience.dataforge.misc.ThreadSafe -import space.kscience.dataforge.names.* -import kotlin.reflect.KProperty1 +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.cutFirst +import space.kscience.dataforge.names.firstOrNull +import space.kscience.dataforge.names.isEmpty internal data class MetaListener( @@ -67,24 +69,4 @@ internal abstract class AbstractObservableMeta : ObservableMeta { override fun toString(): String = Meta.toString(this) override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) override fun hashCode(): Int = Meta.hashCode(this) -} - -/** - * Use the value of the property in a [callBack]. - * The callback is called once immediately after subscription to pass the initial value. - * - * Optional [owner] property is used for - */ -public fun S.useProperty( - property: KProperty1, - owner: Any? = null, - callBack: S.(T) -> Unit, -) { - //Pass initial value. - callBack(property.get(this)) - meta.onChange(owner) { name -> - if (name.startsWith(property.name.asName())) { - callBack(property.get(this@useProperty)) - } - } } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt index ff8d8095..1d654ac2 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt @@ -9,6 +9,7 @@ import space.kscience.dataforge.misc.ThreadSafe import space.kscience.dataforge.names.* import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty +import kotlin.reflect.KProperty1 /** * A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [MetaSpec]. @@ -288,3 +289,24 @@ public fun Scheme.listOfScheme( spec: SchemeSpec, key: Name? = null, ): ReadWriteProperty> = meta.listOfScheme(spec, key) + + +/** + * Use the value of the property in a [callBack]. + * The callback is called once immediately after subscription to pass the initial value. + * + * Optional [owner] property is used for + */ +public fun S.useProperty( + property: KProperty1, + owner: Any? = null, + callBack: S.(T) -> Unit, +) { + //Pass initial value. + callBack(property.get(this)) + meta.onChange(owner) { name -> + if (name.startsWith(property.name.asName())) { + callBack(property.get(this@useProperty)) + } + } +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/schemeDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/schemeDescriptor.kt index 803659a6..a2a77182 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/schemeDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/schemeDescriptor.kt @@ -3,9 +3,11 @@ package space.kscience.dataforge.meta.descriptors import space.kscience.dataforge.meta.Scheme import space.kscience.dataforge.meta.SchemeSpec import space.kscience.dataforge.meta.ValueType +import space.kscience.dataforge.misc.DFExperimental import kotlin.reflect.KProperty1 import kotlin.reflect.typeOf +@DFExperimental public inline fun MetaDescriptorBuilder.value( property: KProperty1, noinline block: MetaDescriptorBuilder.() -> Unit = {}, @@ -37,6 +39,7 @@ public inline fun MetaDescriptorBuilder.value( else -> node(property.name, block) } +@DFExperimental public inline fun MetaDescriptorBuilder.scheme( property: KProperty1, spec: SchemeSpec,