From 9930fc7ed1dc7b5308a496a8c9205834b243dc62 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 26 Dec 2021 18:55:19 +0000 Subject: [PATCH] Extend `AbstractSingletonExtensionPoint` and `AbstractInstanceExtensionPoint`, support lazy instance computation --- .../src/extension/ExtensionPoint.kt | 47 +++++++++++++++++-- .../extensions/CommandCallResolverProvider.kt | 2 +- .../extensions/PermissionServiceProvider.kt | 2 +- .../extension/ComponentStorageInternal.kt | 14 +++--- 4 files changed, 51 insertions(+), 14 deletions(-) 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 : ExtensionPoint< public abstract class AbstractInstanceExtensionPoint, T> -@ConsoleExperimentalApi constructor( +/** + * @since 2.10 + */ +@ConsoleExperimentalApi +constructor( extensionType: KClass, /** * 内建的实现列表. */ @ConsoleExperimentalApi - public vararg val builtinImplementations: E, -) : AbstractExtensionPoint(extensionType) + public vararg val builtinImplementations: () -> E, +) : AbstractExtensionPoint(extensionType) { + + /** + * @since 2.10 + */ + @ConsoleExperimentalApi + public constructor(extensionType: KClass) : this( + extensionType, + builtinImplementations = arrayOf<() -> E>() as Array E> + ) // to avoid resolution ambiguity + + /** + * @since 2.0 + */ + @ConsoleExperimentalApi + public constructor(extensionType: KClass, vararg builtinImplementations: E) : this( + extensionType, + builtinImplementations = builtinImplementations.map { { it } }.toTypedArray() + ) +} public abstract class AbstractSingletonExtensionPoint, T> -@ConsoleExperimentalApi constructor( +/** + * @since 2.10 + */ +@ConsoleExperimentalApi +constructor( extensionType: KClass, /** * 内建的实现. */ @ConsoleExperimentalApi - public val builtinImplementation: T, + public val builtinImplementation: () -> T, ) : AbstractExtensionPoint(extensionType), SingletonExtensionPoint { + /** + * @since 2.0 + */ + @Suppress("USELESS_CAST") // compiler bug + @ConsoleExperimentalApi + public constructor(extensionType: KClass, 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( 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>( 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> val builtins = if (this is AbstractInstanceExtensionPoint<*, *>) { - this.builtinImplementations.mapTo(HashSet()) { + this.builtinImplementations.mapTo(HashSet()) { instance -> DataExtensionRegistry( null, - it + instance() ) } as Set> } else null @@ -116,18 +116,18 @@ internal abstract class AbstractConcurrentComponentStorage : ComponentStorage { } } - internal inline fun , T> ExtensionPoint.findSingletonInstance(builtin: T): T = - findSingletonInstance(E::class, builtin) + internal inline fun , T> ExtensionPoint.findSingletonInstance(noinline default: () -> T): T = + findSingletonInstance(E::class, default) internal fun , T> ExtensionPoint.findSingletonInstance( type: KClass, - 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() } }