Documentation adjustment for Context
This commit is contained in:
parent
139a78beca
commit
abf222434f
@ -10,6 +10,18 @@ import mu.KLogger
|
||||
import mu.KotlinLogging
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
|
||||
* Context has [properties] - equivalent for system environment values, but grouped into a tree and inherited from parent context.
|
||||
*
|
||||
* The main function of the Context is to provide [PluginManager] which stores the loaded plugins and works as a dependency injection point.
|
||||
* The normal behaviour of the [PluginManager] is to search for a plugin in parent context if it is not found in a current one. It is possible to have
|
||||
* different plugins with the same interface in different contexts in the hierarchy. The usual behaviour is to use nearest one, but it could
|
||||
* be overridden by plugin implementation.
|
||||
*
|
||||
* Since plugins could contain mutable state, context has two states: active and inactive. No changes are allowed to active context.
|
||||
* @author Alexander Nozik
|
||||
*/
|
||||
interface Context : Named, MetaRepr, Provider {
|
||||
|
||||
val parent: Context?
|
||||
@ -24,6 +36,9 @@ interface Context : Named, MetaRepr, Provider {
|
||||
*/
|
||||
val logger: KLogger
|
||||
|
||||
/**
|
||||
* A [PluginManager] for current context
|
||||
*/
|
||||
val plugins: PluginManager
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,9 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
||||
*/
|
||||
private val plugins = HashSet<Plugin>()
|
||||
|
||||
/**
|
||||
* A [PluginManager] of parent context if it is present
|
||||
*/
|
||||
private val parent: PluginManager? = context.parent?.plugins
|
||||
|
||||
|
||||
@ -31,7 +34,9 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
||||
}
|
||||
|
||||
/**
|
||||
* Get for existing plugin
|
||||
* Get existing plugin or return null if not present. Only first matching plugin is returned.
|
||||
* @param recursive search for parent [PluginManager] plugins
|
||||
* @param predicate condition for the plugin
|
||||
*/
|
||||
fun get(recursive: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = sequence(recursive).find(predicate)
|
||||
|
||||
@ -87,6 +92,9 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a plugin from [PluginManager]
|
||||
*/
|
||||
fun remove(plugin: Plugin) {
|
||||
if (context.isActive) error("Can't remove plugin from active context")
|
||||
|
||||
@ -98,7 +106,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugin instance via plugin reolver and load it.
|
||||
* Get plugin instance via plugin resolver and load it.
|
||||
*
|
||||
* @param tag
|
||||
* @return
|
||||
@ -114,6 +122,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
fun <T : Plugin> load(type: KClass<T>, meta: Meta = EmptyMeta): T {
|
||||
val loaded = get(type, false)
|
||||
@ -142,4 +151,11 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
||||
|
||||
override fun iterator(): Iterator<Plugin> = plugins.iterator()
|
||||
|
||||
/**
|
||||
* Get a plugin if it exists or load it with given meta if it is not.
|
||||
*/
|
||||
inline fun <reified T : Plugin> getOrLoad(noinline metaBuilder: MetaBuilder.() -> Unit = {}): T {
|
||||
return get(true) ?: load(metaBuilder)
|
||||
}
|
||||
|
||||
}
|
@ -26,13 +26,6 @@ import kotlin.collections.HashSet
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.cast
|
||||
|
||||
/**
|
||||
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
|
||||
* Each context has a set of named [Value] properties which are taken from parent context in case they are not found in local context.
|
||||
* Context implements [ValueProvider] interface and therefore could be uses as a value source for substitutions etc.
|
||||
* Context contains [PluginManager] which could be used any number of configurable named plugins.
|
||||
* @author Alexander Nozik
|
||||
*/
|
||||
open class JVMContext(
|
||||
final override val name: String,
|
||||
final override val parent: JVMContext? = Global,
|
||||
|
Loading…
Reference in New Issue
Block a user