mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-19 15:09:10 +08:00
Extend AbstractSingletonExtensionPoint
and AbstractInstanceExtensionPoint
, support lazy instance computation
This commit is contained in:
parent
8435131499
commit
9930fc7ed1
@ -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] 选择后的实例.
|
||||
*/
|
||||
|
@ -20,7 +20,7 @@ public interface CommandCallResolverProvider : SingletonExtension<CommandCallRes
|
||||
public companion object ExtensionPoint :
|
||||
AbstractSingletonExtensionPoint<CommandCallResolverProvider, CommandCallResolver>(
|
||||
CommandCallResolverProvider::class,
|
||||
BuiltInCommandCallResolver
|
||||
{ BuiltInCommandCallResolver }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public interface PermissionServiceProvider : SingletonExtension<PermissionServic
|
||||
public companion object ExtensionPoint :
|
||||
AbstractSingletonExtensionPoint<PermissionServiceProvider, PermissionService<*>>(
|
||||
PermissionServiceProvider::class,
|
||||
BuiltInPermissionService
|
||||
{ BuiltInPermissionService }
|
||||
) {
|
||||
internal var permissionServiceOk = false
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user