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
|
* Mutable meta representing object state
|
||||||
*/
|
*/
|
||||||
open class Config : MutableMetaNode<Config>() {
|
open class Config : AbstractMutableMeta<Config>() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach configuration node instead of creating one
|
* Attach configuration node instead of creating one
|
||||||
|
@ -327,7 +327,7 @@ class MutableSafeEnumvDelegate<M : MutableMeta<M>, E : Enum<E>>(
|
|||||||
|
|
||||||
//Child node delegate
|
//Child node delegate
|
||||||
|
|
||||||
class MutableNodeDelegate<M : MutableMetaNode<M>>(
|
class MutableNodeDelegate<M : MutableMeta<M>>(
|
||||||
val meta: M,
|
val meta: M,
|
||||||
private val key: String? = null
|
private val key: String? = null
|
||||||
) : ReadWriteProperty<Any?, Meta?> {
|
) : 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,
|
val meta: M,
|
||||||
private val key: String? = null,
|
private val key: String? = null,
|
||||||
private val converter: (Meta) -> T
|
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) =
|
fun <M : MutableMeta<M>> M.number(default: Number? = null, key: String? = null) =
|
||||||
MutableNumberDelegate(this, key, default)
|
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")
|
@JvmName("safeString")
|
||||||
fun <M : MutableMeta<M>> M.string(default: String, key: String? = null) =
|
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
|
* 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 wrap(name: Name, meta: Meta): MetaBuilder = meta.builder()
|
||||||
override fun empty(): MetaBuilder = MetaBuilder()
|
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
|
* 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 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
|
if (name == this.name) target[name] = item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ data class SelfTransformationRule(val name: Name) : TransformationRule {
|
|||||||
data class SingleItemTransformationRule(
|
data class SingleItemTransformationRule(
|
||||||
val from: Name,
|
val from: Name,
|
||||||
val to: Name,
|
val to: Name,
|
||||||
val transform: MutableMetaNode<*>.(MetaItem<*>?) -> Unit
|
val transform: MutableMeta<*>.(MetaItem<*>?) -> Unit
|
||||||
) : TransformationRule {
|
) : TransformationRule {
|
||||||
override fun matches(name: Name, item: MetaItem<*>?): Boolean {
|
override fun matches(name: Name, item: MetaItem<*>?): Boolean {
|
||||||
return name == from
|
return name == from
|
||||||
@ -55,7 +55,7 @@ data class SingleItemTransformationRule(
|
|||||||
|
|
||||||
override fun selectItems(meta: Meta): Sequence<Name> = sequenceOf(from)
|
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) {
|
if (name == this.from) {
|
||||||
target.transform(item)
|
target.transform(item)
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,13 @@ internal data class MetaListener(
|
|||||||
|
|
||||||
|
|
||||||
interface MutableMeta<M : MutableMeta<M>> : MetaNode<M> {
|
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>>
|
override val items: Map<NameToken, MetaItem<M>>
|
||||||
operator fun set(name: Name, item: MetaItem<M>?)
|
operator fun set(name: Name, item: MetaItem<M>?)
|
||||||
fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit)
|
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.
|
* 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>()
|
private val listeners = HashSet<MetaListener>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,13 +69,6 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : AbstractMetaNode<M>(),
|
|||||||
itemChanged(key.asName(), oldItem, newItem)
|
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
|
* 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) =
|
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: Name, value: Value) =
|
||||||
set(name, MetaItem.ValueItem(value))
|
set(name, MetaItem.ValueItem(value))
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: String, value: Value) =
|
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: String, value: Value) =
|
||||||
set(name.toName(), MetaItem.ValueItem(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(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 : 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) {
|
when (item) {
|
||||||
is MetaItem.ValueItem<*> -> setValue(name, item.value)
|
is MetaItem.ValueItem<*> -> setValue(name, item.value)
|
||||||
is MetaItem.NodeItem<*> -> setNode(name, item.node)
|
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)))
|
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
|
* 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) {
|
when (value) {
|
||||||
null -> remove(name)
|
null -> remove(name)
|
||||||
is MetaItem<*> -> setItem(name, value)
|
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:
|
* 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 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
|
* * 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 ->
|
meta.items.forEach { entry ->
|
||||||
val value = entry.value
|
val value = entry.value
|
||||||
when (value) {
|
when (value) {
|
||||||
@ -153,7 +154,7 @@ fun <M : MutableMetaNode<M>> M.update(meta: Meta) {
|
|||||||
|
|
||||||
/* Same name siblings generation */
|
/* Same name siblings generation */
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> M.setIndexed(
|
fun <M : MutableMeta<M>> M.setIndexedItems(
|
||||||
name: Name,
|
name: Name,
|
||||||
items: Iterable<MetaItem<M>>,
|
items: Iterable<MetaItem<M>>,
|
||||||
indexFactory: MetaItem<M>.(index: Int) -> String = { it.toString() }
|
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,
|
name: Name,
|
||||||
metas: Iterable<Meta>,
|
metas: Iterable<Meta>,
|
||||||
indexFactory: MetaItem<M>.(index: Int) -> String = { it.toString() }
|
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 : MutableMeta<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: String, metas: Iterable<Meta>) = setIndexed(name.toName(), metas)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append the node with a same-name-sibling, automatically generating numerical index
|
* 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" }
|
require(!name.isEmpty()) { "Name could not be empty for append operation" }
|
||||||
val newIndex = name.last()!!.index
|
val newIndex = name.last()!!.index
|
||||||
if (newIndex.isNotEmpty()) {
|
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 base - unchangeable base
|
||||||
* @param style - the style
|
* @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>>
|
override val items: Map<NameToken, MetaItem<Styled>>
|
||||||
get() = (base.items.keys + style.items.keys).associate { key ->
|
get() = (base.items.keys + style.items.keys).associate { key ->
|
||||||
val value = base.items[key]
|
val value = base.items[key]
|
||||||
|
Loading…
Reference in New Issue
Block a user