Add action delegate for task creation
This commit is contained in:
parent
8f3c2f3950
commit
5e3de70737
@ -10,7 +10,6 @@ import space.kscience.dataforge.misc.ThreadSafe
|
|||||||
import space.kscience.dataforge.names.*
|
import space.kscience.dataforge.names.*
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.coroutines.coroutineContext
|
|
||||||
import kotlin.reflect.KType
|
import kotlin.reflect.KType
|
||||||
import kotlin.reflect.typeOf
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
@ -21,7 +20,7 @@ public interface DataSourceBuilder<T : Any> : DataSetBuilder<T>, DataSource<T> {
|
|||||||
/**
|
/**
|
||||||
* A mutable [DataTree] that propagates updates
|
* A mutable [DataTree] that propagates updates
|
||||||
*/
|
*/
|
||||||
public class DataTreeBuilder<T : Any>(
|
public class DataTreeBuilder<T : Any> internal constructor(
|
||||||
override val dataType: KType,
|
override val dataType: KType,
|
||||||
coroutineContext: CoroutineContext,
|
coroutineContext: CoroutineContext,
|
||||||
) : DataTree<T>, DataSourceBuilder<T> {
|
) : DataTree<T>, DataSourceBuilder<T> {
|
||||||
@ -100,19 +99,14 @@ public class DataTreeBuilder<T : Any>(
|
|||||||
public fun <T : Any> DataSource(
|
public fun <T : Any> DataSource(
|
||||||
type: KType,
|
type: KType,
|
||||||
parent: CoroutineScope,
|
parent: CoroutineScope,
|
||||||
block: DataSourceBuilder<T>.() -> Unit,
|
block: DataSourceBuilder<T>.() -> Unit = {},
|
||||||
): DataTreeBuilder<T> = DataTreeBuilder<T>(type, parent.coroutineContext).apply(block)
|
): DataTreeBuilder<T> = DataTreeBuilder<T>(type, parent.coroutineContext).apply(block)
|
||||||
|
|
||||||
@Suppress("OPT_IN_USAGE", "FunctionName")
|
@Suppress("OPT_IN_USAGE", "FunctionName")
|
||||||
public inline fun <reified T : Any> DataSource(
|
public inline fun <reified T : Any> DataSource(
|
||||||
parent: CoroutineScope,
|
parent: CoroutineScope,
|
||||||
crossinline block: DataSourceBuilder<T>.() -> Unit,
|
|
||||||
): DataTreeBuilder<T> = DataSource(typeOf<T>(), parent) { block() }
|
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
public suspend inline fun <reified T : Any> DataSource(
|
|
||||||
crossinline block: DataSourceBuilder<T>.() -> Unit = {},
|
crossinline block: DataSourceBuilder<T>.() -> Unit = {},
|
||||||
): DataTreeBuilder<T> = DataTreeBuilder<T>(typeOf<T>(), coroutineContext).apply { block() }
|
): DataTreeBuilder<T> = DataSource(typeOf<T>(), parent) { block() }
|
||||||
|
|
||||||
public inline fun <reified T : Any> DataSourceBuilder<T>.emit(
|
public inline fun <reified T : Any> DataSourceBuilder<T>.emit(
|
||||||
name: Name,
|
name: Name,
|
||||||
|
@ -65,13 +65,11 @@ internal class StaticDataTree<T : Any>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
public inline fun <T : Any> DataTree(
|
public inline fun <T : Any> DataTree(
|
||||||
dataType: KType,
|
dataType: KType,
|
||||||
block: DataSetBuilder<T>.() -> Unit,
|
block: DataSetBuilder<T>.() -> Unit,
|
||||||
): DataTree<T> = StaticDataTree<T>(dataType).apply { block() }
|
): DataTree<T> = StaticDataTree<T>(dataType).apply { block() }
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
public inline fun <reified T : Any> DataTree(
|
public inline fun <reified T : Any> DataTree(
|
||||||
noinline block: DataSetBuilder<T>.() -> Unit,
|
noinline block: DataSetBuilder<T>.() -> Unit,
|
||||||
): DataTree<T> = DataTree(typeOf<T>(), block)
|
): DataTree<T> = DataTree(typeOf<T>(), block)
|
||||||
|
@ -29,7 +29,7 @@ internal class ActionsTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDynamicMapAction() = runTest {
|
fun testDynamicMapAction() = runTest {
|
||||||
val data: DataSourceBuilder<Int> = DataSource()
|
val data: DataSourceBuilder<Int> = DataSource(this)
|
||||||
|
|
||||||
val plusOne = Action.mapping<Int, Int> {
|
val plusOne = Action.mapping<Int, Int> {
|
||||||
result { it + 1 }
|
result { it + 1 }
|
||||||
|
@ -56,7 +56,7 @@ internal class DataTreeBuilderTest {
|
|||||||
try {
|
try {
|
||||||
lateinit var updateJob: Job
|
lateinit var updateJob: Job
|
||||||
supervisorScope {
|
supervisorScope {
|
||||||
val subNode = DataSource<Int> {
|
val subNode = DataSource<Int>(this) {
|
||||||
updateJob = launch {
|
updateJob = launch {
|
||||||
repeat(10) {
|
repeat(10) {
|
||||||
delay(10)
|
delay(10)
|
||||||
@ -70,7 +70,7 @@ internal class DataTreeBuilderTest {
|
|||||||
println(it)
|
println(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val rootNode = DataSource<Int> {
|
val rootNode = DataSource<Int>(this) {
|
||||||
setAndWatch("sub".asName(), subNode)
|
setAndWatch("sub".asName(), subNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
package space.kscience.dataforge.workspace
|
package space.kscience.dataforge.workspace
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import space.kscience.dataforge.actions.Action
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.ContextBuilder
|
import space.kscience.dataforge.context.ContextBuilder
|
||||||
import space.kscience.dataforge.context.Global
|
import space.kscience.dataforge.context.Global
|
||||||
import space.kscience.dataforge.data.*
|
import space.kscience.dataforge.data.DataSet
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.data.DataSource
|
||||||
import space.kscience.dataforge.meta.MetaRepr
|
import space.kscience.dataforge.data.DataSourceBuilder
|
||||||
import space.kscience.dataforge.meta.MetaSpec
|
import space.kscience.dataforge.meta.*
|
||||||
import space.kscience.dataforge.meta.MutableMeta
|
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptorBuilder
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptorBuilder
|
||||||
import space.kscience.dataforge.misc.DFBuilder
|
import space.kscience.dataforge.misc.DFBuilder
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
@ -45,6 +44,9 @@ public inline fun <reified T : Any> TaskContainer.registerTask(
|
|||||||
noinline builder: suspend TaskResultBuilder<T>.() -> Unit,
|
noinline builder: suspend TaskResultBuilder<T>.() -> Unit,
|
||||||
): Unit = registerTask(Name.parse(name), Task(MetaDescriptor(descriptorBuilder), builder))
|
): Unit = registerTask(Name.parse(name), Task(MetaDescriptor(descriptorBuilder), builder))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new t
|
||||||
|
*/
|
||||||
public inline fun <reified T : Any> TaskContainer.buildTask(
|
public inline fun <reified T : Any> TaskContainer.buildTask(
|
||||||
name: String,
|
name: String,
|
||||||
descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {},
|
descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {},
|
||||||
@ -67,6 +69,9 @@ public inline fun <reified T : Any> TaskContainer.task(
|
|||||||
ReadOnlyProperty { _, _ -> TaskReference(taskName, task) }
|
ReadOnlyProperty { _, _ -> TaskReference(taskName, task) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a task based on [MetaSpec]
|
||||||
|
*/
|
||||||
public inline fun <reified T : Any, C : MetaRepr> TaskContainer.task(
|
public inline fun <reified T : Any, C : MetaRepr> TaskContainer.task(
|
||||||
specification: MetaSpec<C>,
|
specification: MetaSpec<C>,
|
||||||
noinline builder: suspend TaskResultBuilder<T>.(C) -> Unit,
|
noinline builder: suspend TaskResultBuilder<T>.(C) -> Unit,
|
||||||
@ -77,15 +82,34 @@ public inline fun <reified T : Any, C : MetaRepr> TaskContainer.task(
|
|||||||
ReadOnlyProperty { _, _ -> TaskReference(taskName, task) }
|
ReadOnlyProperty { _, _ -> TaskReference(taskName, task) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A delegate to create a custom task
|
||||||
|
*/
|
||||||
public inline fun <reified T : Any> TaskContainer.task(
|
public inline fun <reified T : Any> TaskContainer.task(
|
||||||
noinline descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {},
|
noinline descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {},
|
||||||
noinline builder: suspend TaskResultBuilder<T>.() -> Unit,
|
noinline builder: suspend TaskResultBuilder<T>.() -> Unit,
|
||||||
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, TaskReference<T>>> =
|
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, TaskReference<T>>> =
|
||||||
task(MetaDescriptor(descriptorBuilder), builder)
|
task(MetaDescriptor(descriptorBuilder), builder)
|
||||||
|
|
||||||
public class WorkspaceBuilder(private val parentContext: Context = Global) : TaskContainer {
|
/**
|
||||||
|
* A delegate for creating a task based on [action]
|
||||||
|
*/
|
||||||
|
public inline fun <T : Any, reified R : Any> TaskContainer.action(
|
||||||
|
selector: DataSelector<T>,
|
||||||
|
action: Action<T, R>,
|
||||||
|
noinline metaTransform: MutableMeta.()-> Unit = {},
|
||||||
|
noinline descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {},
|
||||||
|
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, TaskReference<R>>> =
|
||||||
|
task(MetaDescriptor(descriptorBuilder)) {
|
||||||
|
result(action.execute(from(selector), taskMeta.copy(metaTransform)))
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WorkspaceBuilder(
|
||||||
|
private val parentContext: Context = Global,
|
||||||
|
private val coroutineScope: CoroutineScope = parentContext,
|
||||||
|
) : TaskContainer {
|
||||||
private var context: Context? = null
|
private var context: Context? = null
|
||||||
private var data: DataSet<*>? = null
|
private val data = DataSource<Any>(coroutineScope)
|
||||||
private val targets: HashMap<String, Meta> = HashMap()
|
private val targets: HashMap<String, Meta> = HashMap()
|
||||||
private val tasks = HashMap<Name, Task<*>>()
|
private val tasks = HashMap<Name, Task<*>>()
|
||||||
private var cache: WorkspaceCache? = null
|
private var cache: WorkspaceCache? = null
|
||||||
@ -100,13 +124,8 @@ public class WorkspaceBuilder(private val parentContext: Context = Global) : Tas
|
|||||||
/**
|
/**
|
||||||
* Define intrinsic data for the workspace
|
* Define intrinsic data for the workspace
|
||||||
*/
|
*/
|
||||||
public fun data(builder: DataSetBuilder<Any>.() -> Unit) {
|
public fun data(builder: DataSourceBuilder<Any>.() -> Unit) {
|
||||||
data = DataTree(builder)
|
data.apply(builder)
|
||||||
}
|
|
||||||
|
|
||||||
@DFExperimental
|
|
||||||
public fun data(scope: CoroutineScope, builder: DataSourceBuilder<Any>.() -> Unit) {
|
|
||||||
data = DataSource(scope, builder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,7 +151,7 @@ public class WorkspaceBuilder(private val parentContext: Context = Global) : Tas
|
|||||||
val postProcess: suspend (TaskResult<*>) -> TaskResult<*> = { result ->
|
val postProcess: suspend (TaskResult<*>) -> TaskResult<*> = { result ->
|
||||||
cache?.evaluate(result) ?: result
|
cache?.evaluate(result) ?: result
|
||||||
}
|
}
|
||||||
return WorkspaceImpl(context ?: parentContext, data ?: DataSet.EMPTY, targets, tasks, postProcess)
|
return WorkspaceImpl(context ?: parentContext, data, targets, tasks, postProcess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user