diff --git a/mirai-console/backend/mirai-console/src/extension/ExtensionPoint.kt b/mirai-console/backend/mirai-console/src/extension/ExtensionPoint.kt index 07afb9f83..f861b92ed 100644 --- a/mirai-console/backend/mirai-console/src/extension/ExtensionPoint.kt +++ b/mirai-console/backend/mirai-console/src/extension/ExtensionPoint.kt @@ -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] 选择后的实例. */ diff --git a/mirai-console/backend/mirai-console/src/extensions/CommandCallResolverProvider.kt b/mirai-console/backend/mirai-console/src/extensions/CommandCallResolverProvider.kt index e88519539..3181a9045 100644 --- a/mirai-console/backend/mirai-console/src/extensions/CommandCallResolverProvider.kt +++ b/mirai-console/backend/mirai-console/src/extensions/CommandCallResolverProvider.kt @@ -20,7 +20,7 @@ public interface CommandCallResolverProvider : SingletonExtension<CommandCallRes public companion object ExtensionPoint : AbstractSingletonExtensionPoint<CommandCallResolverProvider, CommandCallResolver>( CommandCallResolverProvider::class, - BuiltInCommandCallResolver + { BuiltInCommandCallResolver } ) } diff --git a/mirai-console/backend/mirai-console/src/extensions/PermissionServiceProvider.kt b/mirai-console/backend/mirai-console/src/extensions/PermissionServiceProvider.kt index 3a4806c48..2d0618180 100644 --- a/mirai-console/backend/mirai-console/src/extensions/PermissionServiceProvider.kt +++ b/mirai-console/backend/mirai-console/src/extensions/PermissionServiceProvider.kt @@ -26,7 +26,7 @@ public interface PermissionServiceProvider : SingletonExtension<PermissionServic public companion object ExtensionPoint : AbstractSingletonExtensionPoint<PermissionServiceProvider, PermissionService<*>>( PermissionServiceProvider::class, - BuiltInPermissionService + { BuiltInPermissionService } ) { internal var permissionServiceOk = false diff --git a/mirai-console/backend/mirai-console/src/internal/extension/ComponentStorageInternal.kt b/mirai-console/backend/mirai-console/src/internal/extension/ComponentStorageInternal.kt index 96d44922d..5e8d4a755 100644 --- a/mirai-console/backend/mirai-console/src/internal/extension/ComponentStorageInternal.kt +++ b/mirai-console/backend/mirai-console/src/internal/extension/ComponentStorageInternal.kt @@ -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() } }