1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-05-06 05:45:19 +08:00

[core] Simplify and stabilize BaseService and AudioToSilkService ()

* [core] Simplify and stabilize BaseService and AudioToSilkService

* fix

* api dump
This commit is contained in:
Him188 2023-05-21 00:24:51 +01:00 committed by GitHub
parent c57fdd7790
commit dafa25d611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 100 additions and 119 deletions
mirai-core-api
compatibility-validation
android/api
jvm/api
src
commonMain/kotlin/spi
jvmBaseMain/kotlin/spi
nativeMain/kotlin/spi
mirai-core/src/commonMain/kotlin/contact

View File

@ -5438,6 +5438,20 @@ public final class net/mamoe/mirai/network/UnsupportedSmsLoginException : net/ma
public final class net/mamoe/mirai/network/WrongPasswordException : net/mamoe/mirai/network/LoginFailedException {
}
public abstract interface class net/mamoe/mirai/spi/AudioToSilkService : net/mamoe/mirai/spi/BaseService {
public static final field Companion Lnet/mamoe/mirai/spi/AudioToSilkService$Companion;
public abstract fun convert (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static fun getInstance ()Lnet/mamoe/mirai/spi/AudioToSilkService;
}
public final class net/mamoe/mirai/spi/AudioToSilkService$Companion {
public final fun getInstance ()Lnet/mamoe/mirai/spi/AudioToSilkService;
}
public abstract interface class net/mamoe/mirai/spi/BaseService {
public fun getPriority ()I
}
public abstract class net/mamoe/mirai/utils/AbstractBotConfiguration {
public fun <init> ()V
public final fun fileBasedDeviceInfo ()V

View File

@ -5438,6 +5438,20 @@ public final class net/mamoe/mirai/network/UnsupportedSmsLoginException : net/ma
public final class net/mamoe/mirai/network/WrongPasswordException : net/mamoe/mirai/network/LoginFailedException {
}
public abstract interface class net/mamoe/mirai/spi/AudioToSilkService : net/mamoe/mirai/spi/BaseService {
public static final field Companion Lnet/mamoe/mirai/spi/AudioToSilkService$Companion;
public abstract fun convert (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static fun getInstance ()Lnet/mamoe/mirai/spi/AudioToSilkService;
}
public final class net/mamoe/mirai/spi/AudioToSilkService$Companion {
public final fun getInstance ()Lnet/mamoe/mirai/spi/AudioToSilkService;
}
public abstract interface class net/mamoe/mirai/spi/BaseService {
public fun getPriority ()I
}
public abstract class net/mamoe/mirai/utils/AbstractBotConfiguration {
public fun <init> ()V
public final fun fileBasedDeviceInfo ()V

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -9,17 +9,17 @@
package net.mamoe.mirai.spi
import io.ktor.utils.io.errors.*
import net.mamoe.mirai.utils.*
import kotlin.coroutines.cancellation.CancellationException
import net.mamoe.mirai.utils.ExternalResource
import net.mamoe.mirai.utils.runAutoClose
import net.mamoe.mirai.utils.useAutoClose
import net.mamoe.mirai.utils.withAutoClose
import kotlin.jvm.JvmStatic
/**
* 将源音频文件转换为 silk v3 with tencent 格式
*
* @since 2.8.0
*/
@MiraiExperimentalApi
*/ // stable since 2.15
public interface AudioToSilkService : BaseService {
/**
* implementation note:
@ -35,24 +35,19 @@ public interface AudioToSilkService : BaseService {
* @see [runAutoClose]
* @see [useAutoClose]
*/
@Throws(IOException::class, CancellationException::class)
public suspend fun convert(source: ExternalResource): ExternalResource
@MiraiExperimentalApi
public companion object : AudioToSilkService {
private val loader = SPIServiceLoader(object : AudioToSilkService {
override suspend fun convert(source: ExternalResource): ExternalResource = source
}, AudioToSilkService::class)
@Suppress("BlockingMethodInNonBlockingContext")
@Throws(IOException::class, CancellationException::class)
override suspend fun convert(source: ExternalResource): ExternalResource {
return loader.service.convert(source)
public companion object {
private val loader = SpiServiceLoader(AudioToSilkService::class) {
object : AudioToSilkService {
override suspend fun convert(source: ExternalResource): ExternalResource = source
}
}
/**
* 获取当前实例
*/
@JvmStatic
public fun setService(service: AudioToSilkService) {
loader.service = service
}
public val instance: AudioToSilkService get() = loader.service
}
}

View File

@ -9,32 +9,71 @@
package net.mamoe.mirai.spi
import net.mamoe.mirai.utils.MiraiExperimentalApi
import kotlinx.atomicfu.locks.SynchronizedObject
import kotlinx.atomicfu.locks.synchronized
import net.mamoe.mirai.utils.MiraiLogger
import kotlin.jvm.JvmField
import net.mamoe.mirai.utils.lateinitMutableProperty
import net.mamoe.mirai.utils.loadServices
import kotlin.reflect.KClass
/**
* 基本 SPI 接口
* @since 2.8.0
*/
@MiraiExperimentalApi
*/ // stable since 2.15
public interface BaseService {
/** 使用优先级, 值越小越先使用 */
public val priority: Int get() = 5
public val priority: Int get() = 0
}
@OptIn(MiraiExperimentalApi::class)
internal expect class SPIServiceLoader<T : BaseService>(
defaultService: T,
internal fun <T : BaseService> SpiServiceLoader(
serviceType: KClass<T>,
) {
@JvmField
var service: T
defaultImplementation: () -> T
): SpiServiceLoader<T> {
return SpiServiceLoaderImpl(serviceType, defaultImplementation)
}
fun reload()
internal fun <T : BaseService> SpiServiceLoader(
serviceType: KClass<T>
): SpiServiceLoader<T?> {
return SpiServiceLoaderImpl(serviceType, null)
}
internal interface SpiServiceLoader<T : BaseService?> {
val service: T
}
internal class SpiServiceLoaderImpl<T : BaseService?>(
private val serviceType: KClass<T & Any>,
defaultService: (() -> T)?
) : SpiServiceLoader<T> {
private val defaultInstance: T? by lazy {
defaultService?.invoke()
}
private val lock = SynchronizedObject()
override val service: T get() = _service
private var _service: T by lateinitMutableProperty {
synchronized(lock) {
reloadAndSelect()
}
}
fun reload() {
synchronized(lock) {
_service = reloadAndSelect()
}
}
private fun reloadAndSelect(): T {
@Suppress("UNCHECKED_CAST")
return (loadServices(serviceType).minByOrNull { it.priority } ?: defaultInstance) as T
}
companion object {
val SPI_SERVICE_LOADER_LOGGER: MiraiLogger
val SPI_SERVICE_LOADER_LOGGER: MiraiLogger by lazy {
MiraiLogger.Factory.create(SpiServiceLoader::class, "spi-service-loader")
}
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:OptIn(MiraiExperimentalApi::class)
package net.mamoe.mirai.spi
import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiLogger
import java.util.*
import kotlin.reflect.KClass
internal actual class SPIServiceLoader<T : BaseService> actual constructor(
private val defaultService: T,
private val serviceType: KClass<T>
) {
actual var service: T = defaultService
actual fun reload() {
val loader = ServiceLoader.load(serviceType.java)
service = loader.minByOrNull { it.priority } ?: defaultService
}
init {
reload()
}
actual companion object {
actual val SPI_SERVICE_LOADER_LOGGER: MiraiLogger by lazy {
MiraiLogger.Factory.create(SPIServiceLoader::class, "spi-service-loader")
}
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:OptIn(MiraiExperimentalApi::class)
package net.mamoe.mirai.spi
import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.loadService
import kotlin.reflect.KClass
internal actual class SPIServiceLoader<T : BaseService> actual constructor(
defaultService: T,
private val serviceType: KClass<T>
) {
actual var service: T = defaultService
actual fun reload() {
service = loadService(serviceType) { service }
}
init {
reload()
}
actual companion object {
actual val SPI_SERVICE_LOADER_LOGGER: MiraiLogger by lazy {
MiraiLogger.Factory.create(SPIServiceLoader::class, "spi-service-loader")
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -109,7 +109,7 @@ internal class FriendImpl(
override fun toString(): String = "Friend($id)"
override suspend fun uploadAudio(resource: ExternalResource): OfflineAudio = AudioToSilkService.convert(
override suspend fun uploadAudio(resource: ExternalResource): OfflineAudio = AudioToSilkService.instance.convert(
resource
).useAutoClose { res ->

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -311,7 +311,7 @@ internal abstract class CommonGroupImpl constructor(
@Deprecated("use uploadAudio", replaceWith = ReplaceWith("uploadAudio(resource)"), level = DeprecationLevel.HIDDEN)
@Suppress("OverridingDeprecatedMember", "DEPRECATION", "DEPRECATION_ERROR")
override suspend fun uploadVoice(resource: ExternalResource): net.mamoe.mirai.message.data.Voice =
AudioToSilkService.convert(
AudioToSilkService.instance.convert(
resource
).useAutoClose { res ->
return bot.network.run {
@ -359,7 +359,7 @@ internal abstract class CommonGroupImpl constructor(
}.getOrThrow()
}
override suspend fun uploadAudio(resource: ExternalResource): OfflineAudio = AudioToSilkService.convert(
override suspend fun uploadAudio(resource: ExternalResource): OfflineAudio = AudioToSilkService.instance.convert(
resource
).useAutoClose { res ->
return bot.network.run {