From ad23478a79c70ebd7b5c925e279fb8c7878c7bb5 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 23 Mar 2019 11:28:24 +0300 Subject: [PATCH] Updated plugin management --- .../kotlin/hep/dataforge/context/Plugin.kt | 2 +- .../hep/dataforge/context/PluginManager.kt | 9 ++++++ .../hep/dataforge/context/PluginRepository.kt | 21 +++++++------- .../hep/dataforge/context/PluginRepository.kt | 6 ++-- .../hep/dataforge/context/PluginRepository.kt | 6 ++-- .../hep/dataforge/output/OutputManager.kt | 28 +++++++++++++------ 6 files changed, 46 insertions(+), 26 deletions(-) diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt index 1de7f6ca..4560e29b 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt @@ -46,7 +46,7 @@ interface Plugin : Named, ContextAware, Provider, MetaRepr, Configurable { * * @return */ - fun dependsOn(): List = emptyList() + fun dependsOn(): List> = emptyList() /** * Start this plugin and attach registration info to the context. This method diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt index 1f905093..b03d289a 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt @@ -118,6 +118,15 @@ class PluginManager(override val context: Context) : ContextAware, Iterable, meta: Meta = EmptyMeta): Plugin{ + val loaded = get(factory.tag, false) + return when { + loaded == null -> factory.build(meta) + loaded.config == meta -> loaded // if meta is the same, return existing plugin + else -> throw RuntimeException("Can't load plugin with tag ${factory.tag}. Plugin with this tag and different configuration already exists in context.") + } + } + /** * Load plugin by its class and meta. Ignore if plugin with this meta is already loaded. * Throw an exception if there exists plugin with the same type, but different meta diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginRepository.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginRepository.kt index 43e51a07..c34287ab 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginRepository.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginRepository.kt @@ -4,23 +4,23 @@ import hep.dataforge.meta.Meta import hep.dataforge.meta.configure import kotlin.reflect.KClass -interface PluginFactory { +interface PluginFactory { val tag: PluginTag - val type: KClass - fun build(): Plugin + val type: KClass + fun build(): T } -fun PluginFactory.build(meta: Meta) = build().configure(meta) +fun PluginFactory<*>.build(meta: Meta) = build().configure(meta) expect object PluginRepository { - fun register(factory: PluginFactory) + fun register(factory: PluginFactory<*>) /** * List plugins available in the repository */ - fun list(): Sequence + fun list(): Sequence> } @@ -31,15 +31,16 @@ fun PluginRepository.fetch(tag: PluginTag): Plugin = PluginRepository.list().find { it.tag.matches(tag) }?.build() ?: error("Plugin with tag $tag not found in the repository") -fun PluginRepository.register(tag: PluginTag, type: KClass, constructor: () -> Plugin) { - val factory = object : PluginFactory { +fun PluginRepository.register(tag: PluginTag, type: KClass, constructor: () -> T): PluginFactory { + val factory = object : PluginFactory { override val tag: PluginTag = tag - override val type: KClass = type + override val type: KClass = type - override fun build(): Plugin = constructor() + override fun build(): T = constructor() } PluginRepository.register(factory) + return factory } inline fun PluginRepository.register(tag: PluginTag, noinline constructor: () -> T) = diff --git a/dataforge-context/src/jsMain/kotlin/hep/dataforge/context/PluginRepository.kt b/dataforge-context/src/jsMain/kotlin/hep/dataforge/context/PluginRepository.kt index 4cbeb0d1..78a2952e 100644 --- a/dataforge-context/src/jsMain/kotlin/hep/dataforge/context/PluginRepository.kt +++ b/dataforge-context/src/jsMain/kotlin/hep/dataforge/context/PluginRepository.kt @@ -3,14 +3,14 @@ package hep.dataforge.context actual object PluginRepository { - private val factories: MutableSet = HashSet() + private val factories: MutableSet> = HashSet() - actual fun register(factory: PluginFactory) { + actual fun register(factory: PluginFactory<*>) { factories.add(factory) } /** * List plugins available in the repository */ - actual fun list(): Sequence = factories.asSequence() + actual fun list(): Sequence> = factories.asSequence() } \ No newline at end of file diff --git a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/PluginRepository.kt b/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/PluginRepository.kt index 05b65ad9..83455fd6 100644 --- a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/PluginRepository.kt +++ b/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/PluginRepository.kt @@ -2,16 +2,16 @@ package hep.dataforge.context actual object PluginRepository { - private val factories: MutableSet = HashSet() + private val factories: MutableSet> = HashSet() - actual fun register(factory: PluginFactory) { + actual fun register(factory: PluginFactory<*>) { factories.add(factory) } /** * List plugins available in the repository */ - actual fun list(): Sequence = + actual fun list(): Sequence> = factories.asSequence() + Global.services() } \ No newline at end of file diff --git a/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/OutputManager.kt b/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/OutputManager.kt index 2a133f5d..96c4e120 100644 --- a/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/OutputManager.kt +++ b/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/OutputManager.kt @@ -1,9 +1,6 @@ package hep.dataforge.output -import hep.dataforge.context.AbstractPlugin -import hep.dataforge.context.Context -import hep.dataforge.context.Plugin -import hep.dataforge.context.PluginTag +import hep.dataforge.context.* import hep.dataforge.context.PluginTag.Companion.DATAFORGE_GROUP import hep.dataforge.meta.EmptyMeta import hep.dataforge.meta.Meta @@ -24,13 +21,18 @@ interface OutputManager : Plugin { * @param name represents the name inside the node. * @param meta configuration for [Output] (not for rendered object) */ - operator fun get(type: KClass, name: Name, stage: Name = EmptyName, meta: Meta = EmptyMeta): Output + operator fun get( + type: KClass, + name: Name, + stage: Name = EmptyName, + meta: Meta = EmptyMeta + ): Output } /** * Get an output manager for a context */ -val Context.output: OutputManager get() = plugins.get() ?: ConsoleOutputManager +val Context.output: OutputManager get() = plugins.get() ?: ConsoleOutputManager() /** * Get an output with given [name], [stage] and reified content type @@ -47,7 +49,7 @@ inline operator fun OutputManager.get( * Directly render an object using the most suitable renderer */ fun OutputManager.render(obj: Any, name: Name, stage: Name = EmptyName, meta: Meta = EmptyMeta) = - get(obj::class, name,stage).render(obj,meta) + get(obj::class, name, stage).render(obj, meta) /** * System console output. @@ -55,10 +57,18 @@ fun OutputManager.render(obj: Any, name: Name, stage: Name = EmptyName, meta: Me */ expect val ConsoleOutput: Output -object ConsoleOutputManager : AbstractPlugin(), OutputManager { - override val tag: PluginTag = PluginTag("output.console", group = DATAFORGE_GROUP) +class ConsoleOutputManager : AbstractPlugin(), OutputManager { + override val tag: PluginTag get() = ConsoleOutputManager.tag override fun get(type: KClass, name: Name, stage: Name, meta: Meta): Output = ConsoleOutput + + companion object : PluginFactory { + override val tag = PluginTag("output.console", group = DATAFORGE_GROUP) + + override val type = ConsoleOutputManager::class + + override fun build() = ConsoleOutputManager() + } } /**