Explicit API mode
This commit is contained in:
parent
606faa5e1b
commit
d170f5d60c
@ -2,6 +2,6 @@ package hep.dataforge.context
|
|||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
|
|
||||||
interface Factory<out T : Any> {
|
public interface Factory<out T : Any> {
|
||||||
operator fun invoke(meta: Meta = Meta.EMPTY, context: Context = Global): T
|
public operator fun invoke(meta: Meta = Meta.EMPTY, context: Context = Global): T
|
||||||
}
|
}
|
@ -24,16 +24,14 @@ import hep.dataforge.names.isEmpty
|
|||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
interface Named {
|
public interface Named {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of this object instance
|
* The name of this object instance
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
val name: Name
|
public val name: Name
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of given object. If object is Named its name is used,
|
* Get the name of given object. If object is Named its name is used,
|
||||||
@ -42,7 +40,7 @@ interface Named {
|
|||||||
* @param obj
|
* @param obj
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
fun nameOf(obj: Any): Name {
|
public fun nameOf(obj: Any): Name {
|
||||||
return if (obj is Named) {
|
return if (obj is Named) {
|
||||||
obj.name
|
obj.name
|
||||||
} else {
|
} else {
|
||||||
@ -56,5 +54,4 @@ interface Named {
|
|||||||
* Check if this object has an empty name and therefore is anonymous.
|
* Check if this object has an empty name and therefore is anonymous.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
val Named.isAnonymous: Boolean
|
public val Named.isAnonymous: Boolean get() = this.name.isEmpty()
|
||||||
get() = this.name.isEmpty()
|
|
||||||
|
@ -22,21 +22,17 @@ import hep.dataforge.provider.Provider
|
|||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
interface Plugin : Named, ContextAware, Provider, MetaRepr {
|
public interface Plugin : Named, ContextAware, Provider, MetaRepr {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get tag for this plugin
|
* Get tag for this plugin
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
val tag: PluginTag
|
public val tag: PluginTag
|
||||||
|
|
||||||
val meta: Meta
|
public val meta: Meta
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of this plugin ignoring version and group
|
* The name of this plugin ignoring version and group
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
override val name: Name get() = tag.name.toName()
|
override val name: Name get() = tag.name.toName()
|
||||||
|
|
||||||
@ -44,25 +40,21 @@ interface Plugin : Named, ContextAware, Provider, MetaRepr {
|
|||||||
* Plugin dependencies which are required to attach this plugin. Plugin
|
* Plugin dependencies which are required to attach this plugin. Plugin
|
||||||
* dependencies must be initialized and enabled in the Context before this
|
* dependencies must be initialized and enabled in the Context before this
|
||||||
* plugin is enabled.
|
* plugin is enabled.
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
fun dependsOn(): Collection<PluginFactory<*>>
|
public fun dependsOn(): Collection<PluginFactory<*>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start this plugin and attach registration info to the context. This method
|
* Start this plugin and attach registration info to the context. This method
|
||||||
* should be called only via PluginManager to avoid dependency issues.
|
* should be called only via PluginManager to avoid dependency issues.
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
*/
|
*/
|
||||||
fun attach(context: Context)
|
public fun attach(context: Context)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop this plugin and remove registration info from context and other
|
* Stop this plugin and remove registration info from context and other
|
||||||
* plugins. This method should be called only via PluginManager to avoid
|
* plugins. This method should be called only via PluginManager to avoid
|
||||||
* dependency issues.
|
* dependency issues.
|
||||||
*/
|
*/
|
||||||
fun detach()
|
public fun detach()
|
||||||
|
|
||||||
override fun toMeta(): Meta = Meta {
|
override fun toMeta(): Meta = Meta {
|
||||||
"context" put context.name.toString()
|
"context" put context.name.toString()
|
||||||
@ -71,9 +63,9 @@ interface Plugin : Named, ContextAware, Provider, MetaRepr {
|
|||||||
"meta" put meta
|
"meta" put meta
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
|
|
||||||
const val PLUGIN_TARGET = "plugin"
|
public const val PLUGIN_TARGET = "plugin"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,12 +5,12 @@ import hep.dataforge.meta.MetaBuilder
|
|||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
interface PluginFactory<T : Plugin> : Factory<T> {
|
public interface PluginFactory<T : Plugin> : Factory<T> {
|
||||||
val tag: PluginTag
|
public val tag: PluginTag
|
||||||
val type: KClass<out T>
|
public val type: KClass<out T>
|
||||||
|
|
||||||
companion object{
|
public companion object{
|
||||||
const val TYPE = "pluginFactory"
|
public const val TYPE: String = "pluginFactory"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ interface PluginFactory<T : Plugin> : Factory<T> {
|
|||||||
* @property context A context for this plugin manager
|
* @property context A context for this plugin manager
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
class PluginManager(override val context: Context) : ContextAware, Iterable<Plugin> {
|
public class PluginManager(override val context: Context) : ContextAware, Iterable<Plugin> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of loaded plugins
|
* A set of loaded plugins
|
||||||
@ -34,7 +34,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
private val parent: PluginManager? = context.parent?.plugins
|
private val parent: PluginManager? = context.parent?.plugins
|
||||||
|
|
||||||
|
|
||||||
fun sequence(recursive: Boolean): Sequence<Plugin> {
|
public fun sequence(recursive: Boolean): Sequence<Plugin> {
|
||||||
return if (recursive && parent != null) {
|
return if (recursive && parent != null) {
|
||||||
plugins.asSequence() + parent.sequence(true)
|
plugins.asSequence() + parent.sequence(true)
|
||||||
} else {
|
} else {
|
||||||
@ -47,7 +47,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
* @param recursive search for parent [PluginManager] plugins
|
* @param recursive search for parent [PluginManager] plugins
|
||||||
* @param predicate condition for the plugin
|
* @param predicate condition for the plugin
|
||||||
*/
|
*/
|
||||||
fun find(recursive: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = sequence(recursive).find(predicate)
|
public fun find(recursive: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = sequence(recursive).find(predicate)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,7 +56,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
* @param tag
|
* @param tag
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
operator fun get(tag: PluginTag, recursive: Boolean = true): Plugin? = find(recursive) { tag.matches(it.tag) }
|
public operator fun get(tag: PluginTag, recursive: Boolean = true): Plugin? = find(recursive) { tag.matches(it.tag) }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,13 +71,13 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
operator fun <T : Any> get(type: KClass<out T>, tag: PluginTag? = null, recursive: Boolean = true): T? =
|
public operator fun <T : Any> get(type: KClass<out T>, tag: PluginTag? = null, recursive: Boolean = true): T? =
|
||||||
find(recursive) { type.isInstance(it) && (tag == null || tag.matches(it.tag)) } as T?
|
find(recursive) { type.isInstance(it) && (tag == null || tag.matches(it.tag)) } as T?
|
||||||
|
|
||||||
inline operator fun <reified T : Any> get(tag: PluginTag? = null, recursive: Boolean = true): T? =
|
public inline operator fun <reified T : Any> get(tag: PluginTag? = null, recursive: Boolean = true): T? =
|
||||||
get(T::class, tag, recursive)
|
get(T::class, tag, recursive)
|
||||||
|
|
||||||
inline operator fun <reified T : Plugin> get(factory: PluginFactory<T>, recursive: Boolean = true): T? =
|
public inline operator fun <reified T : Plugin> get(factory: PluginFactory<T>, recursive: Boolean = true): T? =
|
||||||
get(factory.type, factory.tag, recursive)
|
get(factory.type, factory.tag, recursive)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,7 +87,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
* @param plugin
|
* @param plugin
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
fun <T : Plugin> load(plugin: T): T {
|
public fun <T : Plugin> load(plugin: T): T {
|
||||||
if (context.isActive) error("Can't load plugin into active context")
|
if (context.isActive) error("Can't load plugin into active context")
|
||||||
|
|
||||||
if (get(plugin::class, plugin.tag, recursive = false) != null) {
|
if (get(plugin::class, plugin.tag, recursive = false) != null) {
|
||||||
@ -107,16 +107,16 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
/**
|
/**
|
||||||
* Load a plugin using its factory
|
* Load a plugin using its factory
|
||||||
*/
|
*/
|
||||||
fun <T : Plugin> load(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T =
|
public fun <T : Plugin> load(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T =
|
||||||
load(factory(meta, context))
|
load(factory(meta, context))
|
||||||
|
|
||||||
fun <T : Plugin> load(factory: PluginFactory<T>, metaBuilder: MetaBuilder.() -> Unit): T =
|
public fun <T : Plugin> load(factory: PluginFactory<T>, metaBuilder: MetaBuilder.() -> Unit): T =
|
||||||
load(factory, Meta(metaBuilder))
|
load(factory, Meta(metaBuilder))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a plugin from [PluginManager]
|
* Remove a plugin from [PluginManager]
|
||||||
*/
|
*/
|
||||||
fun remove(plugin: Plugin) {
|
public fun remove(plugin: Plugin) {
|
||||||
if (context.isActive) error("Can't remove plugin from active context")
|
if (context.isActive) error("Can't remove plugin from active context")
|
||||||
|
|
||||||
if (plugins.contains(plugin)) {
|
if (plugins.contains(plugin)) {
|
||||||
@ -130,7 +130,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
* Get an existing plugin with given meta or load new one using provided factory
|
* Get an existing plugin with given meta or load new one using provided factory
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
fun <T : Plugin> fetch(factory: PluginFactory<T>, recursive: Boolean = true, meta: Meta = Meta.EMPTY): T {
|
public fun <T : Plugin> fetch(factory: PluginFactory<T>, recursive: Boolean = true, meta: Meta = Meta.EMPTY): T {
|
||||||
val loaded = get(factory.type, factory.tag, recursive)
|
val loaded = get(factory.type, factory.tag, recursive)
|
||||||
return when {
|
return when {
|
||||||
loaded == null -> load(factory(meta, context))
|
loaded == null -> load(factory(meta, context))
|
||||||
@ -139,7 +139,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : Plugin> fetch(
|
public fun <T : Plugin> fetch(
|
||||||
factory: PluginFactory<T>,
|
factory: PluginFactory<T>,
|
||||||
recursive: Boolean = true,
|
recursive: Boolean = true,
|
||||||
metaBuilder: MetaBuilder.() -> Unit
|
metaBuilder: MetaBuilder.() -> Unit
|
||||||
|
@ -26,25 +26,25 @@ import hep.dataforge.names.toName
|
|||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
* @version $Id: $Id
|
* @version $Id: $Id
|
||||||
*/
|
*/
|
||||||
inline class Path(val tokens: List<PathToken>) : Iterable<PathToken> {
|
public inline class Path(public val tokens: List<PathToken>) : Iterable<PathToken> {
|
||||||
|
|
||||||
val head: PathToken? get() = tokens.firstOrNull()
|
public val head: PathToken? get() = tokens.firstOrNull()
|
||||||
|
|
||||||
val length: Int get() = tokens.size
|
public val length: Int get() = tokens.size
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns non-empty optional containing the chain without first segment in case of chain path.
|
* Returns non-empty optional containing the chain without first segment in case of chain path.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
val tail: Path? get() = if (tokens.isEmpty()) null else Path(tokens.drop(1))
|
public val tail: Path? get() = if (tokens.isEmpty()) null else Path(tokens.drop(1))
|
||||||
|
|
||||||
override fun iterator(): Iterator<PathToken> = tokens.iterator()
|
override fun iterator(): Iterator<PathToken> = tokens.iterator()
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
const val PATH_SEGMENT_SEPARATOR = "/"
|
public const val PATH_SEGMENT_SEPARATOR = "/"
|
||||||
|
|
||||||
fun parse(path: String): Path {
|
public fun parse(path: String): Path {
|
||||||
val head = path.substringBefore(PATH_SEGMENT_SEPARATOR)
|
val head = path.substringBefore(PATH_SEGMENT_SEPARATOR)
|
||||||
val tail = path.substringAfter(PATH_SEGMENT_SEPARATOR)
|
val tail = path.substringAfter(PATH_SEGMENT_SEPARATOR)
|
||||||
return PathToken.parse(head).toPath() + parse(tail)
|
return PathToken.parse(head).toPath() + parse(tail)
|
||||||
@ -52,18 +52,18 @@ inline class Path(val tokens: List<PathToken>) : Iterable<PathToken> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun Path.plus(path: Path) = Path(this.tokens + path.tokens)
|
public operator fun Path.plus(path: Path): Path = Path(this.tokens + path.tokens)
|
||||||
|
|
||||||
data class PathToken(val name: Name, val target: String? = null) {
|
public data class PathToken(val name: Name, val target: String? = null) {
|
||||||
override fun toString(): String = if (target == null) {
|
override fun toString(): String = if (target == null) {
|
||||||
name.toString()
|
name.toString()
|
||||||
} else {
|
} else {
|
||||||
"$target$TARGET_SEPARATOR$name"
|
"$target$TARGET_SEPARATOR$name"
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
const val TARGET_SEPARATOR = "::"
|
public const val TARGET_SEPARATOR: String = "::"
|
||||||
fun parse(token: String): PathToken {
|
public fun parse(token: String): PathToken {
|
||||||
val target = token.substringBefore(TARGET_SEPARATOR, "")
|
val target = token.substringBefore(TARGET_SEPARATOR, "")
|
||||||
val name = token.substringAfter(TARGET_SEPARATOR).toName()
|
val name = token.substringAfter(TARGET_SEPARATOR).toName()
|
||||||
if (target.contains("[")) TODO("target separators in queries are not supported")
|
if (target.contains("[")) TODO("target separators in queries are not supported")
|
||||||
@ -72,4 +72,4 @@ data class PathToken(val name: Name, val target: String? = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PathToken.toPath() = Path(listOf(this))
|
public fun PathToken.toPath(): Path = Path(listOf(this))
|
||||||
|
@ -22,29 +22,25 @@ import hep.dataforge.names.Name
|
|||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
interface Provider {
|
public interface Provider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default target for this provider
|
* Default target for this provider
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
val defaultTarget: String get() = ""
|
public val defaultTarget: String get() = ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default target for next chain segment
|
* Default target for next chain segment
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
val defaultChainTarget: String get() = ""
|
public val defaultChainTarget: String get() = ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of direct children for specific target
|
* A map of direct children for specific target
|
||||||
*/
|
*/
|
||||||
fun provideTop(target: String): Map<Name, Any> = emptyMap()
|
public fun provideTop(target: String): Map<Name, Any> = emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Provider.provide(path: Path, targetOverride: String? = null): Any? {
|
public fun Provider.provide(path: Path, targetOverride: String? = null): Any? {
|
||||||
if (path.length == 0) throw IllegalArgumentException("Can't provide by empty path")
|
if (path.length == 0) throw IllegalArgumentException("Can't provide by empty path")
|
||||||
val first = path.first()
|
val first = path.first()
|
||||||
val target = targetOverride ?: first.target ?: defaultTarget
|
val target = targetOverride ?: first.target ?: defaultTarget
|
||||||
@ -63,7 +59,7 @@ fun Provider.provide(path: Path, targetOverride: String? = null): Any? {
|
|||||||
/**
|
/**
|
||||||
* Type checked provide
|
* Type checked provide
|
||||||
*/
|
*/
|
||||||
inline fun <reified T : Any> Provider.provide(path: String, targetOverride: String? = null): T? {
|
public inline fun <reified T : Any> Provider.provide(path: String, targetOverride: String? = null): T? {
|
||||||
return provide(Path.parse(path), targetOverride) as? T
|
return provide(Path.parse(path), targetOverride) as? T
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -77,7 +73,7 @@ inline fun <reified T : Any> Provider.provide(path: String, targetOverride: Stri
|
|||||||
/**
|
/**
|
||||||
* Typed top level content
|
* Typed top level content
|
||||||
*/
|
*/
|
||||||
inline fun <reified T : Any> Provider.top(target: String): Map<Name, T> {
|
public inline fun <reified T : Any> Provider.top(target: String): Map<Name, T> {
|
||||||
return provideTop(target).mapValues {
|
return provideTop(target).mapValues {
|
||||||
it.value as? T ?: error("The type of element $it is ${it::class} but ${T::class} is expected")
|
it.value as? T ?: error("The type of element $it is ${it::class} but ${T::class} is expected")
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,4 @@ package hep.dataforge.provider
|
|||||||
*/
|
*/
|
||||||
@MustBeDocumented
|
@MustBeDocumented
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
annotation class Type(val id: String)
|
public annotation class Type(val id: String)
|
||||||
|
@ -5,23 +5,23 @@ import hep.dataforge.meta.Meta
|
|||||||
/**
|
/**
|
||||||
* A simple data transformation on a data node
|
* A simple data transformation on a data node
|
||||||
*/
|
*/
|
||||||
interface Action<in T : Any, out R : Any> {
|
public interface Action<in T : Any, out R : Any> {
|
||||||
/**
|
/**
|
||||||
* Transform the data in the node, producing a new node. By default it is assumed that all calculations are lazy
|
* Transform the data in the node, producing a new node. By default it is assumed that all calculations are lazy
|
||||||
* so not actual computation is started at this moment
|
* so not actual computation is started at this moment
|
||||||
*/
|
*/
|
||||||
operator fun invoke(node: DataNode<T>, meta: Meta): DataNode<R>
|
public operator fun invoke(node: DataNode<T>, meta: Meta): DataNode<R>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminal action is the one that could not be invoked lazily and requires some kind of blocking computation to invoke
|
* Terminal action is the one that could not be invoked lazily and requires some kind of blocking computation to invoke
|
||||||
*/
|
*/
|
||||||
val isTerminal: Boolean get() = false
|
public val isTerminal: Boolean get() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action composition. The result is terminal if one of its parts is terminal
|
* Action composition. The result is terminal if one of its parts is terminal
|
||||||
*/
|
*/
|
||||||
infix fun <T : Any, I : Any, R : Any> Action<T, I>.then(action: Action<I, R>): Action<T, R> {
|
public infix fun <T : Any, I : Any, R : Any> Action<T, I>.then(action: Action<I, R>): Action<T, R> {
|
||||||
// TODO introduce composite action and add optimize by adding action to the list
|
// TODO introduce composite action and add optimize by adding action to the list
|
||||||
return object : Action<T, R> {
|
return object : Action<T, R> {
|
||||||
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
|
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
|
||||||
|
@ -1,48 +1,58 @@
|
|||||||
package hep.dataforge.data
|
package hep.dataforge.data
|
||||||
|
|
||||||
|
import hep.dataforge.meta.DFExperimental
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A monitor of goal state that could be accessed only form inside the goal
|
* A monitor of goal state that could be accessed only form inside the goal
|
||||||
*/
|
*/
|
||||||
class CoroutineMonitor : CoroutineContext.Element {
|
@DFExperimental
|
||||||
|
public class CoroutineMonitor : CoroutineContext.Element {
|
||||||
override val key: CoroutineContext.Key<*> get() = CoroutineMonitor
|
override val key: CoroutineContext.Key<*> get() = CoroutineMonitor
|
||||||
|
|
||||||
var totalWork: Double = 1.0
|
public var totalWork: Double = 1.0
|
||||||
var workDone: Double = 0.0
|
public var workDone: Double = 0.0
|
||||||
var status: String = ""
|
public var status: String = ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the goal as started
|
* Mark the goal as started
|
||||||
*/
|
*/
|
||||||
fun start() {
|
public fun start() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the goal as completed
|
* Mark the goal as completed
|
||||||
*/
|
*/
|
||||||
fun finish() {
|
public fun finish() {
|
||||||
workDone = totalWork
|
workDone = totalWork
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : CoroutineContext.Key<CoroutineMonitor>
|
public companion object : CoroutineContext.Key<CoroutineMonitor>
|
||||||
}
|
}
|
||||||
|
|
||||||
class Dependencies(val values: Collection<Job>) : CoroutineContext.Element {
|
public class Dependencies(public val values: Collection<Job>) : CoroutineContext.Element {
|
||||||
override val key: CoroutineContext.Key<*> get() = Dependencies
|
override val key: CoroutineContext.Key<*> get() = Dependencies
|
||||||
|
|
||||||
companion object : CoroutineContext.Key<Dependencies>
|
public companion object : CoroutineContext.Key<Dependencies>
|
||||||
}
|
}
|
||||||
|
|
||||||
val CoroutineContext.monitor: CoroutineMonitor? get() = this[CoroutineMonitor]
|
@DFExperimental
|
||||||
val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.monitor
|
public val CoroutineContext.monitor: CoroutineMonitor? get() = this[CoroutineMonitor]
|
||||||
|
@DFExperimental
|
||||||
|
public val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.monitor
|
||||||
|
|
||||||
val Job.dependencies: Collection<Job> get() = this[Dependencies]?.values ?: emptyList()
|
public val Job.dependencies: Collection<Job> get() = this[Dependencies]?.values ?: emptyList()
|
||||||
|
|
||||||
val Job.totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0)
|
@DFExperimental
|
||||||
val Job.workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0)
|
public val Job.totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0)
|
||||||
val Job.status: String get() = monitor?.status ?: ""
|
@DFExperimental
|
||||||
val Job.progress: Double get() = workDone / totalWork
|
public val Job.workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0)
|
||||||
|
@DFExperimental
|
||||||
|
public val Job.status: String get() = monitor?.status ?: ""
|
||||||
|
@DFExperimental
|
||||||
|
public val Job.progress: Double get() = workDone / totalWork
|
@ -11,7 +11,7 @@ import kotlin.reflect.KClass
|
|||||||
/**
|
/**
|
||||||
* A data element characterized by its meta
|
* A data element characterized by its meta
|
||||||
*/
|
*/
|
||||||
interface Data<out T : Any> : Goal<T>, MetaRepr{
|
public interface Data<out T : Any> : Goal<T>, MetaRepr{
|
||||||
/**
|
/**
|
||||||
* Type marker for the data. The type is known before the calculation takes place so it could be checked.
|
* Type marker for the data. The type is known before the calculation takes place so it could be checked.
|
||||||
*/
|
*/
|
||||||
|
@ -6,18 +6,18 @@ import hep.dataforge.values.*
|
|||||||
/**
|
/**
|
||||||
* A converter of generic object to and from [MetaItem]
|
* A converter of generic object to and from [MetaItem]
|
||||||
*/
|
*/
|
||||||
interface MetaConverter<T : Any> {
|
public interface MetaConverter<T : Any> {
|
||||||
fun itemToObject(item: MetaItem<*>): T
|
public fun itemToObject(item: MetaItem<*>): T
|
||||||
fun objectToMetaItem(obj: T): MetaItem<*>
|
public fun objectToMetaItem(obj: T): MetaItem<*>
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
|
|
||||||
val item = object : MetaConverter<MetaItem<*>> {
|
public val item: MetaConverter<MetaItem<*>> = object : MetaConverter<MetaItem<*>> {
|
||||||
override fun itemToObject(item: MetaItem<*>): MetaItem<*> = item
|
override fun itemToObject(item: MetaItem<*>): MetaItem<*> = item
|
||||||
override fun objectToMetaItem(obj: MetaItem<*>): MetaItem<*> = obj
|
override fun objectToMetaItem(obj: MetaItem<*>): MetaItem<*> = obj
|
||||||
}
|
}
|
||||||
|
|
||||||
val meta = object : MetaConverter<Meta> {
|
public val meta: MetaConverter<Meta> = object : MetaConverter<Meta> {
|
||||||
override fun itemToObject(item: MetaItem<*>): Meta = when (item) {
|
override fun itemToObject(item: MetaItem<*>): Meta = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node
|
is MetaItem.NodeItem -> item.node
|
||||||
is MetaItem.ValueItem -> item.value.toMeta()
|
is MetaItem.ValueItem -> item.value.toMeta()
|
||||||
@ -26,7 +26,7 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: Meta): MetaItem<*> = MetaItem.NodeItem(obj)
|
override fun objectToMetaItem(obj: Meta): MetaItem<*> = MetaItem.NodeItem(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
val value = object : MetaConverter<Value> {
|
public val value: MetaConverter<Value> = object : MetaConverter<Value> {
|
||||||
override fun itemToObject(item: MetaItem<*>): Value = when (item) {
|
override fun itemToObject(item: MetaItem<*>): Value = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
||||||
is MetaItem.ValueItem -> item.value
|
is MetaItem.ValueItem -> item.value
|
||||||
@ -35,7 +35,7 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: Value): MetaItem<*> = MetaItem.ValueItem(obj)
|
override fun objectToMetaItem(obj: Value): MetaItem<*> = MetaItem.ValueItem(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
val string = object : MetaConverter<String> {
|
public val string: MetaConverter<String> = object : MetaConverter<String> {
|
||||||
override fun itemToObject(item: MetaItem<*>): String = when (item) {
|
override fun itemToObject(item: MetaItem<*>): String = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
||||||
is MetaItem.ValueItem -> item.value
|
is MetaItem.ValueItem -> item.value
|
||||||
@ -44,7 +44,7 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: String): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
override fun objectToMetaItem(obj: String): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
val boolean = object : MetaConverter<Boolean> {
|
public val boolean: MetaConverter<Boolean> = object : MetaConverter<Boolean> {
|
||||||
override fun itemToObject(item: MetaItem<*>): Boolean = when (item) {
|
override fun itemToObject(item: MetaItem<*>): Boolean = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
||||||
is MetaItem.ValueItem -> item.value
|
is MetaItem.ValueItem -> item.value
|
||||||
@ -53,7 +53,7 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: Boolean): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
override fun objectToMetaItem(obj: Boolean): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
val number = object : MetaConverter<Number> {
|
public val number: MetaConverter<Number> = object : MetaConverter<Number> {
|
||||||
override fun itemToObject(item: MetaItem<*>): Number = when (item) {
|
override fun itemToObject(item: MetaItem<*>): Number = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
||||||
is MetaItem.ValueItem -> item.value
|
is MetaItem.ValueItem -> item.value
|
||||||
@ -62,7 +62,7 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: Number): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
override fun objectToMetaItem(obj: Number): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
val double = object : MetaConverter<Double> {
|
public val double: MetaConverter<Double> = object : MetaConverter<Double> {
|
||||||
override fun itemToObject(item: MetaItem<*>): Double = when (item) {
|
override fun itemToObject(item: MetaItem<*>): Double = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
||||||
is MetaItem.ValueItem -> item.value
|
is MetaItem.ValueItem -> item.value
|
||||||
@ -71,7 +71,7 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: Double): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
override fun objectToMetaItem(obj: Double): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
val float = object : MetaConverter<Float> {
|
public val float: MetaConverter<Float> = object : MetaConverter<Float> {
|
||||||
override fun itemToObject(item: MetaItem<*>): Float = when (item) {
|
override fun itemToObject(item: MetaItem<*>): Float = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
||||||
is MetaItem.ValueItem -> item.value
|
is MetaItem.ValueItem -> item.value
|
||||||
@ -80,7 +80,7 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: Float): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
override fun objectToMetaItem(obj: Float): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
val int = object : MetaConverter<Int> {
|
public val int: MetaConverter<Int> = object : MetaConverter<Int> {
|
||||||
override fun itemToObject(item: MetaItem<*>): Int = when (item) {
|
override fun itemToObject(item: MetaItem<*>): Int = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
||||||
is MetaItem.ValueItem -> item.value
|
is MetaItem.ValueItem -> item.value
|
||||||
@ -89,7 +89,7 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: Int): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
override fun objectToMetaItem(obj: Int): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
val long = object : MetaConverter<Long> {
|
public val long: MetaConverter<Long> = object : MetaConverter<Long> {
|
||||||
override fun itemToObject(item: MetaItem<*>): Long = when (item) {
|
override fun itemToObject(item: MetaItem<*>): Long = when (item) {
|
||||||
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value")
|
||||||
is MetaItem.ValueItem -> item.value
|
is MetaItem.ValueItem -> item.value
|
||||||
@ -98,14 +98,14 @@ interface MetaConverter<T : Any> {
|
|||||||
override fun objectToMetaItem(obj: Long): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
override fun objectToMetaItem(obj: Long): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified E : Enum<E>> enum(): MetaConverter<E> = object : MetaConverter<E> {
|
public inline fun <reified E : Enum<E>> enum(): MetaConverter<E> = object : MetaConverter<E> {
|
||||||
@Suppress("USELESS_CAST")
|
@Suppress("USELESS_CAST")
|
||||||
override fun itemToObject(item: MetaItem<*>): E = item.enum<E>() as? E ?: error("The Item is not a Enum")
|
override fun itemToObject(item: MetaItem<*>): E = item.enum<E>() as? E ?: error("The Item is not a Enum")
|
||||||
|
|
||||||
override fun objectToMetaItem(obj: E): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
override fun objectToMetaItem(obj: E): MetaItem<*> = MetaItem.ValueItem(obj.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> valueList(writer: (T) -> Value = {Value.of(it)}, reader: (Value) -> T): MetaConverter<List<T>> =
|
public fun <T> valueList(writer: (T) -> Value = {Value.of(it)}, reader: (Value) -> T): MetaConverter<List<T>> =
|
||||||
object : MetaConverter<List<T>> {
|
object : MetaConverter<List<T>> {
|
||||||
override fun itemToObject(item: MetaItem<*>): List<T> =
|
override fun itemToObject(item: MetaItem<*>): List<T> =
|
||||||
item.value?.list?.map(reader) ?: error("The item is not a value list")
|
item.value?.list?.map(reader) ?: error("The item is not a value list")
|
||||||
@ -117,8 +117,8 @@ interface MetaConverter<T : Any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : Any> MetaConverter<T>.nullableItemToObject(item: MetaItem<*>?): T? = item?.let { itemToObject(it) }
|
public fun <T : Any> MetaConverter<T>.nullableItemToObject(item: MetaItem<*>?): T? = item?.let { itemToObject(it) }
|
||||||
fun <T : Any> MetaConverter<T>.nullableObjectToMetaItem(obj: T?): MetaItem<*>? = obj?.let { objectToMetaItem(it) }
|
public fun <T : Any> MetaConverter<T>.nullableObjectToMetaItem(obj: T?): MetaItem<*>? = obj?.let { objectToMetaItem(it) }
|
||||||
|
|
||||||
fun <T : Any> MetaConverter<T>.metaToObject(meta: Meta): T = itemToObject(MetaItem.NodeItem(meta))
|
public fun <T : Any> MetaConverter<T>.metaToObject(meta: Meta): T = itemToObject(MetaItem.NodeItem(meta))
|
||||||
fun <T : Any> MetaConverter<T>.valueToObject(value: Value): T = itemToObject(MetaItem.ValueItem(value))
|
public fun <T : Any> MetaConverter<T>.valueToObject(value: Value): T = itemToObject(MetaItem.ValueItem(value))
|
||||||
|
@ -6,31 +6,31 @@ import hep.dataforge.names.Name
|
|||||||
/**
|
/**
|
||||||
* A transformation for meta item or a group of items
|
* A transformation for meta item or a group of items
|
||||||
*/
|
*/
|
||||||
interface TransformationRule {
|
public interface TransformationRule {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if this transformation should be applied to a node with given name and value
|
* Check if this transformation should be applied to a node with given name and value
|
||||||
*/
|
*/
|
||||||
fun matches(name: Name, item: MetaItem<*>?): Boolean
|
public fun matches(name: Name, item: MetaItem<*>?): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select all items to be transformed. Item could be a value as well as node
|
* Select all items to be transformed. Item could be a value as well as node
|
||||||
*
|
*
|
||||||
* @return a sequence of item paths to be transformed
|
* @return a sequence of item paths to be transformed
|
||||||
*/
|
*/
|
||||||
fun selectItems(meta: Meta): Sequence<Name> =
|
public fun selectItems(meta: Meta): Sequence<Name> =
|
||||||
meta.sequence().filter { matches(it.first, it.second) }.map { it.first }
|
meta.sequence().filter { matches(it.first, it.second) }.map { it.first }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply transformation for a single item (Node or Value) to the target
|
* Apply transformation for a single item (Node or Value) to the target
|
||||||
*/
|
*/
|
||||||
fun <M : MutableMeta<M>> transformItem(name: Name, item: MetaItem<*>?, target: M): Unit
|
public fun <M : MutableMeta<M>> transformItem(name: Name, item: MetaItem<*>?, target: M): Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A transformation which keeps all elements, matching [selector] unchanged.
|
* A transformation which keeps all elements, matching [selector] unchanged.
|
||||||
*/
|
*/
|
||||||
data class KeepTransformationRule(val selector: (Name) -> Boolean) :
|
public data class KeepTransformationRule(val selector: (Name) -> Boolean) :
|
||||||
TransformationRule {
|
TransformationRule {
|
||||||
override fun matches(name: Name, item: MetaItem<*>?): Boolean {
|
override fun matches(name: Name, item: MetaItem<*>?): Boolean {
|
||||||
return selector(name)
|
return selector(name)
|
||||||
@ -47,7 +47,7 @@ data class KeepTransformationRule(val selector: (Name) -> Boolean) :
|
|||||||
/**
|
/**
|
||||||
* A transformation which transforms element with specific name
|
* A transformation which transforms element with specific name
|
||||||
*/
|
*/
|
||||||
data class SingleItemTransformationRule(
|
public data class SingleItemTransformationRule(
|
||||||
val from: Name,
|
val from: Name,
|
||||||
val transform: MutableMeta<*>.(Name, MetaItem<*>?) -> Unit
|
val transform: MutableMeta<*>.(Name, MetaItem<*>?) -> Unit
|
||||||
) : TransformationRule {
|
) : TransformationRule {
|
||||||
@ -64,7 +64,7 @@ data class SingleItemTransformationRule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class RegexItemTransformationRule(
|
public data class RegexItemTransformationRule(
|
||||||
val from: Regex,
|
val from: Regex,
|
||||||
val transform: MutableMeta<*>.(name: Name, MatchResult, MetaItem<*>?) -> Unit
|
val transform: MutableMeta<*>.(name: Name, MatchResult, MetaItem<*>?) -> Unit
|
||||||
) : TransformationRule {
|
) : TransformationRule {
|
||||||
@ -84,12 +84,12 @@ data class RegexItemTransformationRule(
|
|||||||
/**
|
/**
|
||||||
* A set of [TransformationRule] to either transform static meta or create dynamically updated [MutableMeta]
|
* A set of [TransformationRule] to either transform static meta or create dynamically updated [MutableMeta]
|
||||||
*/
|
*/
|
||||||
inline class MetaTransformation(val transformations: Collection<TransformationRule>) {
|
public inline class MetaTransformation(public val transformations: Collection<TransformationRule>) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produce new meta using only those items that match transformation rules
|
* Produce new meta using only those items that match transformation rules
|
||||||
*/
|
*/
|
||||||
fun generate(source: Meta): Meta =
|
public fun generate(source: Meta): Meta =
|
||||||
Meta {
|
Meta {
|
||||||
transformations.forEach { rule ->
|
transformations.forEach { rule ->
|
||||||
rule.selectItems(source).forEach { name ->
|
rule.selectItems(source).forEach { name ->
|
||||||
@ -102,7 +102,7 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu
|
|||||||
* Generate an observable configuration that contains only elements defined by transformation rules and changes with the source
|
* Generate an observable configuration that contains only elements defined by transformation rules and changes with the source
|
||||||
*/
|
*/
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun generate(source: Config): ObservableMeta = Config().apply {
|
public fun generate(source: Config): ObservableMeta = Config().apply {
|
||||||
transformations.forEach { rule ->
|
transformations.forEach { rule ->
|
||||||
rule.selectItems(source).forEach { name ->
|
rule.selectItems(source).forEach { name ->
|
||||||
rule.transformItem(name, source[name], this)
|
rule.transformItem(name, source[name], this)
|
||||||
@ -115,7 +115,7 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu
|
|||||||
/**
|
/**
|
||||||
* Transform a meta, replacing all elements found in rules with transformed entries
|
* Transform a meta, replacing all elements found in rules with transformed entries
|
||||||
*/
|
*/
|
||||||
fun apply(source: Meta): Meta =
|
public fun apply(source: Meta): Meta =
|
||||||
source.edit {
|
source.edit {
|
||||||
transformations.forEach { rule ->
|
transformations.forEach { rule ->
|
||||||
rule.selectItems(source).forEach { name ->
|
rule.selectItems(source).forEach { name ->
|
||||||
@ -128,7 +128,7 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu
|
|||||||
/**
|
/**
|
||||||
* Listens for changes in the source node and translates them into second node if transformation set contains a corresponding rule.
|
* Listens for changes in the source node and translates them into second node if transformation set contains a corresponding rule.
|
||||||
*/
|
*/
|
||||||
fun <M : MutableMeta<M>> bind(source: Config, target: M) {
|
public fun <M : MutableMeta<M>> bind(source: Config, target: M) {
|
||||||
source.onChange(target) { name, _, newItem ->
|
source.onChange(target) { name, _, newItem ->
|
||||||
transformations.forEach { t ->
|
transformations.forEach { t ->
|
||||||
if (t.matches(name, newItem)) {
|
if (t.matches(name, newItem)) {
|
||||||
@ -147,27 +147,27 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu
|
|||||||
/**
|
/**
|
||||||
* A builder for a set of transformation rules
|
* A builder for a set of transformation rules
|
||||||
*/
|
*/
|
||||||
class MetaTransformationBuilder {
|
public class MetaTransformationBuilder {
|
||||||
val transformations = HashSet<TransformationRule>()
|
private val transformations = HashSet<TransformationRule>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep all items with name satisfying the criteria
|
* Keep all items with name satisfying the criteria
|
||||||
*/
|
*/
|
||||||
fun keep(selector: (Name) -> Boolean) {
|
public fun keep(selector: (Name) -> Boolean) {
|
||||||
transformations.add(KeepTransformationRule(selector))
|
transformations.add(KeepTransformationRule(selector))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep specific item (including its descendants)
|
* Keep specific item (including its descendants)
|
||||||
*/
|
*/
|
||||||
fun keep(name: Name) {
|
public fun keep(name: Name) {
|
||||||
keep { it == name }
|
keep { it == name }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep nodes by regex
|
* Keep nodes by regex
|
||||||
*/
|
*/
|
||||||
fun keep(regex: String) {
|
public fun keep(regex: String) {
|
||||||
transformations.add(
|
transformations.add(
|
||||||
RegexItemTransformationRule(regex.toRegex()) { name, _, metaItem ->
|
RegexItemTransformationRule(regex.toRegex()) { name, _, metaItem ->
|
||||||
setItem(name, metaItem)
|
setItem(name, metaItem)
|
||||||
@ -177,7 +177,7 @@ class MetaTransformationBuilder {
|
|||||||
/**
|
/**
|
||||||
* Move an item from [from] to [to], optionally applying [operation] it defined
|
* Move an item from [from] to [to], optionally applying [operation] it defined
|
||||||
*/
|
*/
|
||||||
fun move(from: Name, to: Name, operation: (MetaItem<*>?) -> Any? = { it }) {
|
public fun move(from: Name, to: Name, operation: (MetaItem<*>?) -> Any? = { it }) {
|
||||||
transformations.add(
|
transformations.add(
|
||||||
SingleItemTransformationRule(from) { _, item ->
|
SingleItemTransformationRule(from) { _, item ->
|
||||||
set(to, operation(item))
|
set(to, operation(item))
|
||||||
@ -185,5 +185,5 @@ class MetaTransformationBuilder {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun build() = MetaTransformation(transformations)
|
public fun build(): MetaTransformation = MetaTransformation(transformations)
|
||||||
}
|
}
|
@ -13,7 +13,7 @@ public fun Value.isNull(): Boolean = this == Null
|
|||||||
*/
|
*/
|
||||||
public fun Value.isList(): Boolean = this.list.size > 1
|
public fun Value.isList(): Boolean = this.list.size > 1
|
||||||
|
|
||||||
public val Value.boolean
|
public val Value.boolean: Boolean
|
||||||
get() = this == True
|
get() = this == True
|
||||||
|| this.list.firstOrNull() == True
|
|| this.list.firstOrNull() == True
|
||||||
|| (type == ValueType.STRING && string.toBoolean())
|
|| (type == ValueType.STRING && string.toBoolean())
|
||||||
|
@ -35,7 +35,7 @@ public abstract class WorkspacePlugin : AbstractPlugin() {
|
|||||||
public inline fun <reified T : Any> task(
|
public inline fun <reified T : Any> task(
|
||||||
name: String,
|
name: String,
|
||||||
noinline builder: TaskBuilder<T>.() -> Unit
|
noinline builder: TaskBuilder<T>.() -> Unit
|
||||||
) = task(name, T::class, builder)
|
): GenericTask<T> = task(name, T::class, builder)
|
||||||
|
|
||||||
//
|
//
|
||||||
////TODO add delegates to build gradle-like tasks
|
////TODO add delegates to build gradle-like tasks
|
||||||
|
Loading…
Reference in New Issue
Block a user