diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b4b4990..67a704f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added ### Changed +- **API breaking** Descriptor no has a member property `defaultValue` instead of `defaultItem()` extension. It cahces default value state on the first call. It is done because computing default on each call is too expensive. ### Deprecated diff --git a/build.gradle.kts b/build.gradle.kts index 53e618df..ead6c9c2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { allprojects { group = "space.kscience" - version = "0.4.0" + version = "0.4.1" } subprojects { diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index e3572ca2..69e86fb8 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -501,15 +501,11 @@ public abstract interface class space/kscience/dataforge/meta/descriptors/Descri public final class space/kscience/dataforge/meta/descriptors/Described$Companion { } -public final class space/kscience/dataforge/meta/descriptors/DescriptorMetaKt { - public static final fun defaultItem (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)Lspace/kscience/dataforge/meta/TypedMetaItem; - public static final fun defaultMeta (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)Lspace/kscience/dataforge/meta/Laminate; -} - public abstract interface class space/kscience/dataforge/meta/descriptors/ItemDescriptor : space/kscience/dataforge/meta/MetaRepr { public static final field Companion Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor$Companion; public static final field DEFAULT_INDEX_KEY Ljava/lang/String; public abstract fun getAttributes ()Lspace/kscience/dataforge/meta/Meta; + public abstract fun getDefaultValue ()Lspace/kscience/dataforge/meta/TypedMetaItem; public abstract fun getIndexKey ()Ljava/lang/String; public abstract fun getInfo ()Ljava/lang/String; public abstract fun getMultiple ()Z @@ -552,6 +548,7 @@ public final class space/kscience/dataforge/meta/descriptors/ItemDescriptorKt { public abstract interface class space/kscience/dataforge/meta/descriptors/NodeDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor { public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor$Companion; + public fun defaultMeta ()Lspace/kscience/dataforge/meta/Laminate; public abstract fun getDefault ()Lspace/kscience/dataforge/meta/Config; public abstract fun getItems ()Ljava/util/Map; public abstract fun getNodes ()Ljava/util/Map; @@ -570,6 +567,7 @@ public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorBuild public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; public fun build ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; public fun getDefault ()Lspace/kscience/dataforge/meta/Config; + public fun getDefaultValue ()Lspace/kscience/dataforge/meta/TypedMetaItem; public fun getItems ()Ljava/util/Map; public fun getNodes ()Ljava/util/Map; public fun getRequired ()Z @@ -610,6 +608,7 @@ public final class space/kscience/dataforge/meta/descriptors/ValueDescriptorBuil public final fun default (Ljava/lang/Object;)V public fun getAllowedValues ()Ljava/util/List; public fun getDefault ()Lspace/kscience/dataforge/values/Value; + public fun getDefaultValue ()Lspace/kscience/dataforge/meta/TypedMetaItem; public fun getRequired ()Z public fun getType ()Ljava/util/List; public fun isAllowedValue (Lspace/kscience/dataforge/values/Value;)Z 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 07816965..c8118954 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 @@ -1,6 +1,9 @@ package space.kscience.dataforge.meta -import space.kscience.dataforge.meta.descriptors.* +import space.kscience.dataforge.meta.descriptors.Described +import space.kscience.dataforge.meta.descriptors.NodeDescriptor +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.descriptors.validateItem import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName @@ -53,7 +56,7 @@ public open class Scheme() : Described, MetaRepr, ItemPropertyProvider { } private fun getDefaultItem(name: Name): MetaItem? { - return default?.get(name) ?: descriptor?.get(name)?.defaultItem() + return default?.get(name) ?: descriptor?.get(name)?.defaultValue } /** @@ -94,7 +97,7 @@ public open class Scheme() : Described, MetaRepr, ItemPropertyProvider { descriptor?.items?.forEach { (key, itemDescriptor) -> val token = NameToken(key) val name = token.asName() - val item = default?.get(name) ?: itemDescriptor.defaultItem() + val item = default?.get(name) ?: itemDescriptor.defaultValue if (item != null) { put(token, item) } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/DescriptorMeta.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/DescriptorMeta.kt deleted file mode 100644 index 6d44012b..00000000 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/DescriptorMeta.kt +++ /dev/null @@ -1,47 +0,0 @@ -package space.kscience.dataforge.meta.descriptors - -import space.kscience.dataforge.meta.* -import space.kscience.dataforge.names.NameToken - -/** - * A [Meta] that is constructed from [NodeDescriptor] - */ -private class DescriptorMeta(val descriptor: NodeDescriptor) : Meta, MetaBase() { - override val items: Map - get() = buildMap { - descriptor.items.forEach { (token, descriptorItem) -> - val item = descriptorItem.defaultItem() - if (item != null) { - put(NameToken(token), item) - } - } - } -} - -/** - * Generate a laminate representing default item set generated by this descriptor - */ -public fun NodeDescriptor.defaultMeta(): Laminate = Laminate(default, DescriptorMeta(this)) - -/** - * Build a default [MetaItemNode] from this node descriptor - */ -internal fun NodeDescriptor.defaultItem(): MetaItemNode<*> = - MetaItemNode(defaultMeta()) - -/** - * Build a default [MetaItemValue] from this descriptor - */ -internal fun ValueDescriptor.defaultItem(): MetaItemValue? { - return MetaItemValue(default ?: return null) -} - -/** - * Build a default [TypedMetaItem] from descriptor. - */ -public fun ItemDescriptor.defaultItem(): MetaItem? { - return when (this) { - is ValueDescriptor -> defaultItem() - is NodeDescriptor -> defaultItem() - } -} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt index a1a6a595..8e9c4d20 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt @@ -37,6 +37,11 @@ public sealed interface ItemDescriptor: MetaRepr { */ public val indexKey: String + /** + * Compute and cache the default [MetaItem] value described by this descriptor + */ + public val defaultValue: MetaItem? + public companion object { public const val DEFAULT_INDEX_KEY: String = "@index" } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt index e677ea32..ca86e36d 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt @@ -5,6 +5,22 @@ import space.kscience.dataforge.misc.DFBuilder import space.kscience.dataforge.names.* +/** + * A [Meta] that is constructed from [NodeDescriptor] + */ +private class DescriptorMeta(val descriptor: NodeDescriptor) : Meta, MetaBase() { + override val items: Map + get() = buildMap { + descriptor.items.forEach { (token, descriptorItem) -> + val item = descriptorItem.defaultValue + if (item != null) { + put(NameToken(token), item) + } + } + } +} + + /** * Descriptor for meta node. Could contain additional information for viewing * and editing. @@ -12,7 +28,7 @@ import space.kscience.dataforge.names.* * @author Alexander Nozik */ @DFBuilder -public sealed interface NodeDescriptor: ItemDescriptor { +public sealed interface NodeDescriptor : ItemDescriptor { /** * True if the node is required * @@ -42,6 +58,11 @@ public sealed interface NodeDescriptor: ItemDescriptor { */ public val values: Map + /** + * Generate a laminate representing default item set generated by this descriptor + */ + public fun defaultMeta(): Laminate = Laminate(default, DescriptorMeta(this)) + public companion object { internal val ITEM_KEY: Name = "item".asName() @@ -166,6 +187,11 @@ public class NodeDescriptorBuilder(config: Config = Config()) : ItemDescriptorBu value(name.toName(), block) } + /** + * Build a default [MetaItemNode] from this node descriptor + */ + override val defaultValue: MetaItem by lazy { MetaItemNode(defaultMeta()) } + override fun build(): NodeDescriptor = NodeDescriptorBuilder(config.copy()) public companion object { diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt index 6642346f..dd530ed2 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt @@ -131,5 +131,7 @@ public class ValueDescriptorBuilder(config: Config = Config()) : ItemDescriptorB this.allowedValues = v.map { Value.of(it) } } + override val defaultValue: MetaItem? get() = default?.asMetaItem() + override fun build(): ValueDescriptor = ValueDescriptorBuilder(config.copy()) }