Merge MetaConverter and MetaSpec
This commit is contained in:
parent
fd1d98aa87
commit
991f77c45a
@ -9,6 +9,7 @@
|
||||
|
||||
### Changed
|
||||
- Descriptor `children` renamed to `nodes`
|
||||
- `MetaConverter` now inherits `MetaSpec` (former `Specifiction`). So `MetaConverter` could be used more universally.
|
||||
|
||||
### Deprecated
|
||||
- `node(key,converter)` in favor of `serializable` delegate
|
||||
|
@ -1,6 +1,5 @@
|
||||
package space.kscience.dataforge.properties
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
@ -14,7 +13,6 @@ public interface Property<T> {
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
public fun <T> Property<T>.toFlow(): StateFlow<T> = MutableStateFlow(value).also { stateFlow ->
|
||||
onChange {
|
||||
stateFlow.value = it
|
||||
|
@ -183,7 +183,6 @@ public interface MetaConverter<T>: MetaSpec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T : Any> MetaConverter<T>.readNullable(item: Meta?): T? = item?.let { read(it) }
|
||||
public fun <T : Any> MetaConverter<T>.convertNullable(obj: T?): Meta? = obj?.let { convert(it) }
|
||||
|
||||
public fun <T> MetaConverter<T>.readValue(value: Value): T? = read(Meta(value))
|
||||
|
||||
|
@ -13,13 +13,13 @@ public fun MetaProvider.node(key: Name? = null): ReadOnlyProperty<Any?, Meta?> =
|
||||
}
|
||||
|
||||
/**
|
||||
* Use [converter] to read the Meta node
|
||||
* Use [metaSpec] to read the Meta node
|
||||
*/
|
||||
public fun <T> MetaProvider.convertable(
|
||||
converter: MetaConverter<T>,
|
||||
public fun <T> MetaProvider.spec(
|
||||
metaSpec: MetaSpec<T>,
|
||||
key: Name? = null,
|
||||
): ReadOnlyProperty<Any?, T?> = ReadOnlyProperty { _, property ->
|
||||
get(key ?: property.name.asName())?.let { converter.read(it) }
|
||||
get(key ?: property.name.asName())?.let { metaSpec.read(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,19 +29,19 @@ public fun <T> MetaProvider.convertable(
|
||||
public inline fun <reified T> MetaProvider.serializable(
|
||||
descriptor: MetaDescriptor? = null,
|
||||
key: Name? = null,
|
||||
): ReadOnlyProperty<Any?, T?> = convertable(MetaConverter.serializable(descriptor), key)
|
||||
): ReadOnlyProperty<Any?, T?> = spec(MetaConverter.serializable(descriptor), key)
|
||||
|
||||
@Deprecated("Use convertable", ReplaceWith("convertable(converter, key)"))
|
||||
public fun <T> MetaProvider.node(
|
||||
key: Name? = null,
|
||||
converter: MetaConverter<T>,
|
||||
): ReadOnlyProperty<Any?, T?> = convertable(converter, key)
|
||||
converter: MetaSpec<T>,
|
||||
): ReadOnlyProperty<Any?, T?> = spec(converter, key)
|
||||
|
||||
/**
|
||||
* Use [converter] to convert a list of same name siblings meta to object
|
||||
*/
|
||||
public fun <T> Meta.listOfConvertable(
|
||||
converter: MetaConverter<T>,
|
||||
public fun <T> Meta.listOfSpec(
|
||||
converter: MetaSpec<T>,
|
||||
key: Name? = null,
|
||||
): ReadOnlyProperty<Any?, List<T>> = ReadOnlyProperty{_, property ->
|
||||
val name = key ?: property.name.asName()
|
||||
@ -52,7 +52,7 @@ public fun <T> Meta.listOfConvertable(
|
||||
public inline fun <reified T> Meta.listOfSerializable(
|
||||
descriptor: MetaDescriptor? = null,
|
||||
key: Name? = null,
|
||||
): ReadOnlyProperty<Any?, List<T>> = listOfConvertable(MetaConverter.serializable(descriptor), key)
|
||||
): ReadOnlyProperty<Any?, List<T>> = listOfSpec(MetaConverter.serializable(descriptor), key)
|
||||
|
||||
/**
|
||||
* A property delegate that uses custom key
|
||||
|
@ -16,3 +16,6 @@ public interface MetaSpec<out T> : Described {
|
||||
public fun read(source: Meta): T = readOrNull(source) ?: error("Meta $source could not be interpreted by $this")
|
||||
}
|
||||
|
||||
|
||||
public fun <T : Any> MetaSpec<T>.readNullable(item: Meta?): T? = item?.let { read(it) }
|
||||
public fun <T> MetaSpec<T>.readValue(value: Value): T? = read(Meta(value))
|
||||
|
@ -1,8 +1,10 @@
|
||||
package space.kscience.dataforge.meta
|
||||
|
||||
import space.kscience.dataforge.misc.ThreadSafe
|
||||
import space.kscience.dataforge.names.*
|
||||
import kotlin.reflect.KProperty1
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.cutFirst
|
||||
import space.kscience.dataforge.names.firstOrNull
|
||||
import space.kscience.dataforge.names.isEmpty
|
||||
|
||||
|
||||
internal data class MetaListener(
|
||||
@ -67,24 +69,4 @@ internal abstract class AbstractObservableMeta : ObservableMeta {
|
||||
override fun toString(): String = Meta.toString(this)
|
||||
override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta)
|
||||
override fun hashCode(): Int = Meta.hashCode(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the value of the property in a [callBack].
|
||||
* The callback is called once immediately after subscription to pass the initial value.
|
||||
*
|
||||
* Optional [owner] property is used for
|
||||
*/
|
||||
public fun <S : Scheme, T> S.useProperty(
|
||||
property: KProperty1<S, T>,
|
||||
owner: Any? = null,
|
||||
callBack: S.(T) -> Unit,
|
||||
) {
|
||||
//Pass initial value.
|
||||
callBack(property.get(this))
|
||||
meta.onChange(owner) { name ->
|
||||
if (name.startsWith(property.name.asName())) {
|
||||
callBack(property.get(this@useProperty))
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import space.kscience.dataforge.misc.ThreadSafe
|
||||
import space.kscience.dataforge.names.*
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
/**
|
||||
* A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [MetaSpec].
|
||||
@ -288,3 +289,24 @@ public fun <T : Scheme> Scheme.listOfScheme(
|
||||
spec: SchemeSpec<T>,
|
||||
key: Name? = null,
|
||||
): ReadWriteProperty<Any?, List<T>> = meta.listOfScheme(spec, key)
|
||||
|
||||
|
||||
/**
|
||||
* Use the value of the property in a [callBack].
|
||||
* The callback is called once immediately after subscription to pass the initial value.
|
||||
*
|
||||
* Optional [owner] property is used for
|
||||
*/
|
||||
public fun <S : Scheme, T> S.useProperty(
|
||||
property: KProperty1<S, T>,
|
||||
owner: Any? = null,
|
||||
callBack: S.(T) -> Unit,
|
||||
) {
|
||||
//Pass initial value.
|
||||
callBack(property.get(this))
|
||||
meta.onChange(owner) { name ->
|
||||
if (name.startsWith(property.name.asName())) {
|
||||
callBack(property.get(this@useProperty))
|
||||
}
|
||||
}
|
||||
}
|
@ -3,9 +3,11 @@ package space.kscience.dataforge.meta.descriptors
|
||||
import space.kscience.dataforge.meta.Scheme
|
||||
import space.kscience.dataforge.meta.SchemeSpec
|
||||
import space.kscience.dataforge.meta.ValueType
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import kotlin.reflect.KProperty1
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
@DFExperimental
|
||||
public inline fun <S : Scheme, reified T> MetaDescriptorBuilder.value(
|
||||
property: KProperty1<S, T>,
|
||||
noinline block: MetaDescriptorBuilder.() -> Unit = {},
|
||||
@ -37,6 +39,7 @@ public inline fun <S : Scheme, reified T> MetaDescriptorBuilder.value(
|
||||
else -> node(property.name, block)
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public inline fun <S : Scheme, reified T : Scheme> MetaDescriptorBuilder.scheme(
|
||||
property: KProperty1<S, T>,
|
||||
spec: SchemeSpec<T>,
|
||||
|
Loading…
Reference in New Issue
Block a user