Updated plugin management
This commit is contained in:
parent
16d263dc0b
commit
ad23478a79
@ -46,7 +46,7 @@ interface Plugin : Named, ContextAware, Provider, MetaRepr, Configurable {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
fun dependsOn(): List<PluginTag> = emptyList()
|
fun dependsOn(): List<PluginFactory<*>> = emptyList()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start this plugin and attach registration info to the context. This method
|
* Start this plugin and attach registration info to the context. This method
|
||||||
|
@ -118,6 +118,15 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun load(factory: PluginFactory<*>, 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.
|
* 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
|
* Throw an exception if there exists plugin with the same type, but different meta
|
||||||
|
@ -4,23 +4,23 @@ import hep.dataforge.meta.Meta
|
|||||||
import hep.dataforge.meta.configure
|
import hep.dataforge.meta.configure
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
interface PluginFactory {
|
interface PluginFactory<T: Plugin> {
|
||||||
val tag: PluginTag
|
val tag: PluginTag
|
||||||
val type: KClass<out Plugin>
|
val type: KClass<out T>
|
||||||
fun build(): Plugin
|
fun build(): T
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PluginFactory.build(meta: Meta) = build().configure(meta)
|
fun PluginFactory<*>.build(meta: Meta) = build().configure(meta)
|
||||||
|
|
||||||
|
|
||||||
expect object PluginRepository {
|
expect object PluginRepository {
|
||||||
|
|
||||||
fun register(factory: PluginFactory)
|
fun register(factory: PluginFactory<*>)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List plugins available in the repository
|
* List plugins available in the repository
|
||||||
*/
|
*/
|
||||||
fun list(): Sequence<PluginFactory>
|
fun list(): Sequence<PluginFactory<*>>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,15 +31,16 @@ fun PluginRepository.fetch(tag: PluginTag): Plugin =
|
|||||||
PluginRepository.list().find { it.tag.matches(tag) }?.build()
|
PluginRepository.list().find { it.tag.matches(tag) }?.build()
|
||||||
?: error("Plugin with tag $tag not found in the repository")
|
?: error("Plugin with tag $tag not found in the repository")
|
||||||
|
|
||||||
fun PluginRepository.register(tag: PluginTag, type: KClass<out Plugin>, constructor: () -> Plugin) {
|
fun <T: Plugin> PluginRepository.register(tag: PluginTag, type: KClass<out T>, constructor: () -> T): PluginFactory<T> {
|
||||||
val factory = object : PluginFactory {
|
val factory = object : PluginFactory<T> {
|
||||||
override val tag: PluginTag = tag
|
override val tag: PluginTag = tag
|
||||||
override val type: KClass<out Plugin> = type
|
override val type: KClass<out T> = type
|
||||||
|
|
||||||
override fun build(): Plugin = constructor()
|
override fun build(): T = constructor()
|
||||||
|
|
||||||
}
|
}
|
||||||
PluginRepository.register(factory)
|
PluginRepository.register(factory)
|
||||||
|
return factory
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : Plugin> PluginRepository.register(tag: PluginTag, noinline constructor: () -> T) =
|
inline fun <reified T : Plugin> PluginRepository.register(tag: PluginTag, noinline constructor: () -> T) =
|
||||||
|
@ -3,14 +3,14 @@ package hep.dataforge.context
|
|||||||
|
|
||||||
actual object PluginRepository {
|
actual object PluginRepository {
|
||||||
|
|
||||||
private val factories: MutableSet<PluginFactory> = HashSet()
|
private val factories: MutableSet<PluginFactory<*>> = HashSet()
|
||||||
|
|
||||||
actual fun register(factory: PluginFactory) {
|
actual fun register(factory: PluginFactory<*>) {
|
||||||
factories.add(factory)
|
factories.add(factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List plugins available in the repository
|
* List plugins available in the repository
|
||||||
*/
|
*/
|
||||||
actual fun list(): Sequence<PluginFactory> = factories.asSequence()
|
actual fun list(): Sequence<PluginFactory<*>> = factories.asSequence()
|
||||||
}
|
}
|
@ -2,16 +2,16 @@ package hep.dataforge.context
|
|||||||
|
|
||||||
actual object PluginRepository {
|
actual object PluginRepository {
|
||||||
|
|
||||||
private val factories: MutableSet<PluginFactory> = HashSet()
|
private val factories: MutableSet<PluginFactory<*>> = HashSet()
|
||||||
|
|
||||||
actual fun register(factory: PluginFactory) {
|
actual fun register(factory: PluginFactory<*>) {
|
||||||
factories.add(factory)
|
factories.add(factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List plugins available in the repository
|
* List plugins available in the repository
|
||||||
*/
|
*/
|
||||||
actual fun list(): Sequence<PluginFactory> =
|
actual fun list(): Sequence<PluginFactory<*>> =
|
||||||
factories.asSequence() + Global.services()
|
factories.asSequence() + Global.services()
|
||||||
|
|
||||||
}
|
}
|
@ -1,9 +1,6 @@
|
|||||||
package hep.dataforge.output
|
package hep.dataforge.output
|
||||||
|
|
||||||
import hep.dataforge.context.AbstractPlugin
|
import hep.dataforge.context.*
|
||||||
import hep.dataforge.context.Context
|
|
||||||
import hep.dataforge.context.Plugin
|
|
||||||
import hep.dataforge.context.PluginTag
|
|
||||||
import hep.dataforge.context.PluginTag.Companion.DATAFORGE_GROUP
|
import hep.dataforge.context.PluginTag.Companion.DATAFORGE_GROUP
|
||||||
import hep.dataforge.meta.EmptyMeta
|
import hep.dataforge.meta.EmptyMeta
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
@ -24,13 +21,18 @@ interface OutputManager : Plugin {
|
|||||||
* @param name represents the name inside the node.
|
* @param name represents the name inside the node.
|
||||||
* @param meta configuration for [Output] (not for rendered object)
|
* @param meta configuration for [Output] (not for rendered object)
|
||||||
*/
|
*/
|
||||||
operator fun <T : Any> get(type: KClass<out T>, name: Name, stage: Name = EmptyName, meta: Meta = EmptyMeta): Output<T>
|
operator fun <T : Any> get(
|
||||||
|
type: KClass<out T>,
|
||||||
|
name: Name,
|
||||||
|
stage: Name = EmptyName,
|
||||||
|
meta: Meta = EmptyMeta
|
||||||
|
): Output<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an output manager for a context
|
* 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
|
* Get an output with given [name], [stage] and reified content type
|
||||||
@ -47,7 +49,7 @@ inline operator fun <reified T : Any> OutputManager.get(
|
|||||||
* Directly render an object using the most suitable renderer
|
* Directly render an object using the most suitable renderer
|
||||||
*/
|
*/
|
||||||
fun OutputManager.render(obj: Any, name: Name, stage: Name = EmptyName, meta: Meta = EmptyMeta) =
|
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.
|
* System console output.
|
||||||
@ -55,10 +57,18 @@ fun OutputManager.render(obj: Any, name: Name, stage: Name = EmptyName, meta: Me
|
|||||||
*/
|
*/
|
||||||
expect val ConsoleOutput: Output<Any>
|
expect val ConsoleOutput: Output<Any>
|
||||||
|
|
||||||
object ConsoleOutputManager : AbstractPlugin(), OutputManager {
|
class ConsoleOutputManager : AbstractPlugin(), OutputManager {
|
||||||
override val tag: PluginTag = PluginTag("output.console", group = DATAFORGE_GROUP)
|
override val tag: PluginTag get() = ConsoleOutputManager.tag
|
||||||
|
|
||||||
override fun <T : Any> get(type: KClass<out T>, name: Name, stage: Name, meta: Meta): Output<T> = ConsoleOutput
|
override fun <T : Any> get(type: KClass<out T>, name: Name, stage: Name, meta: Meta): Output<T> = ConsoleOutput
|
||||||
|
|
||||||
|
companion object : PluginFactory<ConsoleOutputManager> {
|
||||||
|
override val tag = PluginTag("output.console", group = DATAFORGE_GROUP)
|
||||||
|
|
||||||
|
override val type = ConsoleOutputManager::class
|
||||||
|
|
||||||
|
override fun build() = ConsoleOutputManager()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user