diff --git a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/SimpleWorkspace.kt b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/SimpleWorkspace.kt index 7e881a8f..e800d8b3 100644 --- a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/SimpleWorkspace.kt +++ b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/SimpleWorkspace.kt @@ -17,7 +17,7 @@ public class SimpleWorkspace( private val externalTasks: Map>, ) : Workspace { - override val data: TaskResult<*> = internalize(data, Name.EMPTY, Meta.EMPTY) + override val data: TaskResult<*> = wrapResult(data, Name.EMPTY, Meta.EMPTY) override val tasks: Map> get() = context.gather>(Task.TYPE) + externalTasks diff --git a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/Task.kt b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/Task.kt index 965f859e..dcf63db2 100644 --- a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/Task.kt +++ b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/Task.kt @@ -28,7 +28,7 @@ public interface Task : Described { public suspend fun execute(workspace: Workspace, taskName: Name, taskMeta: Meta): TaskResult public companion object { - public const val TYPE: String = "workspace.stage" + public const val TYPE: String = "workspace.task" } } @@ -42,6 +42,10 @@ public class TaskResultBuilder( /** * Create a [Task] that composes a result using [builder]. Only data from the workspace could be used. * Data dependency cycles are not allowed. + * + * @param resultType the type boundary for data produced by this task + * @param descriptor of meta accepted by this task + * @param builder for resulting data set */ @Suppress("FunctionName") @DFInternal @@ -60,9 +64,9 @@ public fun Task( ): TaskResult = withContext(GoalExecutionRestriction() + workspace.goalLogger) { //TODO use safe builder and check for external data on add and detects cycles val dataset = DataTree(resultType) { - TaskResultBuilder(workspace,taskName, taskMeta, this).apply { builder() } + TaskResultBuilder(workspace, taskName, taskMeta, this).apply { builder() } } - workspace.internalize(dataset, taskName, taskMeta) + workspace.wrapResult(dataset, taskName, taskMeta) } } diff --git a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/TaskData.kt b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/TaskData.kt index ff501600..6d14616d 100644 --- a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/TaskData.kt +++ b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/TaskData.kt @@ -42,6 +42,6 @@ private class TaskDataImpl( // } } -internal fun Workspace.internalize(data: Data, name: Name, stage: Name, stageMeta: Meta): TaskData = +internal fun Workspace.wrapResult(data: Data, name: Name, stage: Name, stageMeta: Meta): TaskData = TaskDataImpl(this, data, name, stage, stageMeta) diff --git a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/TaskResult.kt b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/TaskResult.kt index d0097e55..61e4c650 100644 --- a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/TaskResult.kt +++ b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/TaskResult.kt @@ -37,13 +37,16 @@ private class TaskResultImpl( ) : TaskResult, DataSet by dataSet { override fun flow(): Flow> = dataSet.flow().map { - workspace.internalize(it, it.name, taskName, taskMeta) + workspace.wrapResult(it, it.name, taskName, taskMeta) } override suspend fun getData(name: Name): TaskData? = dataSet.getData(name)?.let { - workspace.internalize(it, name, taskName, taskMeta) + workspace.wrapResult(it, name, taskName, taskMeta) } } -internal fun Workspace.internalize(dataSet: DataSet, stage: Name, stageMeta: Meta): TaskResult = - TaskResultImpl(this, dataSet, stage, stageMeta) \ No newline at end of file +/** + * Wrap data into [TaskResult] + */ +public fun Workspace.wrapResult(dataSet: DataSet, taskName: Name, taskMeta: Meta): TaskResult = + TaskResultImpl(this, dataSet, taskName, taskMeta) \ No newline at end of file diff --git a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/Workspace.kt b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/Workspace.kt index e5458258..bc2eb7dd 100644 --- a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/Workspace.kt +++ b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/Workspace.kt @@ -1,6 +1,7 @@ package space.kscience.dataforge.workspace import space.kscience.dataforge.context.ContextAware +import space.kscience.dataforge.data.DataSet import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.misc.Type @@ -8,6 +9,10 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.provider.Provider +public interface DataSelector{ + public suspend fun select(workspace: Workspace, meta: Meta): DataSet +} + @Type(Workspace.TYPE) public interface Workspace : ContextAware, Provider { /** diff --git a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/WorkspaceBuilder.kt b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/WorkspaceBuilder.kt index 423a1807..72a35da7 100644 --- a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/WorkspaceBuilder.kt +++ b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/WorkspaceBuilder.kt @@ -17,7 +17,18 @@ import space.kscience.dataforge.names.Name import kotlin.properties.PropertyDelegateProvider import kotlin.properties.ReadOnlyProperty -public data class TaskReference(public val taskName: Name, public val task: Task) +public data class TaskReference(public val taskName: Name, public val task: Task): DataSelector{ + + @Suppress("UNCHECKED_CAST") + override suspend fun select(workspace: Workspace, meta: Meta): DataSet { + if (workspace.tasks[taskName] == task) { + return workspace.produce(taskName, meta) as TaskResult + } else { + error("Task $taskName does not belong to the workspace") + } + } + +} public interface TaskContainer { public fun registerTask(taskName: Name, task: Task<*>) diff --git a/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/taskBuilders.kt b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/taskBuilders.kt new file mode 100644 index 00000000..bcfeae32 --- /dev/null +++ b/dataforge-workspace/src/commonMain/kotlin/space/kscience/dataforge/workspace/taskBuilders.kt @@ -0,0 +1,9 @@ +package space.kscience.dataforge.workspace + +import space.kscience.dataforge.data.DataSet +import space.kscience.dataforge.meta.Meta + +public suspend fun TaskResultBuilder<*>.from( + selector: DataSelector, + meta: Meta = Meta.EMPTY, +): DataSet = selector.select(workspace, meta) diff --git a/dataforge-workspace/src/jvmMain/kotlin/space/kscience/dataforge/workspace/taskBuilders.kt b/dataforge-workspace/src/jvmMain/kotlin/space/kscience/dataforge/workspace/taskBuilders.kt deleted file mode 100644 index d5ab5313..00000000 --- a/dataforge-workspace/src/jvmMain/kotlin/space/kscience/dataforge/workspace/taskBuilders.kt +++ /dev/null @@ -1,24 +0,0 @@ -package space.kscience.dataforge.workspace - -import space.kscience.dataforge.data.DataSet -import space.kscience.dataforge.data.select -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.names.Name - -public suspend inline fun TaskResultBuilder.from( - task: Name, - taskMeta: Meta = Meta.EMPTY, -): DataSet = workspace.produce(task, taskMeta).select() - - -@Suppress("UNCHECKED_CAST") -public suspend fun TaskResultBuilder<*>.from( - reference: TaskReference, - taskMeta: Meta = Meta.EMPTY, -): DataSet { - if (workspace.tasks[reference.taskName] == reference.task) { - return workspace.produce(reference.taskName, taskMeta) as TaskResult - } else { - throw error("Task ${reference.taskName} does not belong to the workspace") - } -} diff --git a/dataforge-workspace/src/jvmMain/kotlin/space/kscience/dataforge/workspace/workspaceExtensions.kt b/dataforge-workspace/src/jvmMain/kotlin/space/kscience/dataforge/workspace/workspaceExtensions.kt index 543b0da1..2690a8f6 100644 --- a/dataforge-workspace/src/jvmMain/kotlin/space/kscience/dataforge/workspace/workspaceExtensions.kt +++ b/dataforge-workspace/src/jvmMain/kotlin/space/kscience/dataforge/workspace/workspaceExtensions.kt @@ -1,8 +1,17 @@ package space.kscience.dataforge.workspace import kotlinx.coroutines.runBlocking +import space.kscience.dataforge.data.DataSet import space.kscience.dataforge.data.DataSetBuilder +import space.kscience.dataforge.data.select +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.names.Name public fun WorkspaceBuilder.data(builder: suspend DataSetBuilder.() -> Unit): Unit = runBlocking { buildData(builder) -} \ No newline at end of file +} + +public suspend inline fun TaskResultBuilder<*>.from( + task: Name, + taskMeta: Meta = Meta.EMPTY, +): DataSet = workspace.produce(task, taskMeta).select() \ No newline at end of file