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> public abstract class AbstractInstanceExtensionPoint<E : InstanceExtension<T>, T>
@ConsoleExperimentalApi constructor( /**
* @since 2.10
*/
@ConsoleExperimentalApi
constructor(
extensionType: KClass<E>, extensionType: KClass<E>,
/** /**
* 内建的实现列表. * 内建的实现列表.
*/ */
@ConsoleExperimentalApi @ConsoleExperimentalApi
public vararg val builtinImplementations: E, public vararg val builtinImplementations: () -> E,
) : AbstractExtensionPoint<E>(extensionType) ) : 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> public abstract class AbstractSingletonExtensionPoint<E : SingletonExtension<T>, T>
@ConsoleExperimentalApi constructor( /**
* @since 2.10
*/
@ConsoleExperimentalApi
constructor(
extensionType: KClass<E>, extensionType: KClass<E>,
/** /**
* 内建的实现. * 内建的实现.
*/ */
@ConsoleExperimentalApi @ConsoleExperimentalApi
public val builtinImplementation: T, public val builtinImplementation: () -> T,
) : AbstractExtensionPoint<E>(extensionType), SingletonExtensionPoint<E> { ) : 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] 选择后的实例. * [SingletonExtensionSelector] 选择后的实例.
*/ */

View File

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

View File

@ -26,7 +26,7 @@ public interface PermissionServiceProvider : SingletonExtension<PermissionServic
public companion object ExtensionPoint : public companion object ExtensionPoint :
AbstractSingletonExtensionPoint<PermissionServiceProvider, PermissionService<*>>( AbstractSingletonExtensionPoint<PermissionServiceProvider, PermissionService<*>>(
PermissionServiceProvider::class, PermissionServiceProvider::class,
BuiltInPermissionService { BuiltInPermissionService }
) { ) {
internal var permissionServiceOk = false 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 userDefined = instances.getOrPut(this, ::CopyOnWriteArraySet) as Set<ExtensionRegistry<T>>
val builtins = if (this is AbstractInstanceExtensionPoint<*, *>) { val builtins = if (this is AbstractInstanceExtensionPoint<*, *>) {
this.builtinImplementations.mapTo(HashSet()) { this.builtinImplementations.mapTo(HashSet()) { instance ->
DataExtensionRegistry( DataExtensionRegistry(
null, null,
it instance()
) )
} as Set<ExtensionRegistry<T>> } as Set<ExtensionRegistry<T>>
} else null } 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 = internal inline fun <reified E : SingletonExtension<T>, T> ExtensionPoint<out E>.findSingletonInstance(noinline default: () -> T): T =
findSingletonInstance(E::class, builtin) findSingletonInstance(E::class, default)
internal fun <E : SingletonExtension<T>, T> ExtensionPoint<out E>.findSingletonInstance( internal fun <E : SingletonExtension<T>, T> ExtensionPoint<out E>.findSingletonInstance(
type: KClass<E>, type: KClass<E>,
builtin: T, default: () -> T,
): T { ): T {
val candidates = this.getExtensions() val candidates = this.getExtensions()
return when (candidates.size) { return when (candidates.size) {
0 -> builtin 0 -> default()
1 -> candidates.single().extension.instance 1 -> candidates.single().extension.instance
else -> SingletonExtensionSelector.instance.selectSingleton(type, candidates)?.instance ?: builtin else -> SingletonExtensionSelector.instance.selectSingleton(type, candidates)?.instance ?: default()
} }
} }