Simplified mutable meta hierarchy
This commit is contained in:
parent
cffb02d483
commit
59c46344fa
@ -9,7 +9,7 @@ import hep.dataforge.names.asName
|
||||
/**
|
||||
* Mutable meta representing object state
|
||||
*/
|
||||
open class Config : MutableMetaNode<Config>() {
|
||||
open class Config : AbstractMutableMeta<Config>() {
|
||||
|
||||
/**
|
||||
* Attach configuration node instead of creating one
|
||||
|
@ -327,7 +327,7 @@ class MutableSafeEnumvDelegate<M : MutableMeta<M>, E : Enum<E>>(
|
||||
|
||||
//Child node delegate
|
||||
|
||||
class MutableNodeDelegate<M : MutableMetaNode<M>>(
|
||||
class MutableNodeDelegate<M : MutableMeta<M>>(
|
||||
val meta: M,
|
||||
private val key: String? = null
|
||||
) : ReadWriteProperty<Any?, Meta?> {
|
||||
@ -340,7 +340,7 @@ class MutableNodeDelegate<M : MutableMetaNode<M>>(
|
||||
}
|
||||
}
|
||||
|
||||
class MutableMorphDelegate<M : MutableMetaNode<M>, T : Configurable>(
|
||||
class MutableMorphDelegate<M : MutableMeta<M>, T : Configurable>(
|
||||
val meta: M,
|
||||
private val key: String? = null,
|
||||
private val converter: (Meta) -> T
|
||||
@ -390,7 +390,7 @@ fun <M : MutableMeta<M>> M.boolean(default: Boolean? = null, key: String? = null
|
||||
fun <M : MutableMeta<M>> M.number(default: Number? = null, key: String? = null) =
|
||||
MutableNumberDelegate(this, key, default)
|
||||
|
||||
fun <M : MutableMetaNode<M>> M.node(key: String? = null) = MutableNodeDelegate(this, key)
|
||||
fun <M : MutableMeta<M>> M.node(key: String? = null) = MutableNodeDelegate(this, key)
|
||||
|
||||
@JvmName("safeString")
|
||||
fun <M : MutableMeta<M>> M.string(default: String, key: String? = null) =
|
||||
|
@ -7,7 +7,7 @@ import hep.dataforge.values.Value
|
||||
/**
|
||||
* DSL builder for meta. Is not intended to store mutable state
|
||||
*/
|
||||
class MetaBuilder : MutableMetaNode<MetaBuilder>() {
|
||||
class MetaBuilder : AbstractMutableMeta<MetaBuilder>() {
|
||||
override fun wrap(name: Name, meta: Meta): MetaBuilder = meta.builder()
|
||||
override fun empty(): MetaBuilder = MetaBuilder()
|
||||
|
||||
|
@ -23,7 +23,7 @@ interface TransformationRule {
|
||||
/**
|
||||
* Apply transformation for a single item (Node or Value) and return resulting tree with absolute path
|
||||
*/
|
||||
fun <M : MutableMetaNode<M>> transformItem(name: Name, item: MetaItem<*>?, target: M): Unit
|
||||
fun <M : MutableMeta<M>> 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<Name> = sequenceOf(name)
|
||||
|
||||
override fun <M : MutableMetaNode<M>> transformItem(name: Name, item: MetaItem<*>?, target: M) {
|
||||
override fun <M : MutableMeta<M>> 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<Name> = sequenceOf(from)
|
||||
|
||||
override fun <M : MutableMetaNode<M>> transformItem(name: Name, item: MetaItem<*>?, target: M) {
|
||||
override fun <M : MutableMeta<M>> transformItem(name: Name, item: MetaItem<*>?, target: M) {
|
||||
if (name == this.from) {
|
||||
target.transform(item)
|
||||
}
|
||||
|
@ -10,6 +10,13 @@ internal data class MetaListener(
|
||||
|
||||
|
||||
interface MutableMeta<M : MutableMeta<M>> : MetaNode<M> {
|
||||
/**
|
||||
* 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<NameToken, MetaItem<M>>
|
||||
operator fun set(name: Name, item: MetaItem<M>?)
|
||||
fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit)
|
||||
@ -21,7 +28,7 @@ interface MutableMeta<M : MutableMeta<M>> : MetaNode<M> {
|
||||
*
|
||||
* Changes in Meta are not thread safe.
|
||||
*/
|
||||
abstract class MutableMetaNode<M : MutableMetaNode<M>> : AbstractMetaNode<M>(), MutableMeta<M> {
|
||||
abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(), MutableMeta<M> {
|
||||
private val listeners = HashSet<MetaListener>()
|
||||
|
||||
/**
|
||||
@ -62,13 +69,6 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : AbstractMetaNode<M>(),
|
||||
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 <M : MutableMeta<M>> MutableMeta<M>.remove(name: String) = remove(name.toNam
|
||||
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: Name, value: Value) =
|
||||
set(name, MetaItem.ValueItem(value))
|
||||
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: String, value: Value) =
|
||||
set(name.toName(), MetaItem.ValueItem(value))
|
||||
|
||||
//fun <M : MutableMeta<M>> MutableMeta<M>.setItem(token: NameToken, item: MetaItem<M>?) = set(token.asName(), item)
|
||||
//fun <M : MutableMeta<M>> MutableMeta<M>.setItem(name: String, item: MetaItem<M>) = set(name.toName(), item)
|
||||
|
||||
fun <M : MutableMetaNode<M>> MutableMetaNode<M>.setItem(name: Name, item: MetaItem<*>) {
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setItem(name: Name, item: MetaItem<*>) {
|
||||
when (item) {
|
||||
is MetaItem.ValueItem<*> -> setValue(name, item.value)
|
||||
is MetaItem.NodeItem<*> -> setNode(name, item.node)
|
||||
}
|
||||
}
|
||||
|
||||
fun <M : MutableMetaNode<M>> MutableMetaNode<M>.setItem(name: String, item: MetaItem<*>) = setItem(name.toName(), item)
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setItem(name: String, item: MetaItem<*>) = setItem(name.toName(), item)
|
||||
|
||||
fun <M : MutableMetaNode<M>> MutableMetaNode<M>.setNode(name: Name, node: Meta) =
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setNode(name: Name, node: Meta) =
|
||||
set(name, MetaItem.NodeItem(wrap(name, node)))
|
||||
|
||||
fun <M : MutableMetaNode<M>> MutableMetaNode<M>.setNode(name: String, node: Meta) = setNode(name.toName(), node)
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setNode(name: String, node: Meta) = setNode(name.toName(), node)
|
||||
|
||||
/**
|
||||
* Universal set method
|
||||
*/
|
||||
operator fun <M : MutableMetaNode<M>> MutableMetaNode<M>.set(name: Name, value: Any?) {
|
||||
operator fun <M : MutableMeta<M>> MutableMeta<M>.set(name: Name, value: Any?) {
|
||||
when (value) {
|
||||
null -> remove(name)
|
||||
is MetaItem<*> -> setItem(name, value)
|
||||
@ -130,9 +131,9 @@ operator fun <M : MutableMetaNode<M>> MutableMetaNode<M>.set(name: Name, value:
|
||||
}
|
||||
}
|
||||
|
||||
operator fun <M : MutableMetaNode<M>> M.set(name: NameToken, value: Any?) = set(name.asName(), value)
|
||||
operator fun <M : MutableMeta<M>> M.set(name: NameToken, value: Any?) = set(name.asName(), value)
|
||||
|
||||
operator fun <M : MutableMetaNode<M>> M.set(key: String, value: Any?) = set(key.toName(), value)
|
||||
operator fun <M : MutableMeta<M>> 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 : MutableMetaNode<M>> 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 : MutableMetaNode<M>> M.update(meta: Meta) {
|
||||
fun <M : MutableMeta<M>> M.update(meta: Meta) {
|
||||
meta.items.forEach { entry ->
|
||||
val value = entry.value
|
||||
when (value) {
|
||||
@ -153,7 +154,7 @@ fun <M : MutableMetaNode<M>> M.update(meta: Meta) {
|
||||
|
||||
/* Same name siblings generation */
|
||||
|
||||
fun <M : MutableMeta<M>> M.setIndexed(
|
||||
fun <M : MutableMeta<M>> M.setIndexedItems(
|
||||
name: Name,
|
||||
items: Iterable<MetaItem<M>>,
|
||||
indexFactory: MetaItem<M>.(index: Int) -> String = { it.toString() }
|
||||
@ -167,21 +168,21 @@ fun <M : MutableMeta<M>> M.setIndexed(
|
||||
}
|
||||
}
|
||||
|
||||
fun <M : MutableMetaNode<M>> M.setIndexed(
|
||||
fun <M : MutableMeta<M>> M.setIndexed(
|
||||
name: Name,
|
||||
metas: Iterable<Meta>,
|
||||
indexFactory: MetaItem<M>.(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 : MutableMetaNode<M>> M.set(name: Name, metas: Iterable<Meta>) = setIndexed(name, metas)
|
||||
operator fun <M : MutableMetaNode<M>> M.set(name: String, metas: Iterable<Meta>) = setIndexed(name.toName(), metas)
|
||||
operator fun <M : MutableMeta<M>> M.set(name: Name, metas: Iterable<Meta>) = setIndexed(name, metas)
|
||||
operator fun <M : MutableMeta<M>> M.set(name: String, metas: Iterable<Meta>) = setIndexed(name.toName(), metas)
|
||||
|
||||
/**
|
||||
* Append the node with a same-name-sibling, automatically generating numerical index
|
||||
*/
|
||||
fun <M : MutableMetaNode<M>> M.append(name: Name, value: Any?) {
|
||||
fun <M : MutableMeta<M>> 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 : MutableMetaNode<M>> M.append(name: Name, value: Any?) {
|
||||
}
|
||||
}
|
||||
|
||||
fun <M : MutableMetaNode<M>> M.append(name: String, value: Any?) = append(name.toName(), value)
|
||||
fun <M : MutableMeta<M>> M.append(name: String, value: Any?) = append(name.toName(), value)
|
@ -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<Styled> {
|
||||
class Styled(val base: Meta, val style: Config = Config().empty()) : AbstractMutableMeta<Styled>() {
|
||||
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<NameToken, MetaItem<Styled>>
|
||||
get() = (base.items.keys + style.items.keys).associate { key ->
|
||||
val value = base.items[key]
|
||||
|
Loading…
Reference in New Issue
Block a user