From 9fbc482549b9fb106ff655f7cfdd8ea9f28f2ba8 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 5 Apr 2021 22:01:09 +0300 Subject: [PATCH 01/11] Scheme made observable --- .github/workflows/pages.yml | 33 +++++++++++++++++++ build.gradle.kts | 6 +--- .../space/kscience/dataforge/data/DataSet.kt | 7 ++-- .../space/kscience/dataforge/data/DataTree.kt | 2 +- dataforge-meta/api/dataforge-meta.api | 4 ++- .../space/kscience/dataforge/meta/Scheme.kt | 30 +++++++++++++++-- settings.gradle.kts | 4 +-- 7 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/pages.yml diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 00000000..74c1bffd --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,33 @@ +name: Dokka publication + +on: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-20.04 + steps: + - name: Checkout the repo + uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Cache gradle + uses: actions/cache@v2 + with: + path: ~/.gradle/caches + key: ubuntu-20.04-gradle-${{ hashFiles('*.gradle.kts') }} + restore-keys: | + ubuntu-20.04-gradle- + - name: Build + run: | + ./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace + mv build/dokka/htmlMultiModule/-modules.html build/dokka/htmlMultiModule/index.html + - name: Deploy to GitHub Pages + uses: JamesIves/github-pages-deploy-action@4.1.0 + with: + branch: gh-pages + folder: build/dokka/htmlMultiModule diff --git a/build.gradle.kts b/build.gradle.kts index 27f40ae9..6fdbfd60 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,15 +4,11 @@ plugins { allprojects { group = "space.kscience" - version = "0.4.0-dev-2" + version = "0.4.0-dev-5" } subprojects { apply(plugin = "maven-publish") - repositories { - maven("https://dl.bintray.com/mipt-npm/kscience") - maven("https://dl.bintray.com/mipt-npm/dev") - } } readme { diff --git a/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/DataSet.kt b/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/DataSet.kt index 525d4c86..305f50f8 100644 --- a/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/DataSet.kt +++ b/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/DataSet.kt @@ -28,12 +28,11 @@ public interface DataSet { public suspend fun getData(name: Name): Data? /** - * Get a snapshot of names of children of given node. Empty if node does not exist or is a leaf. - * - * By default traverses the whole tree. Could be optimized in descendants + * Get a snapshot of names of top level children of given node. Empty if node does not exist or is a leaf. */ - public suspend fun listChildren(prefix: Name = Name.EMPTY): List = + public suspend fun listTop(prefix: Name = Name.EMPTY): List = flow().map { it.name }.filter { it.startsWith(prefix) && (it.length == prefix.length + 1) }.toList() + // By default traverses the whole tree. Could be optimized in descendants public companion object { public val META_KEY: Name = "@meta".asName() diff --git a/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/DataTree.kt b/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/DataTree.kt index 13c8afbe..cf852b17 100644 --- a/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/DataTree.kt +++ b/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/DataTree.kt @@ -43,7 +43,7 @@ public interface DataTree : DataSet { } } - override suspend fun listChildren(prefix: Name): List = + override suspend fun listTop(prefix: Name): List = getItem(prefix).tree?.items()?.keys?.map { prefix + it } ?: emptyList() override suspend fun getData(name: Name): Data? = when (name.length) { diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index b31a14c0..f5e908d2 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -433,12 +433,14 @@ public final class space/kscience/dataforge/meta/ReadOnlySpecification$DefaultIm public static fun invoke (Lspace/kscience/dataforge/meta/ReadOnlySpecification;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider; } -public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/MutableItemProvider, space/kscience/dataforge/meta/descriptors/Described { +public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/MutableItemProvider, space/kscience/dataforge/meta/ObservableItemProvider, space/kscience/dataforge/meta/descriptors/Described { public fun ()V public fun getDefaultLayer ()Lspace/kscience/dataforge/meta/Meta; public synthetic fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; public final fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; + public fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V + public fun removeListener (Ljava/lang/Object;)V public final fun setDescriptor (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)V public fun setItem (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;)V public fun toMeta ()Lspace/kscience/dataforge/meta/Laminate; diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt index 319401ac..613161e1 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt @@ -4,19 +4,42 @@ import space.kscience.dataforge.meta.descriptors.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName +import kotlin.jvm.Synchronized /** * A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [Specification]. * Default item provider and [NodeDescriptor] are optional */ -public open class Scheme() : MutableItemProvider, Described, MetaRepr { +public open class Scheme() : MutableItemProvider, Described, MetaRepr, ObservableItemProvider { private var items: MutableItemProvider = Config() + private val listeners = HashSet() + private var default: ItemProvider? = null final override var descriptor: NodeDescriptor? = null + + /** + * Add a listener to this scheme changes. If the inner provider is observable, then listening will be delegated to it. + * Otherwise, local listeners will be created. + */ + @Synchronized + override fun onChange(owner: Any?, action: (Name, MetaItem?, MetaItem?) -> Unit) { + (items as? ObservableItemProvider)?.onChange(owner, action) + ?: run { listeners.add(ItemListener(owner, action)) } + } + + /** + * Remove all listeners belonging to given owner + */ + @Synchronized + override fun removeListener(owner: Any?) { + (items as? ObservableItemProvider)?.removeListener(owner) + ?: listeners.removeAll { it.owner === owner } + } + internal fun wrap( items: MutableItemProvider, default: ItemProvider? = null, @@ -50,13 +73,16 @@ public open class Scheme() : MutableItemProvider, Described, MetaRepr { * Set a configurable property */ override fun setItem(name: Name, item: MetaItem?) { + val oldItem = items[name] if (validateItem(name, item)) { items[name] = item + listeners.forEach { it.action(name, oldItem, item) } } else { error("Validation failed for property $name with value $item") } } + /** * Provide a default layer which returns items from [default] and falls back to descriptor * values if default value is unavailable. @@ -100,7 +126,7 @@ public fun > S.wrap( * Relocate scheme target onto given [MutableItemProvider]. Old provider does not get updates anymore. * Current state of the scheme used as a default. */ -public fun T.retarget(provider: MutableItemProvider) :T = apply { wrap(provider) } +public fun T.retarget(provider: MutableItemProvider): T = apply { wrap(provider) } /** * A shortcut to edit a [Scheme] object in-place diff --git a/settings.gradle.kts b/settings.gradle.kts index 95df91b7..c55ee461 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,8 +7,8 @@ pluginManagement { maven("https://dl.bintray.com/kotlin/kotlin-eap") } - val toolsVersion = "0.9.1" - val kotlinVersion = "1.4.31" + val toolsVersion = "0.9.3" + val kotlinVersion = "1.4.32" plugins { id("ru.mipt.npm.gradle.project") version toolsVersion From f1f5f7a70c5232d796c1001c4bdb421b7f062b2e Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 6 Apr 2021 15:12:40 +0300 Subject: [PATCH 02/11] Isolate and deprecate Context plugin mutation logic. --- CHANGELOG.md | 4 ++ dataforge-context/api/dataforge-context.api | 42 +++++++++++------ .../kscience/dataforge/context/Context.kt | 23 +++++++--- .../dataforge/context/ContextBuilder.kt | 42 +++++++++++++++-- .../kscience/dataforge/context/Global.kt | 45 +++---------------- .../kscience/dataforge/context/LogManager.kt | 28 ++++++++++-- .../kscience/dataforge/context/Plugin.kt | 1 - .../dataforge/context/PluginManager.kt | 24 ++++++++-- .../kscience/dataforge/context/ContextTest.kt | 4 +- .../dataforge/context/loggingNative.kt | 23 +--------- .../space/kscience/dataforge/io/IOPlugin.kt | 12 ++++- .../dataforge/io/TaggedEnvelopeFormat.kt | 2 +- .../dataforge/io/TaglessEnvelopeFormat.kt | 2 +- dataforge-meta/api/dataforge-meta.api | 1 + .../space/kscience/dataforge/meta/Meta.kt | 2 + .../kscience/dataforge/meta/TypedMeta.kt | 2 +- .../dataforge/scripting/BuildersKtTest.kt | 9 ++-- .../dataforge/workspace/WorkspaceBuilder.kt | 4 +- 18 files changed, 165 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2e195e9..980aad47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,16 @@ ### Added - LogManager plugin - dataforge-context API dependency on SLF4j +- Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation. ### Changed - Kotlin-logging moved from common to JVM and JS. Replaced by console for native. - Package changed to `space.kscience` +- Scheme made observable +- Global context is a variable (the singleton is hidden and will be deprecated in future) ### Deprecated +- Direct use of PluginManager ### Removed - Common dependency on Kotlin-logging diff --git a/dataforge-context/api/dataforge-context.api b/dataforge-context/api/dataforge-context.api index 5674e74b..1b1a849f 100644 --- a/dataforge-context/api/dataforge-context.api +++ b/dataforge-context/api/dataforge-context.api @@ -38,6 +38,7 @@ public final class space/kscience/dataforge/context/ClassLoaderPluginKt { public class space/kscience/dataforge/context/Context : kotlinx/coroutines/CoroutineScope, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/misc/Named, space/kscience/dataforge/provider/Provider { public static final field Companion Lspace/kscience/dataforge/context/Context$Companion; public static final field PROPERTY_TARGET Ljava/lang/String; + public final fun buildContext (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; public fun close ()V public fun content (Ljava/lang/String;)Ljava/util/Map; public final fun content (Ljava/lang/String;Z)Ljava/util/Map; @@ -47,6 +48,7 @@ public class space/kscience/dataforge/context/Context : kotlinx/coroutines/Corou public final fun getName ()Lspace/kscience/dataforge/names/Name; public final fun getParent ()Lspace/kscience/dataforge/context/Context; public final fun getPlugins ()Lspace/kscience/dataforge/context/PluginManager; + public final fun getProperties ()Lspace/kscience/dataforge/meta/Laminate; public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; } @@ -58,24 +60,35 @@ public abstract interface class space/kscience/dataforge/context/ContextAware { } public final class space/kscience/dataforge/context/ContextBuilder { - public fun ()V - public fun (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;)V - public synthetic fun (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun build ()Lspace/kscience/dataforge/context/Context; - public final fun getName ()Ljava/lang/String; + public final fun getName ()Lspace/kscience/dataforge/names/Name; + public final fun name (Ljava/lang/String;)V public final fun plugin (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V public final fun plugin (Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)V + public final fun plugin (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)V public final fun plugin (Lspace/kscience/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;)V public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Lspace/kscience/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V public final fun properties (Lkotlin/jvm/functions/Function1;)V - public final fun setName (Ljava/lang/String;)V + public final fun setName (Lspace/kscience/dataforge/names/Name;)V } -public final class space/kscience/dataforge/context/ContextKt { - public static final fun Context (Ljava/lang/String;Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; - public static synthetic fun Context$default (Ljava/lang/String;Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context; +public final class space/kscience/dataforge/context/ContextBuilderKt { +} + +public final class space/kscience/dataforge/context/DefaultLogManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/dataforge/context/LogManager { + public static final field Companion Lspace/kscience/dataforge/context/DefaultLogManager$Companion; + public fun ()V + public fun getTag ()Lspace/kscience/dataforge/context/PluginTag; + public fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V +} + +public final class space/kscience/dataforge/context/DefaultLogManager$Companion : space/kscience/dataforge/context/PluginFactory { + public fun getTag ()Lspace/kscience/dataforge/context/PluginTag; + public fun getType ()Lkotlin/reflect/KClass; + public synthetic fun invoke (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;)Ljava/lang/Object; + public fun invoke (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/DefaultLogManager; } public abstract interface class space/kscience/dataforge/context/Factory { @@ -88,12 +101,13 @@ public final class space/kscience/dataforge/context/Factory$DefaultImpls { public final class space/kscience/dataforge/context/Global : space/kscience/dataforge/context/Context { public static final field INSTANCE Lspace/kscience/dataforge/context/Global; - public fun close ()V - public final fun context (Ljava/lang/String;Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; - public static synthetic fun context$default (Lspace/kscience/dataforge/context/Global;Ljava/lang/String;Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context; - public final fun getContext (Ljava/lang/String;)Lspace/kscience/dataforge/context/Context; public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext; - public final fun getLogger ()Lspace/kscience/dataforge/context/LogManager; + public final fun getDefaultLogger ()Lspace/kscience/dataforge/context/LogManager; +} + +public final class space/kscience/dataforge/context/GlobalKt { + public static final fun Context (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; + public static synthetic fun Context$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context; } public abstract interface class space/kscience/dataforge/context/LogManager : space/kscience/dataforge/context/Logable, space/kscience/dataforge/context/Plugin { @@ -128,7 +142,7 @@ public final class space/kscience/dataforge/context/LogManagerKt { public static final fun error (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V public static synthetic fun error$default (Lspace/kscience/dataforge/context/Logable;Ljava/lang/Throwable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V public static synthetic fun error$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V - public static final fun getLogger (Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/LogManager; + public static final fun getLogger (Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/Logable; public static final fun getLogger (Lspace/kscience/dataforge/context/ContextAware;)Lspace/kscience/dataforge/context/Logable; public static final fun info (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V public static synthetic fun info$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt index 081d44d8..56a10925 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt @@ -11,6 +11,7 @@ import space.kscience.dataforge.misc.Named import space.kscience.dataforge.names.Name import space.kscience.dataforge.provider.Provider import kotlin.coroutines.CoroutineContext +import kotlin.jvm.Synchronized /** * The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top. @@ -31,12 +32,13 @@ public open class Context internal constructor( /** * Context properties. Working as substitute for environment variables */ - private val properties: Laminate = if (parent == null) { + public val properties: Laminate = if (parent == null) { Laminate(meta) } else { Laminate(meta, parent.properties) } + /** * A [PluginManager] for current context */ @@ -68,10 +70,24 @@ public open class Context internal constructor( } } + private val childrenContexts = HashMap() + /** - * Detach all plugins and terminate context + * Build and register a child context + */ + @Synchronized + public fun buildContext(block: ContextBuilder.() -> Unit): Context{ + val newContext = ContextBuilder(this).apply(block).build() + childrenContexts[newContext.name] = newContext + return newContext + } + + /** + * Detach all plugins, and close child contexts */ public open fun close() { + //recursively closed child context + childrenContexts.forEach { it.value.close() } //detach all plugins plugins.forEach { it.detach() } } @@ -87,9 +103,6 @@ public open class Context internal constructor( } } -public fun Context(name: String, parent: Context = Global, block: ContextBuilder.() -> Unit = {}): Context = - Global.context(name, parent, block) - /** * The interface for something that encapsulated in context * diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt index f367b5d4..5f9b86b8 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt @@ -3,8 +3,11 @@ package space.kscience.dataforge.context import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaBuilder import space.kscience.dataforge.meta.seal +import space.kscience.dataforge.meta.toMutableMeta import space.kscience.dataforge.misc.DFBuilder import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.toName import kotlin.collections.component1 import kotlin.collections.component2 @@ -14,14 +17,22 @@ import kotlin.collections.set * A convenience builder for context */ @DFBuilder -public class ContextBuilder(private val parent: Context = Global, public var name: String = "@anonymous") { - private val factories = HashMap, Meta>() - private var meta = MetaBuilder() +public class ContextBuilder internal constructor( + private val parent: Context, + public var name: Name? = null, + meta: Meta = Meta.EMPTY, +) { + internal val factories = HashMap, Meta>() + internal var meta = meta.toMutableMeta() public fun properties(action: MetaBuilder.() -> Unit) { meta.action() } + public fun name(string: String){ + this.name = string.toName() + } + @OptIn(DFExperimental::class) private fun findPluginFactory(tag: PluginTag): PluginFactory<*> = parent.gatherInSequence>(PluginFactory.TYPE).values @@ -32,6 +43,10 @@ public class ContextBuilder(private val parent: Context = Global, public var nam factories[factory] = Meta(metaBuilder) } + public fun plugin(factory: PluginFactory<*>, meta: Meta){ + factories[factory] = meta + } + public fun plugin(factory: PluginFactory<*>, metaBuilder: MetaBuilder.() -> Unit = {}) { factories[factory] = Meta(metaBuilder) } @@ -41,10 +56,29 @@ public class ContextBuilder(private val parent: Context = Global, public var nam } public fun build(): Context { - return Context(name.toName(), parent, meta.seal()).apply { + val contextName = name ?: "@auto[${hashCode().toUInt().toString(16)}]".toName() + return Context(contextName, parent, meta.seal()).apply { factories.forEach { (factory, meta) -> plugins.load(factory, meta) } } } +} + +/** + * Check if current context contains all plugins required by the builder and return it it does or forks to a new context + * if it does not. + */ +public fun Context.withEnv(block: ContextBuilder.() -> Unit): Context { + + fun Context.contains(factory: PluginFactory<*>, meta: Meta): Boolean { + val loaded = plugins[factory.tag] ?: return false + return loaded.meta == meta + } + + val builder = ContextBuilder(this, name + "env", properties).apply(block) + val requiresFork = builder.factories.any { (factory, meta) -> + !contains(factory, meta) + } || ((properties as Meta) == builder.meta) + return if (requiresFork) builder.build() else this } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Global.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Global.kt index 645b0805..45ff3c60 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Global.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Global.kt @@ -1,7 +1,7 @@ package space.kscience.dataforge.context import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.Job import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.asName import kotlin.coroutines.CoroutineContext @@ -13,43 +13,10 @@ internal expect val globalLoggerFactory: PluginFactory * A global root context. Closing [Global] terminates the framework. */ @ThreadLocal -public object Global : Context("GLOBAL".asName(), null, Meta.EMPTY) { +private object GlobalContext : Context("GLOBAL".asName(), null, Meta.EMPTY) { + override val coroutineContext: CoroutineContext = GlobalScope.coroutineContext + Job() +} - override val coroutineContext: CoroutineContext = GlobalScope.coroutineContext + SupervisorJob() +public val Global: Context get() = GlobalContext - /** - * The default logging manager - */ - public val logger: LogManager by lazy { globalLoggerFactory.invoke(context = this).apply { attach(this@Global) } } - - /** - * Closing all contexts - * - * @throws Exception - */ - override fun close() { - logger.info { "Shutting down GLOBAL" } - for (ctx in contextRegistry.values) { - ctx.close() - } - super.close() - } - - private val contextRegistry = HashMap() - - /** - * Get previously built context - * - * @param name - * @return - */ - public fun getContext(name: String): Context? { - return contextRegistry[name] - } - - public fun context(name: String, parent: Context = this, block: ContextBuilder.() -> Unit = {}): Context = - ContextBuilder(parent, name).apply(block).build().also { - contextRegistry[name] = it - } - -} \ No newline at end of file +public fun Context(block: ContextBuilder.() -> Unit = {}): Context = Global.buildContext(block) \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/LogManager.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/LogManager.kt index 2deda918..10f9c7af 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/LogManager.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/LogManager.kt @@ -1,15 +1,16 @@ package space.kscience.dataforge.context +import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.misc.Named import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus +import kotlin.reflect.KClass -public interface Logable { +public fun interface Logable { public fun log(name: Name, tag: String, body: () -> String) } public interface LogManager : Plugin, Logable { - public companion object { public const val TRACE: String = "TRACE" public const val INFO: String = "INFO" @@ -41,11 +42,30 @@ public fun Logable.error(throwable: Throwable?, name: Name = Name.EMPTY, body: ( } } + +public class DefaultLogManager : AbstractPlugin(), LogManager { + + override fun log(name: Name, tag: String, body: () -> String) { + val message: String = body.safe + println("[${context.name}] $name: $message") + } + + override val tag: PluginTag get() = Companion.tag + + public companion object : PluginFactory { + override fun invoke(meta: Meta, context: Context): DefaultLogManager = DefaultLogManager() + + override val tag: PluginTag = PluginTag(group = PluginTag.DATAFORGE_GROUP, name = "log.default") + override val type: KClass = DefaultLogManager::class + } +} + /** * Context log manager inherited from parent */ -public val Context.logger: LogManager - get() = plugins.find(inherit = true) { it is LogManager } as? LogManager ?: Global.logger +public val Context.logger: Logable + get() = plugins.find(inherit = true) { it is LogManager } as? LogManager + ?: globalLoggerFactory(context = Global).apply { attach(Global) } /** * The named proxy logger for a context member diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Plugin.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Plugin.kt index 5929515e..d0f03172 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Plugin.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Plugin.kt @@ -63,5 +63,4 @@ public interface Plugin : Named, ContextAware, Provider, MetaRepr { public companion object { public const val TARGET: String = "plugin" } - } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt index 3e045bb5..540b200d 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt @@ -13,8 +13,6 @@ import kotlin.reflect.KClass */ public class PluginManager(override val context: Context) : ContextAware, Iterable { - //TODO refactor to read-only container - /** * A set of loaded plugins */ @@ -85,6 +83,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab * @param plugin * @return */ + @Deprecated("Use immutable contexts instead") public fun load(plugin: T): T { if (get(plugin::class, plugin.tag, recursive = false) != null) { error("Plugin with tag ${plugin.tag} already exists in ${context.name}") @@ -93,7 +92,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab fetch(factory, meta, true) } - Global.logger.info { "Loading plugin ${plugin.name} into ${context.name}" } + logger.info { "Loading plugin ${plugin.name} into ${context.name}" } plugin.attach(context) plugins.add(plugin) return plugin @@ -103,15 +102,18 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab /** * Load a plugin using its factory */ + @Deprecated("Use immutable contexts instead") public fun load(factory: PluginFactory, meta: Meta = Meta.EMPTY): T = load(factory(meta, context)) + @Deprecated("Use immutable contexts instead") public fun load(factory: PluginFactory, metaBuilder: MetaBuilder.() -> Unit): T = load(factory, Meta(metaBuilder)) /** * Remove a plugin from [PluginManager] */ + @Deprecated("Use immutable contexts instead") public fun remove(plugin: Plugin) { if (plugins.contains(plugin)) { Global.logger.info { "Removing plugin ${plugin.name} from ${context.name}" } @@ -123,6 +125,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab /** * Get an existing plugin with given meta or load new one using provided factory */ + @Deprecated("Use immutable contexts instead") public fun fetch(factory: PluginFactory, meta: Meta = Meta.EMPTY, recursive: Boolean = true): T { val loaded = get(factory.type, factory.tag, recursive) return when { @@ -132,6 +135,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab } } + @Deprecated("Use immutable contexts instead") public fun fetch( factory: PluginFactory, recursive: Boolean = true, @@ -140,4 +144,18 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab override fun iterator(): Iterator = plugins.iterator() +} + +/** + * Fetch a plugin with given meta from the context. If the plugin (with given meta) is already registered, it is returned. + * Otherwise, new child context with the plugin is created. In the later case the context could be retrieved from the plugin. + */ +public inline fun Context.fetch(factory: PluginFactory, meta: Meta = Meta.EMPTY): T { + val existing = plugins[factory] + return if (existing != null && existing.meta == meta) existing + else { + buildContext { + plugin(factory, meta) + }.plugins[factory]!! + } } \ No newline at end of file diff --git a/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/context/ContextTest.kt b/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/context/ContextTest.kt index 4bc937aa..262d49f1 100644 --- a/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/context/ContextTest.kt +++ b/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/context/ContextTest.kt @@ -22,7 +22,9 @@ class ContextTest { @Test fun testPluginManager() { - val context = Global.context("test") + val context = Global.buildContext{ + name("test") + } context.plugins.load(DummyPlugin()) //Global.plugins.load(DummyPlugin()) val members = context.gather("test") diff --git a/dataforge-context/src/nativeMain/kotlin/space/kscience/dataforge/context/loggingNative.kt b/dataforge-context/src/nativeMain/kotlin/space/kscience/dataforge/context/loggingNative.kt index f890b238..62512132 100644 --- a/dataforge-context/src/nativeMain/kotlin/space/kscience/dataforge/context/loggingNative.kt +++ b/dataforge-context/src/nativeMain/kotlin/space/kscience/dataforge/context/loggingNative.kt @@ -1,25 +1,4 @@ package space.kscience.dataforge.context -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.names.Name -import kotlin.reflect.KClass - -public class NativeLogManager : AbstractPlugin(), LogManager { - - override fun log(name: Name, tag: String, body: () -> String) { - val message: String = body.safe - println("[${context.name}] $name: $message") - } - - override val tag: PluginTag get() = Companion.tag - - public companion object : PluginFactory { - override fun invoke(meta: Meta, context: Context): NativeLogManager = NativeLogManager() - - override val tag: PluginTag = PluginTag(group = PluginTag.DATAFORGE_GROUP, name = "log.native") - override val type: KClass = NativeLogManager::class - } -} - -internal actual val globalLoggerFactory: PluginFactory = NativeLogManager +internal actual val globalLoggerFactory: PluginFactory = DefaultLogManager diff --git a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/IOPlugin.kt b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/IOPlugin.kt index 4a723967..91442603 100644 --- a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/IOPlugin.kt +++ b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/IOPlugin.kt @@ -9,6 +9,7 @@ import space.kscience.dataforge.io.MetaFormatFactory.Companion.META_FORMAT_TYPE import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.toName +import kotlin.native.concurrent.ThreadLocal import kotlin.reflect.KClass public class IOPlugin(meta: Meta) : AbstractPlugin(meta) { @@ -62,7 +63,8 @@ public class IOPlugin(meta: Meta) : AbstractPlugin(meta) { public companion object : PluginFactory { public val defaultMetaFormats: List = listOf(JsonMetaFormat, BinaryMetaFormat) - public val defaultEnvelopeFormats: List = listOf(TaggedEnvelopeFormat, TaglessEnvelopeFormat) + public val defaultEnvelopeFormats: List = + listOf(TaggedEnvelopeFormat, TaglessEnvelopeFormat) override val tag: PluginTag = PluginTag("io", group = PluginTag.DATAFORGE_GROUP) @@ -71,4 +73,10 @@ public class IOPlugin(meta: Meta) : AbstractPlugin(meta) { } } -public val Context.io: IOPlugin get() = plugins.fetch(IOPlugin) \ No newline at end of file +@ThreadLocal +internal val ioContext = Global.withEnv { + name("IO") + plugin(IOPlugin) +} + +public val Context.io: IOPlugin get() = (if (this == Global) ioContext else this).fetch(IOPlugin) \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/TaggedEnvelopeFormat.kt b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/TaggedEnvelopeFormat.kt index ad0d1aa4..dfc5f233 100644 --- a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/TaggedEnvelopeFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/TaggedEnvelopeFormat.kt @@ -161,7 +161,7 @@ public class TaggedEnvelopeFormat( } } - private val default by lazy { invoke() } + private val default by lazy { invoke(context = ioContext) } override fun readPartial(input: Input): PartialEnvelope = default.run { readPartial(input) } diff --git a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/TaglessEnvelopeFormat.kt b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/TaglessEnvelopeFormat.kt index 30dce96b..e1a55607 100644 --- a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/TaglessEnvelopeFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/TaglessEnvelopeFormat.kt @@ -197,7 +197,7 @@ public class TaglessEnvelopeFormat( return TaglessEnvelopeFormat(context.io, meta) } - private val default by lazy { invoke() } + private val default by lazy { invoke(context = ioContext) } override fun readPartial(input: Input): PartialEnvelope = default.run { readPartial(input) } diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index f5e908d2..abec55f4 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -193,6 +193,7 @@ public abstract interface class space/kscience/dataforge/meta/Meta : space/kscie public final class space/kscience/dataforge/meta/Meta$Companion { public static final field TYPE Ljava/lang/String; public static final field VALUE_KEY Ljava/lang/String; + public final fun equals (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;)Z public final fun getEMPTY ()Lspace/kscience/dataforge/meta/Meta; } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Meta.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Meta.kt index 46ff1d9b..12a03a62 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Meta.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Meta.kt @@ -54,6 +54,8 @@ public interface Meta : MetaRepr, ItemProvider { */ public const val VALUE_KEY: String = "@value" + public fun equals(meta1: Meta, meta2: Meta): Boolean = meta1.items == meta2.items + public val EMPTY: Meta = object : MetaBase() { override val items: Map = emptyMap() } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/TypedMeta.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/TypedMeta.kt index 9d064e11..cd1c3c47 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/TypedMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/TypedMeta.kt @@ -32,7 +32,7 @@ public operator fun > M.get(key: NameToken): TypedMetaItem? public abstract class MetaBase : Meta { override fun equals(other: Any?): Boolean = if (other is Meta) { - this.items == other.items + Meta.equals(this, other) } else { false } diff --git a/dataforge-scripting/src/jvmTest/kotlin/space/kscience/dataforge/scripting/BuildersKtTest.kt b/dataforge-scripting/src/jvmTest/kotlin/space/kscience/dataforge/scripting/BuildersKtTest.kt index 8059b070..c0f557e4 100644 --- a/dataforge-scripting/src/jvmTest/kotlin/space/kscience/dataforge/scripting/BuildersKtTest.kt +++ b/dataforge-scripting/src/jvmTest/kotlin/space/kscience/dataforge/scripting/BuildersKtTest.kt @@ -4,7 +4,6 @@ import space.kscience.dataforge.context.Global import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.workspace.WorkspaceBuilder - import space.kscience.dataforge.workspace.target import kotlin.test.Test import kotlin.test.assertEquals @@ -12,13 +11,13 @@ import kotlin.test.assertEquals class BuildersKtTest { @Test - fun checkBuilder(){ + fun checkBuilder() { val workspace = WorkspaceBuilder(Global).apply { println("I am working") - context("test") + context { name("test") } - target("testTarget"){ + target("testTarget") { "a" put 12 } } @@ -29,7 +28,7 @@ class BuildersKtTest { val script = """ println("I am working") - context("test") + context{ name("test") } target("testTarget"){ "a" put 12 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 5d475cd8..1a6c240f 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 @@ -50,8 +50,8 @@ public class WorkspaceBuilder(private val parentContext: Context = Global) : Tas /** * Define a context for the workspace */ - public fun context(name: String = "workspace", block: ContextBuilder.() -> Unit = {}) { - this.context = ContextBuilder(parentContext, name).apply(block).build() + public fun context(block: ContextBuilder.() -> Unit = {}) { + this.context = parentContext.buildContext(block) } /** From 23f1d4f7fd2228504e6bf518acb6d2ea77a5fbcc Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 6 Apr 2021 17:19:24 +0300 Subject: [PATCH 03/11] Add item property listeners and item property binding tests --- dataforge-context/api/dataforge-context.api | 14 +++------ .../dataforge/context/PluginManager.kt | 7 +---- .../dataforge/properties/schemeProperty.kt | 29 +++++++++++++++++ .../properties/ItemPropertiesTest.kt | 26 ++++++++++++++++ dataforge-meta/api/dataforge-meta.api | 22 +++++-------- .../space/kscience/dataforge/meta/Config.kt | 12 +------ .../dataforge/meta/ObservableItemProvider.kt | 31 +++++++++++++++++++ .../space/kscience/dataforge/meta/Scheme.kt | 2 +- .../kscience/dataforge/meta/SchemeTest.kt | 11 +++++++ 9 files changed, 113 insertions(+), 41 deletions(-) create mode 100644 dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt create mode 100644 dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/properties/ItemPropertiesTest.kt create mode 100644 dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt diff --git a/dataforge-context/api/dataforge-context.api b/dataforge-context/api/dataforge-context.api index 1b1a849f..0f518890 100644 --- a/dataforge-context/api/dataforge-context.api +++ b/dataforge-context/api/dataforge-context.api @@ -75,6 +75,7 @@ public final class space/kscience/dataforge/context/ContextBuilder { } public final class space/kscience/dataforge/context/ContextBuilderKt { + public static final fun withEnv (Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; } public final class space/kscience/dataforge/context/DefaultLogManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/dataforge/context/LogManager { @@ -99,15 +100,10 @@ public final class space/kscience/dataforge/context/Factory$DefaultImpls { public static synthetic fun invoke$default (Lspace/kscience/dataforge/context/Factory;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;ILjava/lang/Object;)Ljava/lang/Object; } -public final class space/kscience/dataforge/context/Global : space/kscience/dataforge/context/Context { - public static final field INSTANCE Lspace/kscience/dataforge/context/Global; - public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext; - public final fun getDefaultLogger ()Lspace/kscience/dataforge/context/LogManager; -} - public final class space/kscience/dataforge/context/GlobalKt { public static final fun Context (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; public static synthetic fun Context$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context; + public static final fun getGlobal ()Lspace/kscience/dataforge/context/Context; } public abstract interface class space/kscience/dataforge/context/LogManager : space/kscience/dataforge/context/Logable, space/kscience/dataforge/context/Plugin { @@ -207,9 +203,6 @@ public final class space/kscience/dataforge/context/PluginManager : java/lang/It public fun iterator ()Ljava/util/Iterator; public final fun list (Z)Ljava/util/Collection; public final fun load (Lspace/kscience/dataforge/context/Plugin;)Lspace/kscience/dataforge/context/Plugin; - public final fun load (Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Plugin; - public final fun load (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/context/Plugin; - public static synthetic fun load$default (Lspace/kscience/dataforge/context/PluginManager;Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Plugin; public final fun remove (Lspace/kscience/dataforge/context/Plugin;)V } @@ -289,6 +282,9 @@ public final class space/kscience/dataforge/properties/Property$DefaultImpls { public final class space/kscience/dataforge/properties/PropertyKt { } +public final class space/kscience/dataforge/properties/SchemePropertyKt { +} + public final class space/kscience/dataforge/provider/DfTypeKt { public static final fun getDfType (Lkotlin/reflect/KClass;)Ljava/lang/String; } diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt index 540b200d..e738addd 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt @@ -102,14 +102,9 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab /** * Load a plugin using its factory */ - @Deprecated("Use immutable contexts instead") - public fun load(factory: PluginFactory, meta: Meta = Meta.EMPTY): T = + internal fun load(factory: PluginFactory, meta: Meta = Meta.EMPTY): T = load(factory(meta, context)) - @Deprecated("Use immutable contexts instead") - public fun load(factory: PluginFactory, metaBuilder: MetaBuilder.() -> Unit): T = - load(factory, Meta(metaBuilder)) - /** * Remove a plugin from [PluginManager] */ diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt new file mode 100644 index 00000000..a2f39eed --- /dev/null +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt @@ -0,0 +1,29 @@ +package space.kscience.dataforge.properties + +import space.kscience.dataforge.meta.ItemPropertyProvider +import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.toName +import kotlin.reflect.KMutableProperty1 + +@DFExperimental +public fun

P.property(property: KMutableProperty1): Property = + object : Property { + override var value: T? + get() = property.get(this@property) + set(value) { + property.set(this@property, value) + } + + override fun onChange(owner: Any?, callback: (T?) -> Unit) { + this@property.onChange(this) { name, oldItem, newItem -> + if (name == property.name.toName() && oldItem != newItem) { + callback(property.get(this@property)) + } + } + } + + override fun removeChangeListener(owner: Any?) { + this@property.removeListener(this@property) + } + + } \ No newline at end of file diff --git a/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/properties/ItemPropertiesTest.kt b/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/properties/ItemPropertiesTest.kt new file mode 100644 index 00000000..b2d8c2e6 --- /dev/null +++ b/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/properties/ItemPropertiesTest.kt @@ -0,0 +1,26 @@ +package space.kscience.dataforge.properties + +import space.kscience.dataforge.meta.Scheme +import space.kscience.dataforge.meta.SchemeSpec +import space.kscience.dataforge.meta.int +import kotlin.test.Test +import kotlin.test.assertEquals + +internal class TestScheme : Scheme() { + var a by int() + var b by int() + companion object : SchemeSpec(::TestScheme) +} + +class ItemPropertiesTest { + @Test + fun testBinding() { + val scheme = TestScheme.empty() + val a = scheme.property(TestScheme::a) + val b = scheme.property(TestScheme::b) + a.bind(b) + scheme.a = 2 + assertEquals(2, scheme.b) + assertEquals(2, b.value) + } +} \ No newline at end of file diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index abec55f4..80b944b5 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -12,7 +12,7 @@ public abstract class space/kscience/dataforge/meta/AbstractTypedMeta : space/ks public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; } -public final class space/kscience/dataforge/meta/Config : space/kscience/dataforge/meta/AbstractMutableMeta, space/kscience/dataforge/meta/ObservableItemProvider { +public final class space/kscience/dataforge/meta/Config : space/kscience/dataforge/meta/AbstractMutableMeta, space/kscience/dataforge/meta/ItemPropertyProvider { public static final field ConfigSerializer Lspace/kscience/dataforge/meta/Config$ConfigSerializer; public fun ()V public synthetic fun empty$dataforge_meta ()Lspace/kscience/dataforge/meta/MutableMeta; @@ -94,18 +94,7 @@ public final class space/kscience/dataforge/meta/ItemDelegateKt { public static synthetic fun value$default (Lspace/kscience/dataforge/meta/ItemProvider;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; } -public final class space/kscience/dataforge/meta/ItemListener { - public fun (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V - public synthetic fun (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/lang/Object; - public final fun component2 ()Lkotlin/jvm/functions/Function3; - public final fun copy (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Lspace/kscience/dataforge/meta/ItemListener; - public static synthetic fun copy$default (Lspace/kscience/dataforge/meta/ItemListener;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/ItemListener; - public fun equals (Ljava/lang/Object;)Z - public final fun getAction ()Lkotlin/jvm/functions/Function3; - public final fun getOwner ()Ljava/lang/Object; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; +public abstract interface class space/kscience/dataforge/meta/ItemPropertyProvider : space/kscience/dataforge/meta/MutableItemProvider, space/kscience/dataforge/meta/ObservableItemProvider { } public abstract interface class space/kscience/dataforge/meta/ItemProvider { @@ -424,6 +413,11 @@ public abstract interface class space/kscience/dataforge/meta/ObservableItemProv public abstract fun removeListener (Ljava/lang/Object;)V } +public final class space/kscience/dataforge/meta/ObservableItemProviderKt { + public static final fun onChange (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun onChange$default (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V +} + public abstract interface class space/kscience/dataforge/meta/ReadOnlySpecification { public abstract fun empty ()Lspace/kscience/dataforge/meta/ItemProvider; public abstract fun invoke (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider; @@ -434,7 +428,7 @@ public final class space/kscience/dataforge/meta/ReadOnlySpecification$DefaultIm public static fun invoke (Lspace/kscience/dataforge/meta/ReadOnlySpecification;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider; } -public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/MutableItemProvider, space/kscience/dataforge/meta/ObservableItemProvider, space/kscience/dataforge/meta/descriptors/Described { +public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/ItemPropertyProvider, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/descriptors/Described { public fun ()V public fun getDefaultLayer ()Lspace/kscience/dataforge/meta/Meta; public synthetic fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt index a69b9a22..20fb1cb2 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt @@ -14,21 +14,11 @@ import kotlin.jvm.Synchronized //TODO add validator to configuration -public data class ItemListener( - val owner: Any? = null, - val action: (name: Name, oldItem: MetaItem?, newItem: MetaItem?) -> Unit -) - -public interface ObservableItemProvider : ItemProvider { - public fun onChange(owner: Any?, action: (name: Name, oldItem: MetaItem?, newItem: MetaItem?) -> Unit) - public fun removeListener(owner: Any?) -} - /** * Mutable meta representing object state */ @Serializable(Config.Companion::class) -public class Config() : AbstractMutableMeta(), ObservableItemProvider { +public class Config : AbstractMutableMeta(), ItemPropertyProvider { private val listeners = HashSet() diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt new file mode 100644 index 00000000..1a11441b --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt @@ -0,0 +1,31 @@ +package space.kscience.dataforge.meta + +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.toName +import kotlin.reflect.KProperty1 + + +internal data class ItemListener( + val owner: Any? = null, + val action: (name: Name, oldItem: MetaItem?, newItem: MetaItem?) -> Unit, +) + + +public interface ObservableItemProvider : ItemProvider { + public fun onChange(owner: Any?, action: (name: Name, oldItem: MetaItem?, newItem: MetaItem?) -> Unit) + public fun removeListener(owner: Any?) +} + +public interface ItemPropertyProvider: ObservableItemProvider, MutableItemProvider + +public fun O.onChange( + property: KProperty1, + owner: Any? = null, + callBack: O.(T?) -> Unit, +) { + onChange(null) { name, oldItem, newItem -> + if (name == property.name.toName() && oldItem != newItem) { + callBack(property.get(this)) + } + } +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt index 613161e1..07816965 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Scheme.kt @@ -10,7 +10,7 @@ import kotlin.jvm.Synchronized * A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [Specification]. * Default item provider and [NodeDescriptor] are optional */ -public open class Scheme() : MutableItemProvider, Described, MetaRepr, ObservableItemProvider { +public open class Scheme() : Described, MetaRepr, ItemPropertyProvider { private var items: MutableItemProvider = Config() diff --git a/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/SchemeTest.kt b/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/SchemeTest.kt index c9d80119..d2407bb4 100644 --- a/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/SchemeTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/SchemeTest.kt @@ -20,4 +20,15 @@ class SchemeTest { scheme.retarget(config) assertEquals(29, scheme.a) } + + @Test + fun testSchemeSubscription(){ + val scheme = TestScheme.empty() + var flag: Int? = null + scheme.onChange(TestScheme::a){a-> + flag = a + } + scheme.a = 2 + assertEquals(2, flag) + } } \ No newline at end of file From 187094d94215c93024cf204b0e246130d6cf2dc0 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 7 Apr 2021 11:39:24 +0300 Subject: [PATCH 04/11] Kotlin 1.5. Further context plugins readOnlyZation --- CHANGELOG.md | 1 + build.gradle.kts | 2 +- dataforge-context/api/dataforge-context.api | 2 +- .../kscience/dataforge/context/ContextBuilder.kt | 11 +++++++++-- .../space/kscience/dataforge/context/PluginFactory.kt | 10 ++++++++++ .../space/kscience/dataforge/context/PluginManager.kt | 3 ++- .../space/kscience/dataforge/properties/Property.kt | 5 ++--- .../kotlin/space/kscience/dataforge/provider/Path.kt | 4 +++- .../space/kscience/dataforge/context/ContextTest.kt | 3 +-- .../dataforge/properties/ItemPropertiesTest.kt | 2 ++ dataforge-meta/api/dataforge-meta.api | 1 - .../meta/transformations/MetaTransformation.kt | 4 +++- .../space/kscience/dataforge/tables/RowTable.kt | 4 +++- settings.gradle.kts | 4 ++-- 14 files changed, 40 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 980aad47..c37535c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Package changed to `space.kscience` - Scheme made observable - Global context is a variable (the singleton is hidden and will be deprecated in future) +- Kotlin 1.5 ### Deprecated - Direct use of PluginManager diff --git a/build.gradle.kts b/build.gradle.kts index 6fdbfd60..741293ae 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { allprojects { group = "space.kscience" - version = "0.4.0-dev-5" + version = "0.4.0-dev-6" } subprojects { diff --git a/dataforge-context/api/dataforge-context.api b/dataforge-context/api/dataforge-context.api index 0f518890..b82d7a01 100644 --- a/dataforge-context/api/dataforge-context.api +++ b/dataforge-context/api/dataforge-context.api @@ -64,6 +64,7 @@ public final class space/kscience/dataforge/context/ContextBuilder { public final fun getName ()Lspace/kscience/dataforge/names/Name; public final fun name (Ljava/lang/String;)V public final fun plugin (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public final fun plugin (Lspace/kscience/dataforge/context/Plugin;)V public final fun plugin (Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)V public final fun plugin (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)V public final fun plugin (Lspace/kscience/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;)V @@ -202,7 +203,6 @@ public final class space/kscience/dataforge/context/PluginManager : java/lang/It public fun getContext ()Lspace/kscience/dataforge/context/Context; public fun iterator ()Ljava/util/Iterator; public final fun list (Z)Ljava/util/Collection; - public final fun load (Lspace/kscience/dataforge/context/Plugin;)Lspace/kscience/dataforge/context/Plugin; public final fun remove (Lspace/kscience/dataforge/context/Plugin;)V } diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt index 5f9b86b8..eceb0e3d 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt @@ -29,7 +29,7 @@ public class ContextBuilder internal constructor( meta.action() } - public fun name(string: String){ + public fun name(string: String) { this.name = string.toName() } @@ -43,7 +43,7 @@ public class ContextBuilder internal constructor( factories[factory] = Meta(metaBuilder) } - public fun plugin(factory: PluginFactory<*>, meta: Meta){ + public fun plugin(factory: PluginFactory<*>, meta: Meta) { factories[factory] = meta } @@ -55,6 +55,13 @@ public class ContextBuilder internal constructor( plugin(PluginTag(name, group, version), action) } + /** + * Add de-facto existing plugin as a dependency + */ + public fun plugin(plugin: Plugin) { + plugin(DeFactoPluginFactory(plugin)) + } + public fun build(): Context { val contextName = name ?: "@auto[${hashCode().toUInt().toString(16)}]".toName() return Context(contextName, parent, meta.seal()).apply { diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginFactory.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginFactory.kt index 78784be5..854f2d1c 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginFactory.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginFactory.kt @@ -1,5 +1,6 @@ package space.kscience.dataforge.context +import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.misc.Type import kotlin.reflect.KClass @@ -12,3 +13,12 @@ public interface PluginFactory : Factory { public const val TYPE: String = "pluginFactory" } } + +/** + * Plugin factory created for the specific actual plugin + */ +internal class DeFactoPluginFactory(val plugin: T) : PluginFactory { + override fun invoke(meta: Meta, context: Context): T = plugin + override val tag: PluginTag get() = plugin.tag + override val type: KClass get() = plugin::class +} diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt index e738addd..0fd1e9e1 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/PluginManager.kt @@ -84,7 +84,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab * @return */ @Deprecated("Use immutable contexts instead") - public fun load(plugin: T): T { + private fun load(plugin: T): T { if (get(plugin::class, plugin.tag, recursive = false) != null) { error("Plugin with tag ${plugin.tag} already exists in ${context.name}") } else { @@ -102,6 +102,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab /** * Load a plugin using its factory */ + @Deprecated("Use immutable contexts instead") internal fun load(factory: PluginFactory, meta: Meta = Meta.EMPTY): T = load(factory(meta, context)) diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/Property.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/Property.kt index a6419f0b..7b0280eb 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/Property.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/Property.kt @@ -1,6 +1,5 @@ package space.kscience.dataforge.properties -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -23,12 +22,12 @@ public fun Property.toFlow(): StateFlow = MutableStateFlow(value).also } /** - * Reflect all changes in the [source] property onto this property + * Reflect all changes in the [source] property onto this property. Does not reflect changes back. * * @return a mirroring job */ @DFExperimental -public fun Property.mirror(source: Property, scope: CoroutineScope) { +public fun Property.mirror(source: Property) { source.onChange(this) { this.value = it } diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/provider/Path.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/provider/Path.kt index 0746feba..2a16e53f 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/provider/Path.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/provider/Path.kt @@ -17,12 +17,14 @@ package space.kscience.dataforge.provider import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.toName +import kotlin.jvm.JvmInline /** * Path interface. * */ -public inline class Path(public val tokens: List) : Iterable { +@JvmInline +public value class Path(public val tokens: List) : Iterable { override fun iterator(): Iterator = tokens.iterator() diff --git a/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/context/ContextTest.kt b/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/context/ContextTest.kt index 262d49f1..81fcf884 100644 --- a/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/context/ContextTest.kt +++ b/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/context/ContextTest.kt @@ -24,9 +24,8 @@ class ContextTest { fun testPluginManager() { val context = Global.buildContext{ name("test") + plugin(DummyPlugin()) } - context.plugins.load(DummyPlugin()) - //Global.plugins.load(DummyPlugin()) val members = context.gather("test") assertEquals(3, members.count()) members.forEach { diff --git a/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/properties/ItemPropertiesTest.kt b/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/properties/ItemPropertiesTest.kt index b2d8c2e6..df6a26f1 100644 --- a/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/properties/ItemPropertiesTest.kt +++ b/dataforge-context/src/commonTest/kotlin/space/kscience/dataforge/properties/ItemPropertiesTest.kt @@ -3,6 +3,7 @@ package space.kscience.dataforge.properties import space.kscience.dataforge.meta.Scheme import space.kscience.dataforge.meta.SchemeSpec import space.kscience.dataforge.meta.int +import space.kscience.dataforge.misc.DFExperimental import kotlin.test.Test import kotlin.test.assertEquals @@ -12,6 +13,7 @@ internal class TestScheme : Scheme() { companion object : SchemeSpec(::TestScheme) } +@DFExperimental class ItemPropertiesTest { @Test fun testBinding() { diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index 80b944b5..ad2d9612 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -658,7 +658,6 @@ public final class space/kscience/dataforge/meta/transformations/MetaTransformat public static fun equals-impl (Ljava/util/Collection;Ljava/lang/Object;)Z public static final fun equals-impl0 (Ljava/util/Collection;Ljava/util/Collection;)Z public static final fun generate-impl (Ljava/util/Collection;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Meta; - public final fun getTransformations ()Ljava/util/Collection; public fun hashCode ()I public static fun hashCode-impl (Ljava/util/Collection;)I public fun toString ()Ljava/lang/String; diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/transformations/MetaTransformation.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/transformations/MetaTransformation.kt index 908ca6b7..3a35dbf8 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/transformations/MetaTransformation.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/transformations/MetaTransformation.kt @@ -3,6 +3,7 @@ package space.kscience.dataforge.meta.transformations import space.kscience.dataforge.meta.* import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name +import kotlin.jvm.JvmInline /** * A transformation for meta item or a group of items @@ -85,7 +86,8 @@ public data class RegexItemTransformationRule( /** * A set of [TransformationRule] to either transform static meta or create dynamically updated [MutableMeta] */ -public inline class MetaTransformation(public val transformations: Collection) { +@JvmInline +public value class MetaTransformation(private val transformations: Collection) { /** * Produce new meta using only those items that match transformation rules diff --git a/dataforge-tables/src/commonMain/kotlin/space/kscience/dataforge/tables/RowTable.kt b/dataforge-tables/src/commonMain/kotlin/space/kscience/dataforge/tables/RowTable.kt index 9244a8a4..4c5bae5e 100644 --- a/dataforge-tables/src/commonMain/kotlin/space/kscience/dataforge/tables/RowTable.kt +++ b/dataforge-tables/src/commonMain/kotlin/space/kscience/dataforge/tables/RowTable.kt @@ -2,9 +2,11 @@ package space.kscience.dataforge.tables import kotlinx.coroutines.flow.toList import space.kscience.dataforge.meta.Meta +import kotlin.jvm.JvmInline import kotlin.reflect.KType -public inline class MapRow(private val values: Map) : Row { +@JvmInline +public value class MapRow(private val values: Map) : Row { override fun get(column: String): C? = values[column] } diff --git a/settings.gradle.kts b/settings.gradle.kts index c55ee461..7bebb33f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,8 +7,8 @@ pluginManagement { maven("https://dl.bintray.com/kotlin/kotlin-eap") } - val toolsVersion = "0.9.3" - val kotlinVersion = "1.4.32" + val toolsVersion = "0.9.4" + val kotlinVersion = "1.5.0-M2" plugins { id("ru.mipt.npm.gradle.project") version toolsVersion From 874a253292bfa01138b9938ec36bc06f13a8673e Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 7 Apr 2021 15:34:27 +0300 Subject: [PATCH 05/11] Fix property usage for ObservableItemProvider --- build.gradle.kts | 2 +- dataforge-meta/api/dataforge-meta.api | 3 +-- .../dataforge/meta/ObservableItemProvider.kt | 14 ++++++++++++-- .../space/kscience/dataforge/meta/SchemeTest.kt | 4 +++- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 741293ae..98a941bb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { allprojects { group = "space.kscience" - version = "0.4.0-dev-6" + version = "0.4.0-dev-7" } subprojects { diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index ad2d9612..47b38de5 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -414,8 +414,7 @@ public abstract interface class space/kscience/dataforge/meta/ObservableItemProv } public final class space/kscience/dataforge/meta/ObservableItemProviderKt { - public static final fun onChange (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V - public static synthetic fun onChange$default (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + public static synthetic fun useProperty$default (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V } public abstract interface class space/kscience/dataforge/meta/ReadOnlySpecification { diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt index 1a11441b..5d455d17 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt @@ -1,5 +1,6 @@ package space.kscience.dataforge.meta +import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.toName import kotlin.reflect.KProperty1 @@ -18,12 +19,21 @@ public interface ObservableItemProvider : ItemProvider { public interface ItemPropertyProvider: ObservableItemProvider, MutableItemProvider -public fun O.onChange( +/** + * Use the value of the property in a [callBack]. + * The callback is called once immediately after subscription to pass the initial value. + * + * Optional [owner] property is used for + */ +@DFExperimental +public fun O.useProperty( property: KProperty1, owner: Any? = null, callBack: O.(T?) -> Unit, ) { - onChange(null) { name, oldItem, newItem -> + //Pass initial value. + callBack(property.get(this)) + onChange(owner) { name, oldItem, newItem -> if (name == property.name.toName() && oldItem != newItem) { callBack(property.get(this)) } diff --git a/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/SchemeTest.kt b/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/SchemeTest.kt index d2407bb4..2b55658e 100644 --- a/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/SchemeTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/space/kscience/dataforge/meta/SchemeTest.kt @@ -1,8 +1,10 @@ package space.kscience.dataforge.meta +import space.kscience.dataforge.misc.DFExperimental import kotlin.test.Test import kotlin.test.assertEquals +@DFExperimental class SchemeTest { @Test fun testSchemeWrappingBeforeEdit(){ @@ -25,7 +27,7 @@ class SchemeTest { fun testSchemeSubscription(){ val scheme = TestScheme.empty() var flag: Int? = null - scheme.onChange(TestScheme::a){a-> + scheme.useProperty(TestScheme::a){a-> flag = a } scheme.a = 2 From 53393e7958f518dad41329ada1e678342e63b207 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 7 Apr 2021 18:47:24 +0300 Subject: [PATCH 06/11] Cleaup context building API --- dataforge-context/api/dataforge-context.api | 7 ++++--- .../kotlin/space/kscience/dataforge/context/Context.kt | 7 +++++-- .../kotlin/space/kscience/dataforge/context/Global.kt | 3 ++- .../space/kscience/dataforge/workspace/WorkspaceBuilder.kt | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/dataforge-context/api/dataforge-context.api b/dataforge-context/api/dataforge-context.api index b82d7a01..8dfdab6e 100644 --- a/dataforge-context/api/dataforge-context.api +++ b/dataforge-context/api/dataforge-context.api @@ -38,7 +38,8 @@ public final class space/kscience/dataforge/context/ClassLoaderPluginKt { public class space/kscience/dataforge/context/Context : kotlinx/coroutines/CoroutineScope, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/misc/Named, space/kscience/dataforge/provider/Provider { public static final field Companion Lspace/kscience/dataforge/context/Context$Companion; public static final field PROPERTY_TARGET Ljava/lang/String; - public final fun buildContext (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; + public final fun buildContext (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; + public static synthetic fun buildContext$default (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context; public fun close ()V public fun content (Ljava/lang/String;)Ljava/util/Map; public final fun content (Ljava/lang/String;Z)Ljava/util/Map; @@ -102,8 +103,8 @@ public final class space/kscience/dataforge/context/Factory$DefaultImpls { } public final class space/kscience/dataforge/context/GlobalKt { - public static final fun Context (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; - public static synthetic fun Context$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context; + public static final fun Context (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context; + public static synthetic fun Context$default (Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context; public static final fun getGlobal ()Lspace/kscience/dataforge/context/Context; } diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt index 56a10925..74bb062f 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt @@ -76,8 +76,11 @@ public open class Context internal constructor( * Build and register a child context */ @Synchronized - public fun buildContext(block: ContextBuilder.() -> Unit): Context{ - val newContext = ContextBuilder(this).apply(block).build() + public fun buildContext(name: String? = null, block: ContextBuilder.() -> Unit): Context { + val newContext = ContextBuilder(this) + .apply { name?.let { name(it) } } + .apply(block) + .build() childrenContexts[newContext.name] = newContext return newContext } diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Global.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Global.kt index 45ff3c60..fe22af62 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Global.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Global.kt @@ -19,4 +19,5 @@ private object GlobalContext : Context("GLOBAL".asName(), null, Meta.EMPTY) { public val Global: Context get() = GlobalContext -public fun Context(block: ContextBuilder.() -> Unit = {}): Context = Global.buildContext(block) \ No newline at end of file +public fun Context(name: String? = null, block: ContextBuilder.() -> Unit = {}): Context = + Global.buildContext(name, block) \ No newline at end of file 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 1a6c240f..68598714 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 @@ -51,7 +51,7 @@ public class WorkspaceBuilder(private val parentContext: Context = Global) : Tas * Define a context for the workspace */ public fun context(block: ContextBuilder.() -> Unit = {}) { - this.context = parentContext.buildContext(block) + this.context = parentContext.buildContext("workspace", block) } /** From 1a983665f82a3bad571e6b73091104fc5a6b3762 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Thu, 8 Apr 2021 13:50:43 +0300 Subject: [PATCH 07/11] Fix useProperty type --- .../space/kscience/dataforge/meta/ObservableItemProvider.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt index 5d455d17..c66ec858 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt @@ -26,10 +26,10 @@ public interface ItemPropertyProvider: ObservableItemProvider, MutableItemProvid * Optional [owner] property is used for */ @DFExperimental -public fun O.useProperty( - property: KProperty1, +public fun O.useProperty( + property: KProperty1, owner: Any? = null, - callBack: O.(T?) -> Unit, + callBack: O.(T) -> Unit, ) { //Pass initial value. callBack(property.get(this)) From 2352f1cff1c3d93da3880a4298c56adf273a9d6b Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 11 Apr 2021 11:15:25 +0300 Subject: [PATCH 08/11] Split ItemDescriptor to builder and read-only descriptor --- CHANGELOG.md | 1 + build.gradle.kts | 5 +- .../dataforge/properties/ConfigProperty.kt | 3 +- .../dataforge/properties/schemeProperty.kt | 3 +- .../space/kscience/dataforge/meta/Config.kt | 6 + .../dataforge/meta/ObservableItemProvider.kt | 3 +- .../meta/descriptors/ItemDescriptor.kt | 284 +++--------------- .../meta/descriptors/NodeDescriptor.kt | 191 ++++++++++++ .../meta/descriptors/ValueDescriptor.kt | 135 +++++++++ .../meta/descriptors/descriptorExtensions.kt | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 2 +- 12 files changed, 396 insertions(+), 241 deletions(-) create mode 100644 dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt create mode 100644 dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index c37535c3..13e065d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - LogManager plugin - dataforge-context API dependency on SLF4j - Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation. +- Split `ItemDescriptor` into builder and read-only part ### Changed - Kotlin-logging moved from common to JVM and JS. Replaced by console for native. diff --git a/build.gradle.kts b/build.gradle.kts index 98a941bb..9b8051e4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { allprojects { group = "space.kscience" - version = "0.4.0-dev-7" + version = "0.4.0-dev-8" } subprojects { @@ -22,5 +22,8 @@ ksciencePublish { } apiValidation { + if(project.version.toString().contains("dev")) { + validationDisabled = true + } nonPublicMarkers.add("space.kscience.dataforge.misc.DFExperimental") } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/ConfigProperty.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/ConfigProperty.kt index a079241e..c51f809e 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/ConfigProperty.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/ConfigProperty.kt @@ -8,6 +8,7 @@ import space.kscience.dataforge.meta.transformations.nullableItemToObject import space.kscience.dataforge.meta.transformations.nullableObjectToMetaItem import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.startsWith @DFExperimental public class ConfigProperty( @@ -24,7 +25,7 @@ public class ConfigProperty( override fun onChange(owner: Any?, callback: (T?) -> Unit) { config.onChange(owner) { name, oldItem, newItem -> - if (name == this.name && oldItem != newItem) callback(converter.nullableItemToObject(newItem)) + if (name.startsWith(this.name) && oldItem != newItem) callback(converter.nullableItemToObject(newItem)) } } diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt index a2f39eed..798154d5 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt @@ -2,6 +2,7 @@ package space.kscience.dataforge.properties import space.kscience.dataforge.meta.ItemPropertyProvider import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.names.toName import kotlin.reflect.KMutableProperty1 @@ -16,7 +17,7 @@ public fun

P.property(property: KMutableProp override fun onChange(owner: Any?, callback: (T?) -> Unit) { this@property.onChange(this) { name, oldItem, newItem -> - if (name == property.name.toName() && oldItem != newItem) { + if (name.startsWith(property.name.toName()) && oldItem != newItem) { callback(property.get(this@property)) } } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt index 20fb1cb2..14beb87b 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt @@ -98,6 +98,12 @@ public fun Meta.toConfig(): Config = Config().also { builder -> } } +/** + * Create a copy of this config, optionally applying the given [block]. + * The listeners of the original Config are not retained. + */ +public inline fun Config.copy(block: Config.() -> Unit = {}): Config = toConfig().apply(block) + /** * Return this [Meta] as [Config] if it is [Config] and create a new copy otherwise */ diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt index c66ec858..d5183fb9 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt @@ -2,6 +2,7 @@ package space.kscience.dataforge.meta import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.names.toName import kotlin.reflect.KProperty1 @@ -34,7 +35,7 @@ public fun O.useProperty( //Pass initial value. callBack(property.get(this)) onChange(owner) { name, oldItem, newItem -> - if (name == property.name.toName() && oldItem != newItem) { + if (name.startsWith(property.name.toName()) && oldItem != newItem) { callBack(property.get(this)) } } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt index d2decefe..a1a6a595 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt @@ -3,28 +3,26 @@ package space.kscience.dataforge.meta.descriptors import space.kscience.dataforge.meta.* import space.kscience.dataforge.misc.DFBuilder import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.* /** * A common parent for [ValueDescriptor] and [NodeDescriptor]. Describes a single [TypedMetaItem] or a group of same-name-siblings. */ -@DFBuilder -public sealed class ItemDescriptor(final override val config: Config) : Configurable { +public sealed interface ItemDescriptor: MetaRepr { /** * True if same name siblings with this name are allowed */ - public var multiple: Boolean by config.boolean(false) + public val multiple: Boolean /** * The item description text */ - public var info: String? by config.string() + public val info: String? /** * True if the item is required */ - public abstract var required: Boolean + public val required: Boolean /** @@ -32,14 +30,56 @@ public sealed class ItemDescriptor(final override val config: Config) : Configur * * @return */ - public var attributes: Config? by config.node() + public val attributes: Meta? /** * An index field by which this node is identified in case of same name siblings construct */ - public var indexKey: String by config.string(DEFAULT_INDEX_KEY) + public val indexKey: String - public abstract fun copy(): ItemDescriptor + public companion object { + public const val DEFAULT_INDEX_KEY: String = "@index" + } +} + + +/** + * The builder for [ItemDescriptor] + */ +@DFBuilder +public sealed class ItemDescriptorBuilder(final override val config: Config) : Configurable, ItemDescriptor { + + /** + * True if same name siblings with this name are allowed + */ + override var multiple: Boolean by config.boolean(false) + + /** + * The item description text + */ + override var info: String? by config.string() + + /** + * True if the item is required + */ + abstract override var required: Boolean + + + /** + * Additional attributes of an item. For example validation and widget parameters + * + * @return + */ + override var attributes: Config? by config.node() + + /** + * An index field by which this node is identified in case of same name siblings construct + */ + override var indexKey: String by config.string(DEFAULT_INDEX_KEY) + + public abstract fun build(): ItemDescriptor + + override fun toMeta(): Meta = config public companion object { public const val DEFAULT_INDEX_KEY: String = "@index" @@ -49,7 +89,7 @@ public sealed class ItemDescriptor(final override val config: Config) : Configur /** * Configure attributes of the descriptor, creating an attributes node if needed. */ -public inline fun ItemDescriptor.attributes(block: Config.() -> Unit) { +public inline fun ItemDescriptorBuilder.attributes(block: Config.() -> Unit) { (attributes ?: Config().also { this.attributes = it }).apply(block) } @@ -66,140 +106,6 @@ public fun ItemDescriptor.validateItem(item: MetaItem?): Boolean { } } -/** - * Descriptor for meta node. Could contain additional information for viewing - * and editing. - * - * @author Alexander Nozik - */ -@DFBuilder -public class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { - init { - config[IS_NODE_KEY] = true - } - - /** - * True if the node is required - * - * @return - */ - override var required: Boolean by config.boolean { default == null } - - /** - * The default for this node. Null if there is no default. - * - * @return - */ - public var default: Config? by config.node() - - /** - * The map of children item descriptors (both nodes and values) - */ - public val items: Map - get() = config.getIndexed(ITEM_KEY).entries.associate { (name, item) -> - if (name == null) error("Child item index should not be null") - val node = item.node ?: error("Node descriptor must be a node") - if (node[IS_NODE_KEY].boolean == true) { - name to NodeDescriptor(node as Config) - } else { - name to ValueDescriptor(node as Config) - } - } - - /** - * The map of children node descriptors - */ - @Suppress("UNCHECKED_CAST") - public val nodes: Map - get() = config.getIndexed(ITEM_KEY).entries.filter { - it.value.node[IS_NODE_KEY].boolean == true - }.associate { (name, item) -> - if (name == null) error("Child node index should not be null") - val node = item.node ?: error("Node descriptor must be a node") - name to NodeDescriptor(node as Config) - } - - /** - * The list of children value descriptors - */ - public val values: Map - get() = config.getIndexed(ITEM_KEY).entries.filter { - it.value.node[IS_NODE_KEY].boolean != true - }.associate { (name, item) -> - if (name == null) error("Child value index should not be null") - val node = item.node ?: error("Node descriptor must be a node") - name to ValueDescriptor(node as Config) - } - - private fun buildNode(name: Name): NodeDescriptor { - return when (name.length) { - 0 -> this - 1 -> { - val token = NameToken(ITEM_KEY.toString(), name.toString()) - val config: Config = config[token].node ?: Config().also { - it[IS_NODE_KEY] = true - config[token] = it - } - NodeDescriptor(config) - } - else -> buildNode(name.firstOrNull()?.asName()!!).buildNode(name.cutFirst()) - } - } - - /** - * Define a child item descriptor for this node - */ - private fun newItem(key: String, descriptor: ItemDescriptor) { - if (items.keys.contains(key)) error("The key $key already exists in descriptor") - val token = ITEM_KEY.withIndex(key) - config[token] = descriptor.config - } - - public fun item(name: Name, descriptor: ItemDescriptor) { - buildNode(name.cutLast()).newItem(name.lastOrNull().toString(), descriptor) - } - - public fun item(name: String, descriptor: ItemDescriptor) { - item(name.toName(), descriptor) - } - - /** - * Create and configure a child node descriptor - */ - public fun node(name: Name, block: NodeDescriptor.() -> Unit) { - item(name, NodeDescriptor().apply(block)) - } - - public fun node(name: String, block: NodeDescriptor.() -> Unit) { - node(name.toName(), block) - } - - /** - * Create and configure child value descriptor - */ - public fun value(name: Name, block: ValueDescriptor.() -> Unit) { - require(name.length >= 1) { "Name length for value descriptor must be non-empty" } - item(name, ValueDescriptor().apply(block)) - } - - public fun value(name: String, block: ValueDescriptor.() -> Unit) { - value(name.toName(), block) - } - - override fun copy(): NodeDescriptor = NodeDescriptor(config.toConfig()) - - public companion object { - - internal val ITEM_KEY: Name = "item".asName() - internal val IS_NODE_KEY: Name = "@isNode".asName() - - //TODO infer descriptor from spec - } -} - -public inline fun NodeDescriptor(block: NodeDescriptor.() -> Unit): NodeDescriptor = - NodeDescriptor().apply(block) - /** * Get a descriptor item associated with given name or null if item for given name not provided */ @@ -213,93 +119,3 @@ public operator fun ItemDescriptor.get(name: Name): ItemDescriptor? { public operator fun ItemDescriptor.get(name: String): ItemDescriptor? = get(name.toName()) -/** - * A descriptor for meta value - * - * Descriptor can have non-atomic path. It is resolved when descriptor is added to the node - * - * @author Alexander Nozik - */ -@DFBuilder -public class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { - - /** - * True if the value is required - * - * @return - */ - override var required: Boolean by config.boolean { default == null } - - /** - * The default for this value. Null if there is no default. - * - * @return - */ - public var default: Value? by config.value() - - public fun default(v: Any) { - this.default = Value.of(v) - } - - /** - * A list of allowed ValueTypes. Empty if any value type allowed - * - * @return - */ - public var type: List? by config.listValue { ValueType.valueOf(it.string) } - - public fun type(vararg t: ValueType) { - this.type = listOf(*t) - } - - /** - * Check if given value is allowed for here. The type should be allowed and - * if it is value should be within allowed values - * - * @param value - * @return - */ - public fun isAllowedValue(value: Value): Boolean { - return (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true) - && (allowedValues.isEmpty() || allowedValues.contains(value)) - } - - /** - * A list of allowed values with descriptions. If empty than any value is - * allowed. - * - * @return - */ - public var allowedValues: List by config.item().convert( - reader = { - val value = it.value - when { - value?.list != null -> value.list - type?.let { type -> type.size == 1 && type[0] === ValueType.BOOLEAN } ?: false -> listOf(True, False) - else -> emptyList() - } - }, - writer = { - MetaItemValue(it.asValue()) - } - ) - - /** - * Allow given list of value and forbid others - */ - public fun allow(vararg v: Any) { - this.allowedValues = v.map { Value.of(it) } - } - - override fun copy(): ValueDescriptor = ValueDescriptor(config.toConfig()) -} - -/** - * Merge two node descriptors into one using first one as primary - */ -public operator fun NodeDescriptor.plus(other: NodeDescriptor): NodeDescriptor { - return NodeDescriptor().apply { - config.update(other.config) - config.update(this@plus.config) - } -} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt new file mode 100644 index 00000000..e677ea32 --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt @@ -0,0 +1,191 @@ +package space.kscience.dataforge.meta.descriptors + +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.misc.DFBuilder +import space.kscience.dataforge.names.* + + +/** + * Descriptor for meta node. Could contain additional information for viewing + * and editing. + * + * @author Alexander Nozik + */ +@DFBuilder +public sealed interface NodeDescriptor: ItemDescriptor { + /** + * True if the node is required + * + * @return + */ + override val required: Boolean + + /** + * The default for this node. Null if there is no default. + * + * @return + */ + public val default: Config? + + /** + * The map of children item descriptors (both nodes and values) + */ + public val items: Map + + /** + * The map of children node descriptors + */ + public val nodes: Map + + /** + * The list of children value descriptors + */ + public val values: Map + + public companion object { + + internal val ITEM_KEY: Name = "item".asName() + internal val IS_NODE_KEY: Name = "@isNode".asName() + + //TODO infer descriptor from spec + } +} + + +@DFBuilder +public class NodeDescriptorBuilder(config: Config = Config()) : ItemDescriptorBuilder(config), NodeDescriptor { + init { + config[IS_NODE_KEY] = true + } + + /** + * True if the node is required + * + * @return + */ + override var required: Boolean by config.boolean { default == null } + + /** + * The default for this node. Null if there is no default. + * + * @return + */ + override var default: Config? by config.node() + + /** + * The map of children item descriptors (both nodes and values) + */ + override val items: Map + get() = config.getIndexed(ITEM_KEY).entries.associate { (name, item) -> + if (name == null) error("Child item index should not be null") + val node = item.node ?: error("Node descriptor must be a node") + if (node[IS_NODE_KEY].boolean == true) { + name to NodeDescriptorBuilder(node as Config) + } else { + name to ValueDescriptorBuilder(node as Config) + } + } + + /** + * The map of children node descriptors + */ + @Suppress("UNCHECKED_CAST") + override val nodes: Map + get() = config.getIndexed(ITEM_KEY).entries.filter { + it.value.node[IS_NODE_KEY].boolean == true + }.associate { (name, item) -> + if (name == null) error("Child node index should not be null") + val node = item.node ?: error("Node descriptor must be a node") + name to NodeDescriptorBuilder(node as Config) + } + + /** + * The list of children value descriptors + */ + override val values: Map + get() = config.getIndexed(ITEM_KEY).entries.filter { + it.value.node[IS_NODE_KEY].boolean != true + }.associate { (name, item) -> + if (name == null) error("Child value index should not be null") + val node = item.node ?: error("Node descriptor must be a node") + name to ValueDescriptorBuilder(node as Config) + } + + private fun buildNode(name: Name): NodeDescriptorBuilder { + return when (name.length) { + 0 -> this + 1 -> { + val token = NameToken(ITEM_KEY.toString(), name.toString()) + val config: Config = config[token].node ?: Config().also { + it[IS_NODE_KEY] = true + config[token] = it + } + NodeDescriptorBuilder(config) + } + else -> buildNode(name.firstOrNull()?.asName()!!).buildNode(name.cutFirst()) + } + } + + /** + * Define a child item descriptor for this node + */ + private fun newItem(key: String, descriptor: ItemDescriptor) { + if (items.keys.contains(key)) error("The key $key already exists in descriptor") + val token = ITEM_KEY.withIndex(key) + config[token] = descriptor.toMeta() + } + + public fun item(name: Name, descriptor: ItemDescriptor) { + buildNode(name.cutLast()).newItem(name.lastOrNull().toString(), descriptor) + } + + public fun item(name: String, descriptor: ItemDescriptor) { + item(name.toName(), descriptor) + } + + /** + * Create and configure a child node descriptor + */ + public fun node(name: Name, block: NodeDescriptorBuilder.() -> Unit) { + item(name, NodeDescriptorBuilder().apply(block)) + } + + public fun node(name: String, block: NodeDescriptorBuilder.() -> Unit) { + node(name.toName(), block) + } + + /** + * Create and configure child value descriptor + */ + public fun value(name: Name, block: ValueDescriptorBuilder.() -> Unit) { + require(name.length >= 1) { "Name length for value descriptor must be non-empty" } + item(name, ValueDescriptorBuilder().apply(block)) + } + + public fun value(name: String, block: ValueDescriptorBuilder.() -> Unit) { + value(name.toName(), block) + } + + override fun build(): NodeDescriptor = NodeDescriptorBuilder(config.copy()) + + public companion object { + + internal val ITEM_KEY: Name = "item".asName() + internal val IS_NODE_KEY: Name = "@isNode".asName() + + //TODO infer descriptor from spec + } +} + +public inline fun NodeDescriptor(block: NodeDescriptorBuilder.() -> Unit): NodeDescriptor = + NodeDescriptorBuilder().apply(block) + +/** + * Merge two node descriptors into one using first one as primary + */ +public operator fun NodeDescriptor.plus(other: NodeDescriptor): NodeDescriptor { + return NodeDescriptorBuilder().apply { + config.update(other.toMeta()) + config.update(this@plus.toMeta()) + } +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt new file mode 100644 index 00000000..6642346f --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt @@ -0,0 +1,135 @@ +package space.kscience.dataforge.meta.descriptors + +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.misc.DFBuilder +import space.kscience.dataforge.values.* + + + +/** + * A descriptor for meta value + * + * Descriptor can have non-atomic path. It is resolved when descriptor is added to the node + * + * @author Alexander Nozik + */ +@DFBuilder +public sealed interface ValueDescriptor: ItemDescriptor{ + + /** + * True if the value is required + * + * @return + */ + override val required: Boolean + + /** + * The default for this value. Null if there is no default. + * + * @return + */ + public val default: Value? + + + /** + * A list of allowed ValueTypes. Empty if any value type allowed + * + * @return + */ + public val type: List? + /** + * Check if given value is allowed for here. The type should be allowed and + * if it is value should be within allowed values + * + * @param value + * @return + */ + public fun isAllowedValue(value: Value): Boolean = + (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true) + && (allowedValues.isEmpty() || allowedValues.contains(value)) + + /** + * A list of allowed values with descriptions. If empty than any value is + * allowed. + * + * @return + */ + public val allowedValues: List +} + +/** + * A builder fir [ValueDescriptor] + */ +@DFBuilder +public class ValueDescriptorBuilder(config: Config = Config()) : ItemDescriptorBuilder(config), ValueDescriptor { + + /** + * True if the value is required + * + * @return + */ + override var required: Boolean by config.boolean { default == null } + + /** + * The default for this value. Null if there is no default. + * + * @return + */ + override var default: Value? by config.value() + + public fun default(v: Any) { + this.default = Value.of(v) + } + + /** + * A list of allowed ValueTypes. Empty if any value type allowed + * + * @return + */ + override var type: List? by config.listValue { ValueType.valueOf(it.string) } + + public fun type(vararg t: ValueType) { + this.type = listOf(*t) + } + + /** + * Check if given value is allowed for here. The type should be allowed and + * if it is value should be within allowed values + * + * @param value + * @return + */ + override fun isAllowedValue(value: Value): Boolean { + return (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true) + && (allowedValues.isEmpty() || allowedValues.contains(value)) + } + + /** + * A list of allowed values with descriptions. If empty than any value is + * allowed. + * + * @return + */ + override var allowedValues: List by config.item().convert( + reader = { + val value = it.value + when { + value?.list != null -> value.list + type?.let { type -> type.size == 1 && type[0] === ValueType.BOOLEAN } ?: false -> listOf(True, False) + else -> emptyList() + } + }, + writer = { + MetaItemValue(it.asValue()) + } + ) + + /** + * Allow given list of value and forbid others + */ + public fun allow(vararg v: Any) { + this.allowedValues = v.map { Value.of(it) } + } + + override fun build(): ValueDescriptor = ValueDescriptorBuilder(config.copy()) +} diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/descriptorExtensions.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/descriptorExtensions.kt index 24a09df9..8149843e 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/descriptorExtensions.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/descriptorExtensions.kt @@ -4,7 +4,7 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.values.ValueType import space.kscience.dataforge.values.asValue -public inline fun > NodeDescriptor.enum( +public inline fun > NodeDescriptorBuilder.enum( key: Name, default: E?, crossinline modifier: ValueDescriptor.() -> Unit = {}, diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 442d9132..f371643e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index 7bebb33f..6db60f3d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,7 +7,7 @@ pluginManagement { maven("https://dl.bintray.com/kotlin/kotlin-eap") } - val toolsVersion = "0.9.4" + val toolsVersion = "0.9.5-dev" val kotlinVersion = "1.5.0-M2" plugins { From a7ecbfb763a1f076e69194478e1cba517dd6317c Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 11 Apr 2021 11:24:25 +0300 Subject: [PATCH 09/11] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13e065d1..c7bf4dfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - Kotlinx-io fork dependency. Replaced by Ktor-io. ### Fixed +- Scheme properties properly handle children property change. ### Security From 5afe0523f14c0a7559217f95fcb50ab43d593723 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 27 Apr 2021 10:55:58 +0300 Subject: [PATCH 10/11] refactor to kotlin 1.5 --- CHANGELOG.md | 2 + build.gradle.kts | 2 +- dataforge-context/api/dataforge-context.api | 84 +++----- .../kscience/dataforge/context/Context.kt | 2 +- .../kscience/dataforge/context/LogManager.kt | 53 ++--- .../kscience/dataforge/context/loggingJs.kt | 5 +- .../kscience/dataforge/context/loggingJvm.kt | 4 +- .../dataforge/data/CoroutineMonitor.kt | 4 +- .../kscience/dataforge/io/BinaryMetaFormat.kt | 4 +- dataforge-meta/api/dataforge-meta.api | 185 +++++++++--------- settings.gradle.kts | 6 +- 11 files changed, 163 insertions(+), 188 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7bf4dfd..dfa1206e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ - Scheme made observable - Global context is a variable (the singleton is hidden and will be deprecated in future) - Kotlin 1.5 +- Added blank builders for children context. +- Refactor loggers ### Deprecated - Direct use of PluginManager diff --git a/build.gradle.kts b/build.gradle.kts index 9b8051e4..abe746a4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { allprojects { group = "space.kscience" - version = "0.4.0-dev-8" + version = "0.4.0" } subprojects { diff --git a/dataforge-context/api/dataforge-context.api b/dataforge-context/api/dataforge-context.api index 8dfdab6e..3cf0970c 100644 --- a/dataforge-context/api/dataforge-context.api +++ b/dataforge-context/api/dataforge-context.api @@ -3,17 +3,12 @@ public abstract class space/kscience/dataforge/context/AbstractPlugin : space/ks public fun (Lspace/kscience/dataforge/meta/Meta;)V public synthetic fun (Lspace/kscience/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun attach (Lspace/kscience/dataforge/context/Context;)V - public fun content (Ljava/lang/String;)Ljava/util/Map; public final fun dependsOn ()Ljava/util/Map; public fun detach ()V public fun getContext ()Lspace/kscience/dataforge/context/Context; - public fun getDefaultChainTarget ()Ljava/lang/String; - public fun getDefaultTarget ()Ljava/lang/String; public fun getMeta ()Lspace/kscience/dataforge/meta/Meta; - public fun getName ()Lspace/kscience/dataforge/names/Name; protected final fun require (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)Lkotlin/properties/ReadOnlyProperty; public static synthetic fun require$default (Lspace/kscience/dataforge/context/AbstractPlugin;Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; } public final class space/kscience/dataforge/context/AbstractPluginKt { @@ -44,7 +39,6 @@ public class space/kscience/dataforge/context/Context : kotlinx/coroutines/Corou public fun content (Ljava/lang/String;)Ljava/util/Map; public final fun content (Ljava/lang/String;Z)Ljava/util/Map; public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext; - public fun getDefaultChainTarget ()Ljava/lang/String; public fun getDefaultTarget ()Ljava/lang/String; public final fun getName ()Lspace/kscience/dataforge/names/Name; public final fun getParent ()Lspace/kscience/dataforge/context/Context; @@ -83,8 +77,9 @@ public final class space/kscience/dataforge/context/ContextBuilderKt { public final class space/kscience/dataforge/context/DefaultLogManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/dataforge/context/LogManager { public static final field Companion Lspace/kscience/dataforge/context/DefaultLogManager$Companion; public fun ()V + public fun getDefaultLogger ()Lspace/kscience/dataforge/context/Logger; public fun getTag ()Lspace/kscience/dataforge/context/PluginTag; - public fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V + public fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger; } public final class space/kscience/dataforge/context/DefaultLogManager$Companion : space/kscience/dataforge/context/PluginFactory { @@ -96,9 +91,6 @@ public final class space/kscience/dataforge/context/DefaultLogManager$Companion public abstract interface class space/kscience/dataforge/context/Factory { public abstract fun invoke (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;)Ljava/lang/Object; -} - -public final class space/kscience/dataforge/context/Factory$DefaultImpls { public static synthetic fun invoke$default (Lspace/kscience/dataforge/context/Factory;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;ILjava/lang/Object;)Ljava/lang/Object; } @@ -108,13 +100,17 @@ public final class space/kscience/dataforge/context/GlobalKt { public static final fun getGlobal ()Lspace/kscience/dataforge/context/Context; } -public abstract interface class space/kscience/dataforge/context/LogManager : space/kscience/dataforge/context/Logable, space/kscience/dataforge/context/Plugin { +public abstract interface class space/kscience/dataforge/context/LogManager : space/kscience/dataforge/context/Logger, space/kscience/dataforge/context/Plugin { public static final field Companion Lspace/kscience/dataforge/context/LogManager$Companion; public static final field DEBUG Ljava/lang/String; public static final field ERROR Ljava/lang/String; public static final field INFO Ljava/lang/String; public static final field TRACE Ljava/lang/String; public static final field WARNING Ljava/lang/String; + public abstract fun getDefaultLogger ()Lspace/kscience/dataforge/context/Logger; + public fun log (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V + public fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V + public abstract fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger; } public final class space/kscience/dataforge/context/LogManager$Companion { @@ -125,33 +121,19 @@ public final class space/kscience/dataforge/context/LogManager$Companion { public static final field WARNING Ljava/lang/String; } -public final class space/kscience/dataforge/context/LogManager$DefaultImpls { - public static fun content (Lspace/kscience/dataforge/context/LogManager;Ljava/lang/String;)Ljava/util/Map; - public static fun getDefaultChainTarget (Lspace/kscience/dataforge/context/LogManager;)Ljava/lang/String; - public static fun getDefaultTarget (Lspace/kscience/dataforge/context/LogManager;)Ljava/lang/String; - public static fun getName (Lspace/kscience/dataforge/context/LogManager;)Lspace/kscience/dataforge/names/Name; - public static fun toMeta (Lspace/kscience/dataforge/context/LogManager;)Lspace/kscience/dataforge/meta/Meta; -} - public final class space/kscience/dataforge/context/LogManagerKt { - public static final fun debug (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V - public static synthetic fun debug$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V - public static final fun error (Lspace/kscience/dataforge/context/Logable;Ljava/lang/Throwable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V - public static final fun error (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V - public static synthetic fun error$default (Lspace/kscience/dataforge/context/Logable;Ljava/lang/Throwable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V - public static synthetic fun error$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V - public static final fun getLogger (Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/Logable; - public static final fun getLogger (Lspace/kscience/dataforge/context/ContextAware;)Lspace/kscience/dataforge/context/Logable; - public static final fun info (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V - public static synthetic fun info$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V - public static final fun trace (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V - public static synthetic fun trace$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V - public static final fun warn (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V - public static synthetic fun warn$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V + public static final fun debug (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V + public static final fun error (Lspace/kscience/dataforge/context/Logger;Ljava/lang/Throwable;Lkotlin/jvm/functions/Function0;)V + public static final fun error (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V + public static final fun getLogger (Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/LogManager; + public static final fun getLogger (Lspace/kscience/dataforge/context/ContextAware;)Lspace/kscience/dataforge/context/Logger; + public static final fun info (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V + public static final fun trace (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V + public static final fun warn (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V } -public abstract interface class space/kscience/dataforge/context/Logable { - public abstract fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V +public abstract interface class space/kscience/dataforge/context/Logger { + public abstract fun log (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V } public abstract interface class space/kscience/dataforge/context/Plugin : space/kscience/dataforge/context/ContextAware, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/misc/Named, space/kscience/dataforge/provider/Provider { @@ -161,23 +143,15 @@ public abstract interface class space/kscience/dataforge/context/Plugin : space/ public abstract fun dependsOn ()Ljava/util/Map; public abstract fun detach ()V public abstract fun getMeta ()Lspace/kscience/dataforge/meta/Meta; - public abstract fun getName ()Lspace/kscience/dataforge/names/Name; + public fun getName ()Lspace/kscience/dataforge/names/Name; public abstract fun getTag ()Lspace/kscience/dataforge/context/PluginTag; - public abstract fun toMeta ()Lspace/kscience/dataforge/meta/Meta; + public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; } public final class space/kscience/dataforge/context/Plugin$Companion { public static final field TARGET Ljava/lang/String; } -public final class space/kscience/dataforge/context/Plugin$DefaultImpls { - public static fun content (Lspace/kscience/dataforge/context/Plugin;Ljava/lang/String;)Ljava/util/Map; - public static fun getDefaultChainTarget (Lspace/kscience/dataforge/context/Plugin;)Ljava/lang/String; - public static fun getDefaultTarget (Lspace/kscience/dataforge/context/Plugin;)Ljava/lang/String; - public static fun getName (Lspace/kscience/dataforge/context/Plugin;)Lspace/kscience/dataforge/names/Name; - public static fun toMeta (Lspace/kscience/dataforge/context/Plugin;)Lspace/kscience/dataforge/meta/Meta; -} - public abstract interface class space/kscience/dataforge/context/PluginFactory : space/kscience/dataforge/context/Factory { public static final field Companion Lspace/kscience/dataforge/context/PluginFactory$Companion; public static final field TYPE Ljava/lang/String; @@ -242,8 +216,9 @@ public final class space/kscience/dataforge/context/ResolveKt { public final class space/kscience/dataforge/context/SlfLogManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/dataforge/context/LogManager { public static final field Companion Lspace/kscience/dataforge/context/SlfLogManager$Companion; public fun ()V + public fun getDefaultLogger ()Lspace/kscience/dataforge/context/Logger; public fun getTag ()Lspace/kscience/dataforge/context/PluginTag; - public fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V + public fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger; } public final class space/kscience/dataforge/context/SlfLogManager$Companion : space/kscience/dataforge/context/PluginFactory { @@ -275,11 +250,6 @@ public abstract interface annotation class space/kscience/dataforge/descriptors/ public abstract fun type ()[Lspace/kscience/dataforge/values/ValueType; } -public final class space/kscience/dataforge/properties/Property$DefaultImpls { - public static synthetic fun onChange$default (Lspace/kscience/dataforge/properties/Property;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V - public static synthetic fun removeChangeListener$default (Lspace/kscience/dataforge/properties/Property;Ljava/lang/Object;ILjava/lang/Object;)V -} - public final class space/kscience/dataforge/properties/PropertyKt { } @@ -345,15 +315,9 @@ public final class space/kscience/dataforge/provider/PathToken$Companion { } public abstract interface class space/kscience/dataforge/provider/Provider { - public abstract fun content (Ljava/lang/String;)Ljava/util/Map; - public abstract fun getDefaultChainTarget ()Ljava/lang/String; - public abstract fun getDefaultTarget ()Ljava/lang/String; -} - -public final class space/kscience/dataforge/provider/Provider$DefaultImpls { - public static fun content (Lspace/kscience/dataforge/provider/Provider;Ljava/lang/String;)Ljava/util/Map; - public static fun getDefaultChainTarget (Lspace/kscience/dataforge/provider/Provider;)Ljava/lang/String; - public static fun getDefaultTarget (Lspace/kscience/dataforge/provider/Provider;)Ljava/lang/String; + public fun content (Ljava/lang/String;)Ljava/util/Map; + public fun getDefaultChainTarget ()Ljava/lang/String; + public fun getDefaultTarget ()Ljava/lang/String; } public final class space/kscience/dataforge/provider/ProviderKt { diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt index 74bb062f..2451048d 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/Context.kt @@ -76,7 +76,7 @@ public open class Context internal constructor( * Build and register a child context */ @Synchronized - public fun buildContext(name: String? = null, block: ContextBuilder.() -> Unit): Context { + public fun buildContext(name: String? = null, block: ContextBuilder.() -> Unit = {}): Context { val newContext = ContextBuilder(this) .apply { name?.let { name(it) } } .apply(block) diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/LogManager.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/LogManager.kt index 10f9c7af..d3efed6f 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/LogManager.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/LogManager.kt @@ -6,11 +6,19 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus import kotlin.reflect.KClass -public fun interface Logable { - public fun log(name: Name, tag: String, body: () -> String) +public fun interface Logger { + public fun log(tag: String, body: () -> String) } -public interface LogManager : Plugin, Logable { +public interface LogManager : Plugin, Logger { + public fun logger(name: Name): Logger + + public val defaultLogger: Logger + + override fun log(tag: String, body: () -> String): Unit = defaultLogger.log(tag, body) + + public fun log(name: Name, tag: String, body: () -> String): Unit = logger(name).log(tag, body) + public companion object { public const val TRACE: String = "TRACE" public const val INFO: String = "INFO" @@ -20,11 +28,11 @@ public interface LogManager : Plugin, Logable { } } -public fun Logable.trace(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.TRACE, body) -public fun Logable.info(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.INFO, body) -public fun Logable.debug(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.DEBUG, body) -public fun Logable.warn(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.WARNING, body) -public fun Logable.error(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.ERROR, body) +public fun Logger.trace(body: () -> String): Unit = log(LogManager.TRACE, body) +public fun Logger.info(body: () -> String): Unit = log(LogManager.INFO, body) +public fun Logger.debug(body: () -> String): Unit = log(LogManager.DEBUG, body) +public fun Logger.warn(body: () -> String): Unit = log(LogManager.WARNING, body) +public fun Logger.error(body: () -> String): Unit = log(LogManager.ERROR, body) internal val (() -> String).safe: String get() = try { @@ -34,22 +42,24 @@ internal val (() -> String).safe: String } -public fun Logable.error(throwable: Throwable?, name: Name = Name.EMPTY, body: () -> String): Unit = - log(name, LogManager.ERROR) { - buildString { - appendLine(body()) - throwable?.let { appendLine(throwable.stackTraceToString()) } - } +public fun Logger.error(throwable: Throwable?, body: () -> String): Unit = log(LogManager.ERROR) { + buildString { + appendLine(body()) + throwable?.let { appendLine(throwable.stackTraceToString()) } } +} public class DefaultLogManager : AbstractPlugin(), LogManager { - override fun log(name: Name, tag: String, body: () -> String) { + override fun logger(name: Name): Logger = Logger { tag, body -> val message: String = body.safe - println("[${context.name}] $name: $message") + println("$tag $name: [${context.name}] $message") } + override val defaultLogger: Logger = logger(Name.EMPTY) + + override val tag: PluginTag get() = Companion.tag public companion object : PluginFactory { @@ -63,20 +73,17 @@ public class DefaultLogManager : AbstractPlugin(), LogManager { /** * Context log manager inherited from parent */ -public val Context.logger: Logable +public val Context.logger: LogManager get() = plugins.find(inherit = true) { it is LogManager } as? LogManager ?: globalLoggerFactory(context = Global).apply { attach(Global) } /** * The named proxy logger for a context member */ -public val ContextAware.logger: Logable +public val ContextAware.logger: Logger get() = if (this is Named) { - object : Logable { - val contextLog = context.logger - override fun log(name: Name, tag: String, body: () -> String) { - contextLog.log(this@logger.name + name, tag, body) - } + Logger { tag, body -> + context.logger.log(this@logger.name + name, tag, body) } } else { context.logger diff --git a/dataforge-context/src/jsMain/kotlin/space/kscience/dataforge/context/loggingJs.kt b/dataforge-context/src/jsMain/kotlin/space/kscience/dataforge/context/loggingJs.kt index 3c822b82..406929ca 100644 --- a/dataforge-context/src/jsMain/kotlin/space/kscience/dataforge/context/loggingJs.kt +++ b/dataforge-context/src/jsMain/kotlin/space/kscience/dataforge/context/loggingJs.kt @@ -6,7 +6,7 @@ import kotlin.reflect.KClass public class ConsoleLogManager : AbstractPlugin(), LogManager { - override fun log(name: Name, tag: String, body: () -> String) { + override fun logger(name: Name): Logger = Logger { tag, body -> val message: String = body.safe when (tag) { LogManager.INFO -> console.info("[${context.name}] $name: $message") @@ -16,6 +16,9 @@ public class ConsoleLogManager : AbstractPlugin(), LogManager { } } + override val defaultLogger: Logger = logger(Name.EMPTY) + + override val tag: PluginTag get() = Companion.tag public companion object : PluginFactory { diff --git a/dataforge-context/src/jvmMain/kotlin/space/kscience/dataforge/context/loggingJvm.kt b/dataforge-context/src/jvmMain/kotlin/space/kscience/dataforge/context/loggingJvm.kt index 9fa9226c..05763e00 100644 --- a/dataforge-context/src/jvmMain/kotlin/space/kscience/dataforge/context/loggingJvm.kt +++ b/dataforge-context/src/jvmMain/kotlin/space/kscience/dataforge/context/loggingJvm.kt @@ -7,7 +7,7 @@ import kotlin.reflect.KClass public class SlfLogManager : AbstractPlugin(), LogManager { - override fun log(name: Name, tag: String, body: () -> String) { + override fun logger(name: Name): Logger = Logger { tag, body -> val logger = LoggerFactory.getLogger("[${context.name}] $name") //KotlinLogging.logger("[${context.name}] $name") val message = body.safe when (tag) { @@ -19,6 +19,8 @@ public class SlfLogManager : AbstractPlugin(), LogManager { } } + override val defaultLogger: Logger = logger(Name.EMPTY) + override val tag: PluginTag get() = Companion.tag public companion object : PluginFactory { diff --git a/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/CoroutineMonitor.kt b/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/CoroutineMonitor.kt index c8c1a78f..4607d92c 100644 --- a/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/CoroutineMonitor.kt +++ b/dataforge-data/src/commonMain/kotlin/space/kscience/dataforge/data/CoroutineMonitor.kt @@ -48,9 +48,9 @@ public val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.mo public val Job.dependencies: Collection get() = this[Dependencies]?.values ?: emptyList() @DFExperimental -public val Job.totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0) +public val Job.totalWork: Double get() = dependencies.sumOf { totalWork } + (monitor?.totalWork ?: 0.0) @DFExperimental -public val Job.workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0) +public val Job.workDone: Double get() = dependencies.sumOf { workDone } + (monitor?.workDone ?: 0.0) @DFExperimental public val Job.status: String get() = monitor?.status ?: "" @DFExperimental diff --git a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/BinaryMetaFormat.kt b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/BinaryMetaFormat.kt index 96ac4522..38ca6ec2 100644 --- a/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/BinaryMetaFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/BinaryMetaFormat.kt @@ -20,7 +20,7 @@ public object BinaryMetaFormat : MetaFormat, MetaFormatFactory { return (input.readMetaItem() as MetaItemNode).node } - private fun Output.writeChar(char: Char) = writeByte(char.toByte()) + private fun Output.writeChar(char: Char) = writeByte(char.code.toByte()) private fun Output.writeString(str: String) { writeInt(str.length) @@ -101,7 +101,7 @@ public object BinaryMetaFormat : MetaFormat, MetaFormatFactory { @Suppress("UNCHECKED_CAST") public fun Input.readMetaItem(): TypedMetaItem { - return when (val keyChar = readByte().toChar()) { + return when (val keyChar = readByte().toInt().toChar()) { 'S' -> MetaItemValue(StringValue(readString())) 'N' -> MetaItemValue(Null) '+' -> MetaItemValue(True) diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index 47b38de5..e3572ca2 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -9,7 +9,6 @@ public abstract class space/kscience/dataforge/meta/AbstractMutableMeta : space/ public abstract class space/kscience/dataforge/meta/AbstractTypedMeta : space/kscience/dataforge/meta/MetaBase, space/kscience/dataforge/meta/TypedMeta { public fun ()V - public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; } public final class space/kscience/dataforge/meta/Config : space/kscience/dataforge/meta/AbstractMutableMeta, space/kscience/dataforge/meta/ItemPropertyProvider { @@ -33,6 +32,8 @@ public final class space/kscience/dataforge/meta/Config$ConfigSerializer : kotli public final class space/kscience/dataforge/meta/ConfigKt { public static final fun asConfig (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Config; + public static final fun copy (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/Config; + public static synthetic fun copy$default (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Config; public static final fun get (Lspace/kscience/dataforge/meta/Config;Lspace/kscience/dataforge/names/NameToken;)Lspace/kscience/dataforge/meta/TypedMetaItem; public static final fun toConfig (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Config; } @@ -172,10 +173,10 @@ public abstract interface class space/kscience/dataforge/meta/Meta : space/kscie public static final field TYPE Ljava/lang/String; public static final field VALUE_KEY Ljava/lang/String; public abstract fun equals (Ljava/lang/Object;)Z - public abstract fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; + public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; public abstract fun getItems ()Ljava/util/Map; public abstract fun hashCode ()I - public abstract fun toMeta ()Lspace/kscience/dataforge/meta/Meta; + public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; public abstract fun toString ()Ljava/lang/String; } @@ -186,17 +187,10 @@ public final class space/kscience/dataforge/meta/Meta$Companion { public final fun getEMPTY ()Lspace/kscience/dataforge/meta/Meta; } -public final class space/kscience/dataforge/meta/Meta$DefaultImpls { - public static fun getItem (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; - public static fun toMeta (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Meta; -} - public abstract class space/kscience/dataforge/meta/MetaBase : space/kscience/dataforge/meta/Meta { public fun ()V public fun equals (Ljava/lang/Object;)Z - public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; public fun hashCode ()I - public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; public fun toString ()Ljava/lang/String; } @@ -398,11 +392,6 @@ public abstract interface class space/kscience/dataforge/meta/MutableMeta : spac public abstract fun getItems ()Ljava/util/Map; } -public final class space/kscience/dataforge/meta/MutableMeta$DefaultImpls { - public static fun getItem (Lspace/kscience/dataforge/meta/MutableMeta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; - public static fun toMeta (Lspace/kscience/dataforge/meta/MutableMeta;)Lspace/kscience/dataforge/meta/Meta; -} - public final class space/kscience/dataforge/meta/MutableMetaKt { public static final fun append (Lspace/kscience/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/Object;)V public static final fun append (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/names/Name;Ljava/lang/Object;)V @@ -419,14 +408,10 @@ public final class space/kscience/dataforge/meta/ObservableItemProviderKt { public abstract interface class space/kscience/dataforge/meta/ReadOnlySpecification { public abstract fun empty ()Lspace/kscience/dataforge/meta/ItemProvider; - public abstract fun invoke (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider; + public fun invoke (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider; public abstract fun read (Lspace/kscience/dataforge/meta/ItemProvider;)Lspace/kscience/dataforge/meta/ItemProvider; } -public final class space/kscience/dataforge/meta/ReadOnlySpecification$DefaultImpls { - public static fun invoke (Lspace/kscience/dataforge/meta/ReadOnlySpecification;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider; -} - public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/ItemPropertyProvider, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/descriptors/Described { public fun ()V public fun getDefaultLayer ()Lspace/kscience/dataforge/meta/Meta; @@ -475,10 +460,6 @@ public final class space/kscience/dataforge/meta/SealedMetaKt { public abstract interface class space/kscience/dataforge/meta/Specification : space/kscience/dataforge/meta/ReadOnlySpecification { public abstract fun write (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;)Lspace/kscience/dataforge/meta/MutableItemProvider; -} - -public final class space/kscience/dataforge/meta/Specification$DefaultImpls { - public static fun invoke (Lspace/kscience/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/MutableItemProvider; public static synthetic fun write$default (Lspace/kscience/dataforge/meta/Specification;Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/MutableItemProvider; } @@ -491,15 +472,10 @@ public final class space/kscience/dataforge/meta/SpecificationKt { } public abstract interface class space/kscience/dataforge/meta/TypedMeta : space/kscience/dataforge/meta/Meta { - public abstract fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; + public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; public abstract fun getItems ()Ljava/util/Map; } -public final class space/kscience/dataforge/meta/TypedMeta$DefaultImpls { - public static fun getItem (Lspace/kscience/dataforge/meta/TypedMeta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; - public static fun toMeta (Lspace/kscience/dataforge/meta/TypedMeta;)Lspace/kscience/dataforge/meta/Meta; -} - public abstract class space/kscience/dataforge/meta/TypedMetaItem { public static final field Companion Lspace/kscience/dataforge/meta/TypedMetaItem$Companion; public abstract fun equals (Ljava/lang/Object;)Z @@ -530,78 +506,117 @@ public final class space/kscience/dataforge/meta/descriptors/DescriptorMetaKt { public static final fun defaultMeta (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)Lspace/kscience/dataforge/meta/Laminate; } -public abstract class space/kscience/dataforge/meta/descriptors/ItemDescriptor : space/kscience/dataforge/meta/Configurable { +public abstract interface class space/kscience/dataforge/meta/descriptors/ItemDescriptor : space/kscience/dataforge/meta/MetaRepr { public static final field Companion Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor$Companion; public static final field DEFAULT_INDEX_KEY Ljava/lang/String; - public synthetic fun (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public abstract fun copy ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; - public final fun getAttributes ()Lspace/kscience/dataforge/meta/Config; - public final fun getConfig ()Lspace/kscience/dataforge/meta/Config; - public final fun getIndexKey ()Ljava/lang/String; - public final fun getInfo ()Ljava/lang/String; - public final fun getMultiple ()Z + public abstract fun getAttributes ()Lspace/kscience/dataforge/meta/Meta; + public abstract fun getIndexKey ()Ljava/lang/String; + public abstract fun getInfo ()Ljava/lang/String; + public abstract fun getMultiple ()Z public abstract fun getRequired ()Z - public final fun setAttributes (Lspace/kscience/dataforge/meta/Config;)V - public final fun setIndexKey (Ljava/lang/String;)V - public final fun setInfo (Ljava/lang/String;)V - public final fun setMultiple (Z)V - public abstract fun setRequired (Z)V } public final class space/kscience/dataforge/meta/descriptors/ItemDescriptor$Companion { + public static final field DEFAULT_INDEX_KEY Ljava/lang/String; +} + +public abstract class space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder : space/kscience/dataforge/meta/Configurable, space/kscience/dataforge/meta/descriptors/ItemDescriptor { + public static final field Companion Lspace/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder$Companion; + public static final field DEFAULT_INDEX_KEY Ljava/lang/String; + public synthetic fun (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public abstract fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; + public fun getAttributes ()Lspace/kscience/dataforge/meta/Config; + public synthetic fun getAttributes ()Lspace/kscience/dataforge/meta/Meta; + public final fun getConfig ()Lspace/kscience/dataforge/meta/Config; + public fun getIndexKey ()Ljava/lang/String; + public fun getInfo ()Ljava/lang/String; + public fun getMultiple ()Z + public abstract fun getRequired ()Z + public fun setAttributes (Lspace/kscience/dataforge/meta/Config;)V + public fun setIndexKey (Ljava/lang/String;)V + public fun setInfo (Ljava/lang/String;)V + public fun setMultiple (Z)V + public abstract fun setRequired (Z)V + public fun toMeta ()Lspace/kscience/dataforge/meta/Meta; +} + +public final class space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder$Companion { } public final class space/kscience/dataforge/meta/descriptors/ItemDescriptorKt { - public static final fun NodeDescriptor (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; - public static final fun attributes (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;Lkotlin/jvm/functions/Function1;)V + public static final fun attributes (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder;Lkotlin/jvm/functions/Function1;)V public static final fun get (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;Ljava/lang/String;)Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; public static final fun get (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; - public static final fun plus (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; public static final fun validateItem (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;Lspace/kscience/dataforge/meta/TypedMetaItem;)Z } -public final class space/kscience/dataforge/meta/descriptors/NodeDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor { +public abstract interface class space/kscience/dataforge/meta/descriptors/NodeDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor { public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor$Companion; - public fun ()V - public fun (Lspace/kscience/dataforge/meta/Config;)V - public synthetic fun (Lspace/kscience/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun copy ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; - public fun copy ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; - public final fun getDefault ()Lspace/kscience/dataforge/meta/Config; - public final fun getItems ()Ljava/util/Map; - public final fun getNodes ()Ljava/util/Map; - public fun getRequired ()Z - public final fun getValues ()Ljava/util/Map; - public final fun item (Ljava/lang/String;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V - public final fun item (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V - public final fun node (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V - public final fun node (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V - public final fun setDefault (Lspace/kscience/dataforge/meta/Config;)V - public fun setRequired (Z)V - public final fun value (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V - public final fun value (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V + public abstract fun getDefault ()Lspace/kscience/dataforge/meta/Config; + public abstract fun getItems ()Ljava/util/Map; + public abstract fun getNodes ()Ljava/util/Map; + public abstract fun getRequired ()Z + public abstract fun getValues ()Ljava/util/Map; } public final class space/kscience/dataforge/meta/descriptors/NodeDescriptor$Companion { } -public final class space/kscience/dataforge/meta/descriptors/ValueDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor { +public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder : space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder, space/kscience/dataforge/meta/descriptors/NodeDescriptor { + public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder$Companion; + public fun ()V + public fun (Lspace/kscience/dataforge/meta/Config;)V + public synthetic fun (Lspace/kscience/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; + public fun build ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; + public fun getDefault ()Lspace/kscience/dataforge/meta/Config; + public fun getItems ()Ljava/util/Map; + public fun getNodes ()Ljava/util/Map; + public fun getRequired ()Z + public fun getValues ()Ljava/util/Map; + public final fun item (Ljava/lang/String;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V + public final fun item (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V + public final fun node (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public final fun node (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V + public fun setDefault (Lspace/kscience/dataforge/meta/Config;)V + public fun setRequired (Z)V + public final fun value (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public final fun value (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V +} + +public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder$Companion { +} + +public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorKt { + public static final fun NodeDescriptor (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; + public static final fun plus (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; +} + +public abstract interface class space/kscience/dataforge/meta/descriptors/ValueDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor { + public abstract fun getAllowedValues ()Ljava/util/List; + public abstract fun getDefault ()Lspace/kscience/dataforge/values/Value; + public abstract fun getRequired ()Z + public abstract fun getType ()Ljava/util/List; + public fun isAllowedValue (Lspace/kscience/dataforge/values/Value;)Z +} + +public final class space/kscience/dataforge/meta/descriptors/ValueDescriptorBuilder : space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder, space/kscience/dataforge/meta/descriptors/ValueDescriptor { public fun ()V public fun (Lspace/kscience/dataforge/meta/Config;)V public synthetic fun (Lspace/kscience/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun allow ([Ljava/lang/Object;)V - public synthetic fun copy ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; - public fun copy ()Lspace/kscience/dataforge/meta/descriptors/ValueDescriptor; + public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; + public fun build ()Lspace/kscience/dataforge/meta/descriptors/ValueDescriptor; public final fun default (Ljava/lang/Object;)V - public final fun getAllowedValues ()Ljava/util/List; - public final fun getDefault ()Lspace/kscience/dataforge/values/Value; + public fun getAllowedValues ()Ljava/util/List; + public fun getDefault ()Lspace/kscience/dataforge/values/Value; public fun getRequired ()Z - public final fun getType ()Ljava/util/List; - public final fun isAllowedValue (Lspace/kscience/dataforge/values/Value;)Z - public final fun setAllowedValues (Ljava/util/List;)V - public final fun setDefault (Lspace/kscience/dataforge/values/Value;)V + public fun getType ()Ljava/util/List; + public fun isAllowedValue (Lspace/kscience/dataforge/values/Value;)Z + public fun setAllowedValues (Ljava/util/List;)V + public fun setDefault (Lspace/kscience/dataforge/values/Value;)V public fun setRequired (Z)V - public final fun setType (Ljava/util/List;)V + public fun setType (Ljava/util/List;)V public final fun type ([Lspace/kscience/dataforge/values/ValueType;)V } @@ -689,7 +704,6 @@ public final class space/kscience/dataforge/meta/transformations/RegexItemTransf public final fun getTransform ()Lkotlin/jvm/functions/Function4; public fun hashCode ()I public fun matches (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;)Z - public fun selectItems (Lspace/kscience/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; public fun toString ()Ljava/lang/String; public fun transformItem (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;Lspace/kscience/dataforge/meta/MutableMeta;)V } @@ -712,14 +726,10 @@ public final class space/kscience/dataforge/meta/transformations/SingleItemTrans public abstract interface class space/kscience/dataforge/meta/transformations/TransformationRule { public abstract fun matches (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;)Z - public abstract fun selectItems (Lspace/kscience/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; + public fun selectItems (Lspace/kscience/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; public abstract fun transformItem (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;Lspace/kscience/dataforge/meta/MutableMeta;)V } -public final class space/kscience/dataforge/meta/transformations/TransformationRule$DefaultImpls { - public static fun selectItems (Lspace/kscience/dataforge/meta/transformations/TransformationRule;Lspace/kscience/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; -} - public abstract interface annotation class space/kscience/dataforge/misc/DFBuilder : java/lang/annotation/Annotation { } @@ -852,7 +862,6 @@ public final class space/kscience/dataforge/values/DoubleArrayValue : java/lang/ public final class space/kscience/dataforge/values/EnumValue : space/kscience/dataforge/values/Value { public fun (Ljava/lang/Enum;)V public fun equals (Ljava/lang/Object;)Z - public fun getList ()Ljava/util/List; public fun getType ()Lspace/kscience/dataforge/values/ValueType; public fun getValue ()Ljava/lang/Enum; public synthetic fun getValue ()Ljava/lang/Object; @@ -868,7 +877,6 @@ public final class space/kscience/dataforge/values/ExoticValuesKt { public final class space/kscience/dataforge/values/False : space/kscience/dataforge/values/Value { public static final field INSTANCE Lspace/kscience/dataforge/values/False; public fun equals (Ljava/lang/Object;)Z - public fun getList ()Ljava/util/List; public fun getType ()Lspace/kscience/dataforge/values/ValueType; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -878,7 +886,6 @@ public final class space/kscience/dataforge/values/False : space/kscience/datafo public final class space/kscience/dataforge/values/LazyParsedValue : space/kscience/dataforge/values/Value { public fun (Ljava/lang/String;)V public fun equals (Ljava/lang/Object;)Z - public fun getList ()Ljava/util/List; public final fun getString ()Ljava/lang/String; public fun getType ()Lspace/kscience/dataforge/values/ValueType; public fun getValue ()Ljava/lang/Object; @@ -906,7 +913,6 @@ public final class space/kscience/dataforge/values/ListValue$Companion { public final class space/kscience/dataforge/values/Null : space/kscience/dataforge/values/Value { public static final field INSTANCE Lspace/kscience/dataforge/values/Null; public fun equals (Ljava/lang/Object;)Z - public fun getList ()Ljava/util/List; public fun getType ()Lspace/kscience/dataforge/values/ValueType; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -916,7 +922,6 @@ public final class space/kscience/dataforge/values/Null : space/kscience/datafor public final class space/kscience/dataforge/values/NumberValue : space/kscience/dataforge/values/Value { public fun (Ljava/lang/Number;)V public fun equals (Ljava/lang/Object;)Z - public fun getList ()Ljava/util/List; public final fun getNumber ()Ljava/lang/Number; public fun getType ()Lspace/kscience/dataforge/values/ValueType; public fun getValue ()Ljava/lang/Object; @@ -927,7 +932,6 @@ public final class space/kscience/dataforge/values/NumberValue : space/kscience/ public final class space/kscience/dataforge/values/StringValue : space/kscience/dataforge/values/Value { public fun (Ljava/lang/String;)V public fun equals (Ljava/lang/Object;)Z - public fun getList ()Ljava/util/List; public final fun getString ()Ljava/lang/String; public fun getType ()Lspace/kscience/dataforge/values/ValueType; public fun getValue ()Ljava/lang/Object; @@ -938,7 +942,6 @@ public final class space/kscience/dataforge/values/StringValue : space/kscience/ public final class space/kscience/dataforge/values/True : space/kscience/dataforge/values/Value { public static final field INSTANCE Lspace/kscience/dataforge/values/True; public fun equals (Ljava/lang/Object;)Z - public fun getList ()Ljava/util/List; public fun getType ()Lspace/kscience/dataforge/values/ValueType; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -949,7 +952,7 @@ public abstract interface class space/kscience/dataforge/values/Value { public static final field Companion Lspace/kscience/dataforge/values/Value$Companion; public static final field TYPE Ljava/lang/String; public abstract fun equals (Ljava/lang/Object;)Z - public abstract fun getList ()Ljava/util/List; + public fun getList ()Ljava/util/List; public abstract fun getType ()Lspace/kscience/dataforge/values/ValueType; public abstract fun getValue ()Ljava/lang/Object; public abstract fun hashCode ()I @@ -961,10 +964,6 @@ public final class space/kscience/dataforge/values/Value$Companion { public final fun of (Ljava/lang/Object;)Lspace/kscience/dataforge/values/Value; } -public final class space/kscience/dataforge/values/Value$DefaultImpls { - public static fun getList (Lspace/kscience/dataforge/values/Value;)Ljava/util/List; -} - public final class space/kscience/dataforge/values/ValueExtensionsKt { public static final fun getBoolean (Lspace/kscience/dataforge/values/Value;)Z public static final fun getDouble (Lspace/kscience/dataforge/values/Value;)D diff --git a/settings.gradle.kts b/settings.gradle.kts index 6db60f3d..a5bf754f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,13 +2,11 @@ pluginManagement { repositories { maven("https://repo.kotlin.link") mavenCentral() - jcenter() gradlePluginPortal() - maven("https://dl.bintray.com/kotlin/kotlin-eap") } - val toolsVersion = "0.9.5-dev" - val kotlinVersion = "1.5.0-M2" + val toolsVersion = "0.9.5" + val kotlinVersion = "1.5.0" plugins { id("ru.mipt.npm.gradle.project") version toolsVersion From 3e8421187f9eedf29136f28a1851338f46ca4ccb Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 27 Apr 2021 11:17:27 +0300 Subject: [PATCH 11/11] patach CHANGELOG.md --- CHANGELOG.md | 12 ++++++++++++ build.gradle.kts | 4 ++++ .../kscience/dataforge/context/ContextBuilder.kt | 1 + 3 files changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfa1206e..8b4b4990 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ ## [Unreleased] ### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Security +## [0.4.0] +### Added - LogManager plugin - dataforge-context API dependency on SLF4j - Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation. diff --git a/build.gradle.kts b/build.gradle.kts index abe746a4..53e618df 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,6 +15,10 @@ readme { readmeTemplate = file("docs/templates/README-TEMPLATE.md") } +changelog{ + version = project.version.toString() +} + ksciencePublish { github("dataforge-core") space("https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven") diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt index eceb0e3d..c302cb6b 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/context/ContextBuilder.kt @@ -66,6 +66,7 @@ public class ContextBuilder internal constructor( val contextName = name ?: "@auto[${hashCode().toUInt().toString(16)}]".toName() return Context(contextName, parent, meta.seal()).apply { factories.forEach { (factory, meta) -> + @Suppress("DEPRECATION") plugins.load(factory, meta) } }