All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.space.kscience.dataforge.data.Data.kt Maven / Gradle / Ivy

There is a newer version: 0.7.0
Show newest version
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