Refactor context factories
This commit is contained in:
parent
027d5ed923
commit
030f3ed6fe
@ -17,6 +17,7 @@
|
||||
- \[Major breaking change\] Schemes and configurables us `MutableItemProvider` instead of `Config`
|
||||
- \[Major breaking change\] `MetaItem` renamed to `TypedMetaItem` and `MetaItem` is now an alias for `TypedMetaItem<*>`
|
||||
- \[Major breaking change\] Moved `NodeItem` and `ValueItem` to a top level
|
||||
- Plugins are removed from Context constructor and added lazily in ContextBuilder
|
||||
|
||||
### Deprecated
|
||||
|
||||
|
@ -38,8 +38,7 @@ public final class hep/dataforge/context/ClassLoaderPluginKt {
|
||||
public class hep/dataforge/context/Context : hep/dataforge/context/Named, hep/dataforge/meta/MetaRepr, hep/dataforge/provider/Provider, kotlinx/coroutines/CoroutineScope {
|
||||
public static final field Companion Lhep/dataforge/context/Context$Companion;
|
||||
public static final field PROPERTY_TARGET Ljava/lang/String;
|
||||
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/context/Context;Lhep/dataforge/meta/Meta;Ljava/util/Set;)V
|
||||
public synthetic fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/context/Context;Lhep/dataforge/meta/Meta;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/context/Context;Lhep/dataforge/meta/Meta;)V
|
||||
public fun close ()V
|
||||
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
||||
public final fun content (Ljava/lang/String;Z)Ljava/util/Map;
|
||||
@ -65,7 +64,6 @@ public final class hep/dataforge/context/ContextBuilder {
|
||||
public synthetic fun <init> (Lhep/dataforge/context/Context;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun build ()Lhep/dataforge/context/Context;
|
||||
public final fun getName ()Ljava/lang/String;
|
||||
public final fun plugin (Lhep/dataforge/context/Plugin;)V
|
||||
public final fun plugin (Lhep/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun plugin (Lhep/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun plugin (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
|
||||
@ -147,7 +145,7 @@ public final class hep/dataforge/context/PluginFactory$Companion {
|
||||
}
|
||||
|
||||
public final class hep/dataforge/context/PluginManager : hep/dataforge/context/ContextAware, java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker {
|
||||
public fun <init> (Lhep/dataforge/context/Context;Ljava/util/Set;)V
|
||||
public fun <init> (Lhep/dataforge/context/Context;)V
|
||||
public final fun fetch (Lhep/dataforge/context/PluginFactory;ZLhep/dataforge/meta/Meta;)Lhep/dataforge/context/Plugin;
|
||||
public final fun fetch (Lhep/dataforge/context/PluginFactory;ZLkotlin/jvm/functions/Function1;)Lhep/dataforge/context/Plugin;
|
||||
public static synthetic fun fetch$default (Lhep/dataforge/context/PluginManager;Lhep/dataforge/context/PluginFactory;ZLhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/context/Plugin;
|
||||
|
@ -25,7 +25,6 @@ public open class Context(
|
||||
final override val name: Name,
|
||||
public val parent: Context?,
|
||||
meta: Meta,
|
||||
plugins: Set<Plugin> = emptySet(),
|
||||
) : Named, MetaRepr, Provider, CoroutineScope {
|
||||
|
||||
/**
|
||||
@ -40,7 +39,7 @@ public open class Context(
|
||||
/**
|
||||
* A [PluginManager] for current context
|
||||
*/
|
||||
public val plugins: PluginManager by lazy { PluginManager(this, plugins)}
|
||||
public val plugins: PluginManager by lazy { PluginManager(this)}
|
||||
|
||||
override val defaultTarget: String get() = Plugin.TARGET
|
||||
|
||||
|
@ -8,17 +8,13 @@ import hep.dataforge.names.toName
|
||||
*/
|
||||
@DFBuilder
|
||||
public class ContextBuilder(private val parent: Context = Global, public var name: String = "@anonymous") {
|
||||
private val plugins = HashSet<Plugin>()
|
||||
private val factories = HashMap<PluginFactory<*>, Meta>()
|
||||
private var meta = MetaBuilder()
|
||||
|
||||
public fun properties(action: MetaBuilder.() -> Unit) {
|
||||
meta.action()
|
||||
}
|
||||
|
||||
public fun plugin(plugin: Plugin) {
|
||||
plugins.add(plugin)
|
||||
}
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
private fun findPluginFactory(tag: PluginTag): PluginFactory<*> =
|
||||
parent.gatherInSequence<PluginFactory<*>>(PluginFactory.TYPE).values
|
||||
@ -26,12 +22,11 @@ public class ContextBuilder(private val parent: Context = Global, public var nam
|
||||
|
||||
public fun plugin(tag: PluginTag, metaBuilder: MetaBuilder.() -> Unit = {}) {
|
||||
val factory = findPluginFactory(tag)
|
||||
val plugin = factory.invoke(Meta(metaBuilder), parent)
|
||||
plugins.add(plugin)
|
||||
factories[factory] = Meta(metaBuilder)
|
||||
}
|
||||
|
||||
public fun plugin(builder: PluginFactory<*>, action: MetaBuilder.() -> Unit = {}) {
|
||||
plugins.add(builder.invoke(Meta(action)))
|
||||
public fun plugin(factory: PluginFactory<*>, metaBuilder: MetaBuilder.() -> Unit = {}) {
|
||||
factories[factory] = Meta(metaBuilder)
|
||||
}
|
||||
|
||||
public fun plugin(name: String, group: String = "", version: String = "", action: MetaBuilder.() -> Unit = {}) {
|
||||
@ -39,6 +34,10 @@ public class ContextBuilder(private val parent: Context = Global, public var nam
|
||||
}
|
||||
|
||||
public fun build(): Context {
|
||||
return Context(name.toName(), parent, meta.seal(), plugins)
|
||||
return Context(name.toName(), parent, meta.seal()).apply {
|
||||
factories.forEach { (factory, meta) ->
|
||||
plugins.load(factory, meta)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package hep.dataforge.context
|
||||
|
||||
import hep.dataforge.provider.Type
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@Type(PluginFactory.TYPE)
|
||||
public interface PluginFactory<T : Plugin> : Factory<T> {
|
||||
public val tag: PluginTag
|
||||
public val type: KClass<out T>
|
||||
|
||||
public companion object {
|
||||
public const val TYPE: String = "pluginFactory"
|
||||
}
|
||||
}
|
@ -2,34 +2,23 @@ package hep.dataforge.context
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.provider.Type
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
@Type(PluginFactory.TYPE)
|
||||
public interface PluginFactory<T : Plugin> : Factory<T> {
|
||||
public val tag: PluginTag
|
||||
public val type: KClass<out T>
|
||||
|
||||
public companion object {
|
||||
public const val TYPE: String = "pluginFactory"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The manager for plugin system. Should monitor plugin dependencies and locks.
|
||||
*
|
||||
* @property context A context for this plugin manager
|
||||
* @author Alexander Nozik
|
||||
*/
|
||||
public class PluginManager(override val context: Context, plugins: Set<Plugin>) : ContextAware, Iterable<Plugin> {
|
||||
public class PluginManager(override val context: Context) : ContextAware, Iterable<Plugin> {
|
||||
|
||||
//TODO refactor to read-only container
|
||||
|
||||
/**
|
||||
* A set of loaded plugins
|
||||
*/
|
||||
private val plugins: HashSet<Plugin> = HashSet(plugins)
|
||||
private val plugins: HashSet<Plugin> = HashSet()
|
||||
|
||||
init {
|
||||
plugins.forEach { it.attach(context) }
|
||||
|
@ -17,13 +17,13 @@ class ContextTest {
|
||||
else -> emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPluginManager() {
|
||||
val context = Global.context("test"){
|
||||
plugin(DummyPlugin())
|
||||
}
|
||||
val context = Global.context("test")
|
||||
context.plugins.load(DummyPlugin())
|
||||
//Global.plugins.load(DummyPlugin())
|
||||
val members = context.gather<Name>("test")
|
||||
assertEquals(3, members.count())
|
||||
|
@ -299,18 +299,6 @@ public final class hep/dataforge/meta/MetaSerializer : kotlinx/serialization/KSe
|
||||
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class hep/dataforge/meta/MetaWithDefault : hep/dataforge/meta/MetaBase {
|
||||
public fun <init> (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)V
|
||||
public final fun getDefault ()Lhep/dataforge/meta/ItemProvider;
|
||||
public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/TypedMetaItem;
|
||||
public fun getItems ()Ljava/util/Map;
|
||||
public final fun getMeta ()Lhep/dataforge/meta/Meta;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/meta/MetaWithDefaultKt {
|
||||
public static final fun withDefault (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MetaWithDefault;
|
||||
}
|
||||
|
||||
public final class hep/dataforge/meta/MutableItemDelegateKt {
|
||||
public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty;
|
||||
public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty;
|
||||
|
@ -24,7 +24,7 @@ public operator fun ItemProvider?.get(name: Name): MetaItem? = this?.getItem(nam
|
||||
/**
|
||||
* Root item of this provider
|
||||
*/
|
||||
public val ItemProvider.rootItem: MetaItem? get() = get(Name.EMPTY)
|
||||
public val ItemProvider.rootItem: MetaItem? get() = get(Name.EMPTY)
|
||||
|
||||
/**
|
||||
* The root node of this item provider if it is present
|
||||
@ -39,8 +39,12 @@ public operator fun ItemProvider?.get(key: String): MetaItem? = this?.get(key.to
|
||||
/**
|
||||
* Create a provider that uses given provider for default values if those are not found in this provider
|
||||
*/
|
||||
public fun ItemProvider.withDefault(default: ItemProvider): ItemProvider = ItemProvider {
|
||||
this[it] ?: default[it]
|
||||
public fun ItemProvider.withDefault(default: ItemProvider?): ItemProvider = if (default == null) {
|
||||
this
|
||||
} else {
|
||||
ItemProvider {
|
||||
this[it] ?: default[it]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +75,7 @@ public fun ItemProvider.getIndexed(name: String): Map<String?, MetaItem> = this@
|
||||
*/
|
||||
public fun ItemProvider.getChild(childName: Name): ItemProvider = get(childName).node ?: ItemProvider.EMPTY
|
||||
|
||||
public fun ItemProvider.getChild(childName: String): ItemProvider = getChild(childName.toName())
|
||||
public fun ItemProvider.getChild(childName: String): ItemProvider = getChild(childName.toName())
|
||||
|
||||
///**
|
||||
// * Get all items matching given name.
|
||||
|
@ -1,18 +0,0 @@
|
||||
package hep.dataforge.meta
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
|
||||
/**
|
||||
* Meta object with default provider for items not present in the initial meta.
|
||||
*/
|
||||
public class MetaWithDefault(public val meta: Meta, public val default: ItemProvider) : MetaBase() {
|
||||
override val items: Map<NameToken, MetaItem>
|
||||
get() = meta.items
|
||||
|
||||
override fun getItem(name: Name): MetaItem? {
|
||||
return meta[name] ?: default[name]
|
||||
}
|
||||
}
|
||||
|
||||
public fun Meta.withDefault(default: ItemProvider): MetaWithDefault = MetaWithDefault(this, default)
|
@ -56,8 +56,7 @@ class DataPropagationTestPlugin : WorkspacePlugin() {
|
||||
|
||||
override val type: KClass<out DataPropagationTestPlugin> = DataPropagationTestPlugin::class
|
||||
|
||||
override fun invoke(meta: Meta, context: Context): DataPropagationTestPlugin =
|
||||
DataPropagationTestPlugin(meta)
|
||||
override fun invoke(meta: Meta, context: Context): DataPropagationTestPlugin = DataPropagationTestPlugin()
|
||||
|
||||
override val tag: PluginTag = PluginTag("Test")
|
||||
}
|
||||
@ -66,7 +65,7 @@ class DataPropagationTestPlugin : WorkspacePlugin() {
|
||||
class DataPropagationTest {
|
||||
val testWorkspace = Workspace {
|
||||
context {
|
||||
plugin(DataPropagationTestPlugin())
|
||||
plugin(DataPropagationTestPlugin)
|
||||
}
|
||||
data {
|
||||
repeat(100) {
|
||||
|
@ -1,17 +1,23 @@
|
||||
package hep.dataforge.workspace
|
||||
|
||||
import hep.dataforge.context.PluginTag
|
||||
import hep.dataforge.context.logger
|
||||
import hep.dataforge.context.*
|
||||
import hep.dataforge.data.*
|
||||
import hep.dataforge.meta.boolean
|
||||
import hep.dataforge.meta.builder
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.int
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.plus
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Make a fake-factory for a one single plugin. Useful for unique or test plugins
|
||||
*/
|
||||
public inline fun <reified P: Plugin> P.toFactory(): PluginFactory<P> = object : PluginFactory<P> {
|
||||
override fun invoke(meta: Meta, context: Context): P = this@toFactory
|
||||
|
||||
override val tag: PluginTag = this@toFactory.tag
|
||||
override val type: KClass<out P> = P::class
|
||||
}
|
||||
|
||||
class SimpleWorkspaceTest {
|
||||
val testPlugin = object : WorkspacePlugin() {
|
||||
@ -23,11 +29,12 @@ class SimpleWorkspaceTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
val testPluginFactory = testPlugin.toFactory()
|
||||
|
||||
val workspace = Workspace {
|
||||
|
||||
context {
|
||||
plugin(testPlugin)
|
||||
plugin(testPluginFactory)
|
||||
}
|
||||
|
||||
data {
|
||||
|
Loading…
Reference in New Issue
Block a user