Extend AbstractSingletonExtensionPoint and AbstractInstanceExtensionPoint, support lazy instance computation

This commit is contained in:
Him188 2021-12-26 18:55:19 +00:00
parent 8435131499
commit 9930fc7ed1
4 changed files with 51 additions and 14 deletions

View File

@ -51,25 +51,62 @@ public interface FunctionExtensionPoint<T : FunctionExtension> : ExtensionPoint<
public abstract class AbstractInstanceExtensionPoint<E : InstanceExtension<T>, T>
@ConsoleExperimentalApi constructor(
/**
* @since 2.10
*/
@ConsoleExperimentalApi
constructor(
extensionType: KClass<E>,
/**
* 内建的实现列表.
*/
@ConsoleExperimentalApi
public vararg val builtinImplementations: E,
) : AbstractExtensionPoint<E>(extensionType)
public vararg val builtinImplementations: () -> E,
) : AbstractExtensionPoint<E>(extensionType) {
/**
* @since 2.10
*/
@ConsoleExperimentalApi
public constructor(extensionType: KClass<E>) : this(
extensionType,
builtinImplementations = arrayOf<() -> E>() as Array<out () -> E>
) // to avoid resolution ambiguity
/**
* @since 2.0
*/
@ConsoleExperimentalApi
public constructor(extensionType: KClass<E>, vararg builtinImplementations: E) : this(
extensionType,
builtinImplementations = builtinImplementations.map { { it } }.toTypedArray()
)
}
public abstract class AbstractSingletonExtensionPoint<E : SingletonExtension<T>, T>
@ConsoleExperimentalApi constructor(
/**
* @since 2.10
*/
@ConsoleExperimentalApi
constructor(
extensionType: KClass<E>,
/**
* 内建的实现.
*/
@ConsoleExperimentalApi
public val builtinImplementation: T,
public val builtinImplementation: () -> T,
) : AbstractExtensionPoint<E>(extensionType), SingletonExtensionPoint<E> {
/**
* @since 2.0
*/
@Suppress("USELESS_CAST") // compiler bug
@ConsoleExperimentalApi
public constructor(extensionType: KClass<E>, builtinImplementation: T) : this(
extensionType,
{ builtinImplementation } as () -> T
)
/**
* [SingletonExtensionSelector] 选择后的实例.
*/

View File

@ -20,7 +20,7 @@ public interface CommandCallResolverProvider : SingletonExtension<CommandCallRes
public companion object ExtensionPoint :
AbstractSingletonExtensionPoint<CommandCallResolverProvider, CommandCallResolver>(
CommandCallResolverProvider::class,
BuiltInCommandCallResolver
{ BuiltInCommandCallResolver }
)
}

View File

@ -26,7 +26,7 @@ public interface PermissionServiceProvider : SingletonExtension<PermissionServic
public companion object ExtensionPoint :
AbstractSingletonExtensionPoint<PermissionServiceProvider, PermissionService<*>>(
PermissionServiceProvider::class,
BuiltInPermissionService
{ BuiltInPermissionService }
) {
internal var permissionServiceOk = false

View File

@ -57,10 +57,10 @@ internal abstract class AbstractConcurrentComponentStorage : ComponentStorage {
val userDefined = instances.getOrPut(this, ::CopyOnWriteArraySet) as Set<ExtensionRegistry<T>>
val builtins = if (this is AbstractInstanceExtensionPoint<*, *>) {
this.builtinImplementations.mapTo(HashSet()) {
this.builtinImplementations.mapTo(HashSet()) { instance ->
DataExtensionRegistry(
null,
it
instance()
)
} as Set<ExtensionRegistry<T>>
} else null
@ -116,18 +116,18 @@ internal abstract class AbstractConcurrentComponentStorage : ComponentStorage {
}
}
internal inline fun <reified E : SingletonExtension<T>, T> ExtensionPoint<out E>.findSingletonInstance(builtin: T): T =
findSingletonInstance(E::class, builtin)
internal inline fun <reified E : SingletonExtension<T>, T> ExtensionPoint<out E>.findSingletonInstance(noinline default: () -> T): T =
findSingletonInstance(E::class, default)
internal fun <E : SingletonExtension<T>, T> ExtensionPoint<out E>.findSingletonInstance(
type: KClass<E>,
builtin: T,
default: () -> T,
): T {
val candidates = this.getExtensions()
return when (candidates.size) {
0 -> builtin
0 -> default()
1 -> candidates.single().extension.instance
else -> SingletonExtensionSelector.instance.selectSingleton(type, candidates)?.instance ?: builtin
else -> SingletonExtensionSelector.instance.selectSingleton(type, candidates)?.instance ?: default()
}
}