diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt index 00fcec23..f6370942 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt @@ -9,7 +9,7 @@ import hep.dataforge.names.asName /** * Mutable meta representing object state */ -open class Config : MutableMetaNode() { +open class Config : AbstractMutableMeta() { /** * Attach configuration node instead of creating one diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Delegates.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Delegates.kt index 377ec994..bcd60cc8 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Delegates.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Delegates.kt @@ -327,7 +327,7 @@ class MutableSafeEnumvDelegate, E : Enum>( //Child node delegate -class MutableNodeDelegate>( +class MutableNodeDelegate>( val meta: M, private val key: String? = null ) : ReadWriteProperty { @@ -340,7 +340,7 @@ class MutableNodeDelegate>( } } -class MutableMorphDelegate, T : Configurable>( +class MutableMorphDelegate, T : Configurable>( val meta: M, private val key: String? = null, private val converter: (Meta) -> T @@ -390,7 +390,7 @@ fun > M.boolean(default: Boolean? = null, key: String? = null fun > M.number(default: Number? = null, key: String? = null) = MutableNumberDelegate(this, key, default) -fun > M.node(key: String? = null) = MutableNodeDelegate(this, key) +fun > M.node(key: String? = null) = MutableNodeDelegate(this, key) @JvmName("safeString") fun > M.string(default: String, key: String? = null) = diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt index 7debc39b..c8911c60 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt @@ -7,7 +7,7 @@ import hep.dataforge.values.Value /** * DSL builder for meta. Is not intended to store mutable state */ -class MetaBuilder : MutableMetaNode() { +class MetaBuilder : AbstractMutableMeta() { override fun wrap(name: Name, meta: Meta): MetaBuilder = meta.builder() override fun empty(): MetaBuilder = MetaBuilder() diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaTransformation.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaTransformation.kt index 2e00bd11..22a294b1 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaTransformation.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaTransformation.kt @@ -23,7 +23,7 @@ interface TransformationRule { /** * Apply transformation for a single item (Node or Value) and return resulting tree with absolute path */ - fun > transformItem(name: Name, item: MetaItem<*>?, target: M): Unit + fun > transformItem(name: Name, item: MetaItem<*>?, target: M): Unit } /** @@ -36,7 +36,7 @@ data class SelfTransformationRule(val name: Name) : TransformationRule { override fun selectItems(meta: Meta): Sequence = sequenceOf(name) - override fun > transformItem(name: Name, item: MetaItem<*>?, target: M) { + override fun > transformItem(name: Name, item: MetaItem<*>?, target: M) { if (name == this.name) target[name] = item } } @@ -47,7 +47,7 @@ data class SelfTransformationRule(val name: Name) : TransformationRule { data class SingleItemTransformationRule( val from: Name, val to: Name, - val transform: MutableMetaNode<*>.(MetaItem<*>?) -> Unit + val transform: MutableMeta<*>.(MetaItem<*>?) -> Unit ) : TransformationRule { override fun matches(name: Name, item: MetaItem<*>?): Boolean { return name == from @@ -55,7 +55,7 @@ data class SingleItemTransformationRule( override fun selectItems(meta: Meta): Sequence = sequenceOf(from) - override fun > transformItem(name: Name, item: MetaItem<*>?, target: M) { + override fun > transformItem(name: Name, item: MetaItem<*>?, target: M) { if (name == this.from) { target.transform(item) } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt index 000bff7a..83edc56b 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt @@ -10,6 +10,13 @@ internal data class MetaListener( interface MutableMeta> : MetaNode { + /** + * Transform given meta to node type of this meta tree + * @param name the name of the node where meta should be attached. Needed for correct assignment validators and styles + * @param meta the node itself + */ + fun wrap(name: Name, meta: Meta): M + override val items: Map> operator fun set(name: Name, item: MetaItem?) fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit) @@ -21,7 +28,7 @@ interface MutableMeta> : MetaNode { * * Changes in Meta are not thread safe. */ -abstract class MutableMetaNode> : AbstractMetaNode(), MutableMeta { +abstract class AbstractMutableMeta> : AbstractMetaNode(), MutableMeta { private val listeners = HashSet() /** @@ -62,13 +69,6 @@ abstract class MutableMetaNode> : AbstractMetaNode(), itemChanged(key.asName(), oldItem, newItem) } - /** - * Transform given meta to node type of this meta tree - * @param name the name of the node where meta should be attached. Needed for correct assignment validators and styles - * @param meta the node itself - */ - internal abstract fun wrap(name: Name, meta: Meta): M - /** * Create empty node */ @@ -97,30 +97,31 @@ fun > MutableMeta.remove(name: String) = remove(name.toNam fun > MutableMeta.setValue(name: Name, value: Value) = set(name, MetaItem.ValueItem(value)) + fun > MutableMeta.setValue(name: String, value: Value) = set(name.toName(), MetaItem.ValueItem(value)) //fun > MutableMeta.setItem(token: NameToken, item: MetaItem?) = set(token.asName(), item) //fun > MutableMeta.setItem(name: String, item: MetaItem) = set(name.toName(), item) -fun > MutableMetaNode.setItem(name: Name, item: MetaItem<*>) { +fun > MutableMeta.setItem(name: Name, item: MetaItem<*>) { when (item) { is MetaItem.ValueItem<*> -> setValue(name, item.value) is MetaItem.NodeItem<*> -> setNode(name, item.node) } } -fun > MutableMetaNode.setItem(name: String, item: MetaItem<*>) = setItem(name.toName(), item) +fun > MutableMeta.setItem(name: String, item: MetaItem<*>) = setItem(name.toName(), item) -fun > MutableMetaNode.setNode(name: Name, node: Meta) = +fun > MutableMeta.setNode(name: Name, node: Meta) = set(name, MetaItem.NodeItem(wrap(name, node))) -fun > MutableMetaNode.setNode(name: String, node: Meta) = setNode(name.toName(), node) +fun > MutableMeta.setNode(name: String, node: Meta) = setNode(name.toName(), node) /** * Universal set method */ -operator fun > MutableMetaNode.set(name: Name, value: Any?) { +operator fun > MutableMeta.set(name: Name, value: Any?) { when (value) { null -> remove(name) is MetaItem<*> -> setItem(name, value) @@ -130,9 +131,9 @@ operator fun > MutableMetaNode.set(name: Name, value: } } -operator fun > M.set(name: NameToken, value: Any?) = set(name.asName(), value) +operator fun > M.set(name: NameToken, value: Any?) = set(name.asName(), value) -operator fun > M.set(key: String, value: Any?) = set(key.toName(), value) +operator fun > M.set(key: String, value: Any?) = set(key.toName(), value) /** * Update existing mutable node with another node. The rules are following: @@ -140,7 +141,7 @@ operator fun > M.set(key: String, value: Any?) = set(key. * * node updates node and replaces anything but node * * node list updates node list if number of nodes in the list is the same and replaces anything otherwise */ -fun > M.update(meta: Meta) { +fun > M.update(meta: Meta) { meta.items.forEach { entry -> val value = entry.value when (value) { @@ -153,7 +154,7 @@ fun > M.update(meta: Meta) { /* Same name siblings generation */ -fun > M.setIndexed( +fun > M.setIndexedItems( name: Name, items: Iterable>, indexFactory: MetaItem.(index: Int) -> String = { it.toString() } @@ -167,21 +168,21 @@ fun > M.setIndexed( } } -fun > M.setIndexed( +fun > M.setIndexed( name: Name, metas: Iterable, indexFactory: MetaItem.(index: Int) -> String = { it.toString() } ) { - setIndexed(name, metas.map { MetaItem.NodeItem(wrap(name, it)) }, indexFactory) + setIndexedItems(name, metas.map { MetaItem.NodeItem(wrap(name, it)) }, indexFactory) } -operator fun > M.set(name: Name, metas: Iterable) = setIndexed(name, metas) -operator fun > M.set(name: String, metas: Iterable) = setIndexed(name.toName(), metas) +operator fun > M.set(name: Name, metas: Iterable) = setIndexed(name, metas) +operator fun > M.set(name: String, metas: Iterable) = setIndexed(name.toName(), metas) /** * Append the node with a same-name-sibling, automatically generating numerical index */ -fun > M.append(name: Name, value: Any?) { +fun > M.append(name: Name, value: Any?) { require(!name.isEmpty()) { "Name could not be empty for append operation" } val newIndex = name.last()!!.index if (newIndex.isNotEmpty()) { @@ -192,4 +193,4 @@ fun > M.append(name: Name, value: Any?) { } } -fun > M.append(name: String, value: Any?) = append(name.toName(), value) \ No newline at end of file +fun > M.append(name: String, value: Any?) = append(name.toName(), value) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt index dcc36a5a..136c5617 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt @@ -11,7 +11,15 @@ import kotlin.reflect.KProperty * @param base - unchangeable base * @param style - the style */ -class Styled(val base: Meta, val style: Config = Config().empty()) : MutableMeta { +class Styled(val base: Meta, val style: Config = Config().empty()) : AbstractMutableMeta() { + override fun wrap(name: Name, meta: Meta): Styled { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun empty(): Styled { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + override val items: Map> get() = (base.items.keys + style.items.keys).associate { key -> val value = base.items[key]