
commonMain.space.kscience.dataforge.data.Data.kt Maven / Gradle / Ivy
package space.kscience.dataforge.data
import kotlinx.coroutines.*
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MetaRepr
import space.kscience.dataforge.meta.isEmpty
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.misc.Type
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KType
import kotlin.reflect.typeOf
/**
* A data element characterized by its meta
*/
@Type(Data.TYPE)
public interface Data : Goal, MetaRepr {
/**
* Type marker for the data. The type is known before the calculation takes place so it could be checked.
*/
public val type: KType
/**
* Meta for the data
*/
public val meta: Meta
override fun toMeta(): Meta = Meta {
"type" put (type.toString())
if (!meta.isEmpty()) {
"meta" put meta
}
}
public companion object {
public const val TYPE: String = "data"
/**
* The type that can't have any subtypes
*/
internal val TYPE_OF_NOTHING: KType = typeOf()
public inline fun static(
value: T,
meta: Meta = Meta.EMPTY,
): Data = StaticData(typeOf(), value, meta)
/**
* An empty data containing only meta
*/
@OptIn(DelicateCoroutinesApi::class)
public fun empty(meta: Meta): Data = object : Data {
override val type: KType = TYPE_OF_NOTHING
override val meta: Meta = meta
override val dependencies: Collection> = emptyList()
override val deferred: Deferred
get() = GlobalScope.async(start = CoroutineStart.LAZY) {
error("The Data is empty and could not be computed")
}
override fun async(coroutineScope: CoroutineScope): Deferred = deferred
override fun reset() {}
}
}
}
/**
* A lazily computed variant of [Data] based on [LazyGoal]
* One must ensure that proper [type] is used so this method should not be used
*/
private class LazyData(
override val type: KType,
override val meta: Meta = Meta.EMPTY,
additionalContext: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection> = emptyList(),
block: suspend () -> T,
) : Data, LazyGoal(additionalContext, dependencies, block)
public class StaticData(
override val type: KType,
value: T,
override val meta: Meta = Meta.EMPTY,
) : Data, StaticGoal(value)
@Suppress("FunctionName")
@DFInternal
public fun Data(
type: KType,
meta: Meta = Meta.EMPTY,
context: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection> = emptyList(),
block: suspend () -> T,
): Data = LazyData(type, meta, context, dependencies, block)
@OptIn(DFInternal::class)
@Suppress("FunctionName")
public inline fun Data(
meta: Meta = Meta.EMPTY,
context: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection> = emptyList(),
noinline block: suspend () -> T,
): Data = Data(typeOf(), meta, context, dependencies, block)
© 2015 - 2025 Weber Informatics LLC | Privacy Policy