Experimenting on Task builder and inner contexts

This commit is contained in:
Alexander Nozik 2019-03-28 09:56:11 +03:00
parent 7ce45f4ab1
commit 929f1b9d69
7 changed files with 39 additions and 33 deletions

View File

@ -45,7 +45,7 @@ allprojects {
} }
group = "hep.dataforge" group = "hep.dataforge"
version = "0.1.2-dev-1" version = "0.1.2-dev-2"
// apply bintray configuration // apply bintray configuration
apply(from = "${rootProject.rootDir}/gradle/bintray.gradle") apply(from = "${rootProject.rootDir}/gradle/bintray.gradle")
@ -67,8 +67,6 @@ subprojects {
// classifier = "javadoc" // classifier = "javadoc"
// } // }
apply(plugin = "com.moowork.node")
// Create empty jar for sources classifier to satisfy maven requirements // Create empty jar for sources classifier to satisfy maven requirements
val stubSources by tasks.registering(Jar::class) { val stubSources by tasks.registering(Jar::class) {
archiveClassifier.set("sources") archiveClassifier.set("sources")
@ -89,6 +87,7 @@ subprojects {
afterEvaluate { afterEvaluate {
extensions.findByType<KotlinMultiplatformExtension>()?.apply { extensions.findByType<KotlinMultiplatformExtension>()?.apply {
apply(plugin = "com.moowork.node")
jvm { jvm {
compilations.all { compilations.all {
kotlinOptions { kotlinOptions {

View File

@ -16,7 +16,7 @@ class JoinGroup<T : Any, R : Any>(var name: String, internal val node: DataNode<
var meta: MetaBuilder = MetaBuilder() var meta: MetaBuilder = MetaBuilder()
lateinit var result: suspend ActionEnv.(Map<Name, T>) -> R var result: suspend ActionEnv.(Map<Name, T>) -> R = TODO("Action not implemented")
fun result(f: suspend ActionEnv.(Map<Name, T>) -> R) { fun result(f: suspend ActionEnv.(Map<Name, T>) -> R) {
this.result = f; this.result = f;

View File

@ -14,7 +14,7 @@ class ActionEnv(val name: Name, val meta: Meta)
* Action environment * Action environment
*/ */
class PipeBuilder<T, R>(var name: Name, var meta: MetaBuilder) { class PipeBuilder<T, R>(var name: Name, var meta: MetaBuilder) {
lateinit var result: suspend ActionEnv.(T) -> R; var result: suspend ActionEnv.(T) -> R = TODO("Action not implemented")
/** /**
* Calculate the result of goal * Calculate the result of goal

View File

@ -14,7 +14,7 @@ import kotlin.reflect.full.isSuperclassOf
class FragmentRule<T : Any, R : Any>(val name: Name, var meta: MetaBuilder) { class FragmentRule<T : Any, R : Any>(val name: Name, var meta: MetaBuilder) {
lateinit var result: suspend (T) -> R var result: suspend (T) -> R = TODO("Action not implemented")
fun result(f: suspend (T) -> R) { fun result(f: suspend (T) -> R) {
result = f; result = f;

View File

@ -34,8 +34,6 @@ class DynamicMeta(val obj: dynamic) : Meta {
private fun isArray(obj: dynamic): Boolean = js("Array.isArray(obj)") as Boolean private fun isArray(obj: dynamic): Boolean = js("Array.isArray(obj)") as Boolean
//private fun isObject(obj: dynamic): Boolean = js("typeof obj === 'object'") as Boolean
private fun asItem(obj: dynamic): MetaItem<DynamicMeta>? { private fun asItem(obj: dynamic): MetaItem<DynamicMeta>? {
if (obj == null) return MetaItem.ValueItem(Null) if (obj == null) return MetaItem.ValueItem(Null)
return when (jsTypeOf(obj)) { return when (jsTypeOf(obj)) {

View File

@ -10,6 +10,7 @@ class DynamicMetaTest {
fun testDynamicMeta() { fun testDynamicMeta() {
val d = js("{}") val d = js("{}")
d.a = 22 d.a = 22
d.array = arrayOf(1,2,3)
d.b = "myString" d.b = "myString"
d.ob = js("{}") d.ob = js("{}")
d.ob.childNode = 18 d.ob.childNode = 18
@ -17,6 +18,7 @@ class DynamicMetaTest {
val meta = DynamicMeta(d) val meta = DynamicMeta(d)
assertEquals(true, meta["ob.booleanNode"].boolean) assertEquals(true, meta["ob.booleanNode"].boolean)
assertEquals(2,meta["array[1]"].int)
} }
} }

View File

@ -8,15 +8,17 @@ import hep.dataforge.meta.node
import hep.dataforge.meta.string import hep.dataforge.meta.string
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.toName import hep.dataforge.names.toName
import mu.KotlinLogging
import kotlin.reflect.KClass import kotlin.reflect.KClass
//data class TaskEnv(val workspace: Workspace, val model: TaskModel)
class GenericTask<R : Any>( class GenericTask<R : Any>(
override val name: String, override val name: String,
override val type: KClass<out R>, override val type: KClass<out R>,
override val descriptor: NodeDescriptor, override val descriptor: NodeDescriptor,
private val modelTransform: TaskModelBuilder.(Meta) -> Unit, private val modelTransform: TaskModelBuilder.(Meta) -> Unit,
private val dataTransform: TaskModel.(DataNode<Any>) -> DataNode<R> private val dataTransform: Workspace.() -> TaskModel.(DataNode<Any>) -> DataNode<R>
) : Task<R> { ) : Task<R> {
private fun gather(workspace: Workspace, model: TaskModel): DataNode<Any> { private fun gather(workspace: Workspace, model: TaskModel): DataNode<Any> {
@ -36,7 +38,7 @@ class GenericTask<R : Any>(
//execute //execute
workspace.context.logger.info("Starting task '$name' on ${model.target} with meta: \n${model.meta}") workspace.context.logger.info("Starting task '$name' on ${model.target} with meta: \n${model.meta}")
val output = dataTransform.invoke(model, input) val output = dataTransform(workspace).invoke(model, input)
//handle result //handle result
//output.handle(model.context.dispatcher) { this.handle(it) } //output.handle(model.context.dispatcher) { this.handle(it) }
@ -65,18 +67,21 @@ class KTaskBuilder(val name: String) {
private var modelTransform: TaskModelBuilder.(Meta) -> Unit = { data("*") } private var modelTransform: TaskModelBuilder.(Meta) -> Unit = { data("*") }
var descriptor: NodeDescriptor? = null var descriptor: NodeDescriptor? = null
/**
* TODO will look better as extension class
*/
private class DataTransformation( private class DataTransformation(
val from: String = "", val from: String = "",
val to: String = "", val to: String = "",
val transform: TaskModel.(DataNode<Any>) -> DataNode<Any> val transform: Workspace.() -> TaskModel.(DataNode<Any>) -> DataNode<Any>
) { ) {
operator fun invoke(model: TaskModel, node: DataNode<Any>): DataNode<Any>? { operator fun Workspace.invoke(model: TaskModel, node: DataNode<Any>): DataNode<Any>? {
val localData = if (from.isEmpty()) { val localData = if (from.isEmpty()) {
node node
} else { } else {
node.getNode(from.toName()) ?: return null node.getNode(from.toName()) ?: return null
} }
return transform.invoke(model, localData); return transform(this).invoke(model, localData)
} }
} }
@ -90,7 +95,7 @@ class KTaskBuilder(val name: String) {
inputType: KClass<T>, inputType: KClass<T>,
from: String = "", from: String = "",
to: String = "", to: String = "",
transform: TaskModel.(DataNode<T>) -> DataNode<Any> transform: Workspace.() -> TaskModel.(DataNode<T>) -> DataNode<Any>
) { ) {
dataTransforms += DataTransformation(from, to) { data: DataNode<Any> -> dataTransforms += DataTransformation(from, to) { data: DataNode<Any> ->
transform.invoke(this, data.cast(inputType)) transform.invoke(this, data.cast(inputType))
@ -100,7 +105,7 @@ class KTaskBuilder(val name: String) {
inline fun <reified T : Any> transform( inline fun <reified T : Any> transform(
from: String = "", from: String = "",
to: String = "", to: String = "",
noinline transform: TaskModel.(DataNode<T>) -> DataNode<Any> noinline transform: Workspace.() -> TaskModel.(DataNode<T>) -> DataNode<Any>
) { ) {
transform(T::class, from, to, transform) transform(T::class, from, to, transform)
} }
@ -110,7 +115,7 @@ class KTaskBuilder(val name: String) {
*/ */
inline fun <reified T : Any, reified R : Any> action(action: Action<T, R>, from: String = "", to: String = "") { inline fun <reified T : Any, reified R : Any> action(action: Action<T, R>, from: String = "", to: String = "") {
transform(from, to) { data: DataNode<T> -> transform(from, to) { data: DataNode<T> ->
action(data, meta) action(data, model.meta)
} }
} }
@ -189,27 +194,29 @@ class KTaskBuilder(val name: String) {
} }
fun build(): GenericTask<Any> { fun build(): GenericTask<Any> {
val transform: TaskModel.(DataNode<Any>) -> DataNode<Any> = { data -> val transform: Workspace.() -> TaskModel.(DataNode<Any>) -> DataNode<Any> = {
if (dataTransforms.isEmpty()) { { data ->
//return data node as is if (dataTransforms.isEmpty()) {
KotlinLogging.logger(this::class.toString()).warn("No transformation present, returning input data") //return data node as is
data logger.warn("No transformation present, returning input data")
} else { data
val builder = DataTreeBuilder(Any::class) } else {
dataTransforms.forEach { val builder = DataTreeBuilder(Any::class)
val res = it(this, data) dataTransforms.forEach { transform ->
if (res != null) { val res = transform(this, data)
if (it.to.isEmpty()) { if (res != null) {
builder.update(res) if (transform.to.isEmpty()) {
} else { builder.update(res)
builder[it.to.toName()] = res } else {
builder[transform.to.toName()] = res
}
} }
} }
builder.build()
} }
builder.build()
} }
} }
return GenericTask<Any>(name, Any::class, descriptor ?: NodeDescriptor.empty(), modelTransform, transform); return GenericTask(name, Any::class, descriptor ?: NodeDescriptor.empty(), modelTransform, transform);
} }
} }