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 96c64308..dad483a8 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt @@ -71,7 +71,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable load(plugin: T): T { if (context.isActive) error("Can't load plugin into active context") - if (get(plugin::class, recursive = false) != null) { - throw RuntimeException("Plugin of type ${plugin::class} already exists in ${context.name}") + if (get(plugin::class, plugin.tag, recursive = false) != null) { + error("Plugin of type ${plugin::class} already exists in ${context.name}") } else { - loadDependencies(plugin) + for (tag in plugin.dependsOn()) { + fetch(tag, true) + } logger.info { "Loading plugin ${plugin.name} into ${context.name}" } plugin.attach(context) @@ -91,11 +93,14 @@ class PluginManager(override val context: Context) : ContextAware, Iterable load(factory: PluginFactory, meta: Meta = EmptyMeta): T = + load(factory(meta)) + + fun load(factory: PluginFactory, metaBuilder: MetaBuilder.() -> Unit): T = + load(factory, buildMeta(metaBuilder)) /** * Remove a plugin from [PluginManager] @@ -111,22 +116,11 @@ class PluginManager(override val context: Context) : ContextAware, Iterable load(PluginRepository.fetch(tag, meta)) - loaded.meta == meta -> loaded // if meta is the same, return existing plugin - else -> throw RuntimeException("Can't load plugin with tag $tag. Plugin with this tag and different configuration already exists in context.") - } - } - - fun load(factory: PluginFactory<*>, meta: Meta = EmptyMeta): Plugin { - val loaded = get(factory.tag, false) + fun fetch(factory: PluginFactory, recursive: Boolean = true, meta: Meta = EmptyMeta): T { + val loaded = get(factory.type, factory.tag, recursive) return when { loaded == null -> load(factory(meta)) loaded.meta == meta -> loaded // if meta is the same, return existing plugin @@ -134,43 +128,12 @@ class PluginManager(override val context: Context) : ContextAware, Iterable load(type: KClass, meta: Meta = EmptyMeta): T { - val loaded = get(type, recursive = false) - return when { - loaded == null -> { - val plugin = PluginRepository.list().find { it.type == type }?.invoke(meta) - ?: error("Plugin factory for class $type not found") - if (type.isInstance(plugin)) { - @Suppress("UNCHECKED_CAST") - load(plugin as T) - } else { - error("Corrupt type information in plugin repository") - } - } - loaded.meta == meta -> loaded // if meta is the same, return existing plugin - else -> throw RuntimeException("Can't load plugin with type $type. Plugin with this type and different configuration already exists in context.") - } - } - - inline fun load(noinline metaBuilder: MetaBuilder.() -> Unit = {}): T { - return load(T::class, buildMeta(metaBuilder)) - } - - fun load(name: String, meta: Meta = EmptyMeta): Plugin { - return load(PluginTag.fromString(name), meta) - } + fun fetch( + factory: PluginFactory, + recursive: Boolean = true, + metaBuilder: MetaBuilder.() -> Unit + ): T = fetch(factory, recursive, buildMeta(metaBuilder)) override fun iterator(): Iterator = plugins.iterator() - /** - * Get a plugin if it exists or load it with given meta if it is not. - */ - inline fun getOrLoad(noinline metaBuilder: MetaBuilder.() -> Unit = {}): T { - return get(recursive = true) ?: load(metaBuilder) - } - } \ No newline at end of file