Meta subtyping and get by empty name.
This commit is contained in:
parent
effac131de
commit
f9ae9348e2
@ -66,8 +66,14 @@ interface Meta : MetaRepr {
|
|||||||
|
|
||||||
/* Get operations*/
|
/* Get operations*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform recursive item search using given [name]. Each [NameToken] is treated as a name in [Meta.items] of a parent node.
|
||||||
|
*
|
||||||
|
* If [name] is empty reture current [Meta] as a [NodeItem]
|
||||||
|
*/
|
||||||
operator fun Meta?.get(name: Name): MetaItem<*>? {
|
operator fun Meta?.get(name: Name): MetaItem<*>? {
|
||||||
if (this == null) return null
|
if (this == null) return null
|
||||||
|
if (name.isEmpty()) return NodeItem(this)
|
||||||
return name.first()?.let { token ->
|
return name.first()?.let { token ->
|
||||||
val tail = name.cutFirst()
|
val tail = name.cutFirst()
|
||||||
when (tail.length) {
|
when (tail.length) {
|
||||||
@ -78,6 +84,9 @@ operator fun Meta?.get(name: Name): MetaItem<*>? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token)
|
operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token)
|
||||||
|
/**
|
||||||
|
* Parse [Name] from [key] using full name notation and pass it to [Meta.get]
|
||||||
|
*/
|
||||||
operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName())
|
operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,12 +122,16 @@ operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem<*>>> = sequence().ite
|
|||||||
/**
|
/**
|
||||||
* A meta node that ensures that all of its descendants has at least the same type
|
* A meta node that ensures that all of its descendants has at least the same type
|
||||||
*/
|
*/
|
||||||
interface MetaNode<M : MetaNode<M>> : Meta {
|
interface MetaNode<out M : MetaNode<M>> : Meta {
|
||||||
override val items: Map<NameToken, MetaItem<M>>
|
override val items: Map<NameToken, MetaItem<M>>
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun <M : MetaNode<M>> MetaNode<M>?.get(name: Name): MetaItem<M>? {
|
/**
|
||||||
|
* The same as [Meta.get], but with specific node type
|
||||||
|
*/
|
||||||
|
operator fun <M : MetaNode<M>> M?.get(name: Name): MetaItem<M>? {
|
||||||
if (this == null) return null
|
if (this == null) return null
|
||||||
|
if (name.isEmpty()) return NodeItem(this)
|
||||||
return name.first()?.let { token ->
|
return name.first()?.let { token ->
|
||||||
val tail = name.cutFirst()
|
val tail = name.cutFirst()
|
||||||
when (tail.length) {
|
when (tail.length) {
|
||||||
@ -128,17 +141,9 @@ operator fun <M : MetaNode<M>> MetaNode<M>?.get(name: Name): MetaItem<M>? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun <M : MetaNode<M>> MetaNode<M>?.get(key: String): MetaItem<M>? = if (this == null) {
|
operator fun <M : MetaNode<M>> M?.get(key: String): MetaItem<M>? = this[key.toName()]
|
||||||
null
|
|
||||||
} else {
|
|
||||||
this[key.toName()]
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun <M : MetaNode<M>> MetaNode<M>?.get(key: NameToken): MetaItem<M>? = if (this == null) {
|
operator fun <M : MetaNode<M>> M?.get(key: NameToken): MetaItem<M>? = this[key.asName()]
|
||||||
null
|
|
||||||
} else {
|
|
||||||
this[key.asName()]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Equals, hashcode and to string for any meta
|
* Equals, hashcode and to string for any meta
|
||||||
|
@ -3,7 +3,7 @@ package hep.dataforge.meta
|
|||||||
import hep.dataforge.names.*
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
|
|
||||||
interface MutableMeta<M : MutableMeta<M>> : MetaNode<M> {
|
interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M> {
|
||||||
override val items: Map<NameToken, MetaItem<M>>
|
override val items: Map<NameToken, MetaItem<M>>
|
||||||
operator fun set(name: Name, item: MetaItem<*>?)
|
operator fun set(name: Name, item: MetaItem<*>?)
|
||||||
// fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit)
|
// fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit)
|
||||||
@ -54,13 +54,14 @@ abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(),
|
|||||||
0 -> error("Can't setValue meta item for empty name")
|
0 -> error("Can't setValue meta item for empty name")
|
||||||
1 -> {
|
1 -> {
|
||||||
val token = name.first()!!
|
val token = name.first()!!
|
||||||
replaceItem(token, get(name), wrapItem(item))
|
@Suppress("UNCHECKED_CAST") val oldItem: MetaItem<M>? = get(name) as? MetaItem<M>
|
||||||
|
replaceItem(token, oldItem, wrapItem(item))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val token = name.first()!!
|
val token = name.first()!!
|
||||||
//get existing or create new node. Query is ignored for new node
|
//get existing or create new node. Query is ignored for new node
|
||||||
if(items[token] == null){
|
if (items[token] == null) {
|
||||||
replaceItem(token,null, MetaItem.NodeItem(empty()))
|
replaceItem(token, null, MetaItem.NodeItem(empty()))
|
||||||
}
|
}
|
||||||
items[token]?.node!![name.cutFirst()] = item
|
items[token]?.node!![name.cutFirst()] = item
|
||||||
}
|
}
|
||||||
@ -71,6 +72,7 @@ abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(),
|
|||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun MutableMeta<*>.remove(name: Name) = set(name, null)
|
inline fun MutableMeta<*>.remove(name: Name) = set(name, null)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun MutableMeta<*>.remove(name: String) = remove(name.toName())
|
inline fun MutableMeta<*>.remove(name: String) = remove(name.toName())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user