mirror of
https://github.com/mamoe/mirai.git
synced 2025-05-06 05:45:19 +08:00
[core] Simplify and stabilize BaseService and AudioToSilkService (#2658)
* [core] Simplify and stabilize BaseService and AudioToSilkService * fix * api dump
This commit is contained in:
parent
c57fdd7790
commit
dafa25d611
mirai-core-api
compatibility-validation
src
commonMain/kotlin/spi
jvmBaseMain/kotlin/spi
nativeMain/kotlin/spi
mirai-core/src/commonMain/kotlin/contact
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 ->
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user