Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] Simplify and stabilize BaseService and AudioToSilkService #2658

Merged
merged 3 commits into from
May 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions mirai-core-api/compatibility-validation/android/api/android.api
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions mirai-core-api/compatibility-validation/jvm/api/jvm.api
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 15 additions & 20 deletions mirai-core-api/src/commonMain/kotlin/spi/AudioToSilkService.kt
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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:
Expand All @@ -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
}
}
65 changes: 52 additions & 13 deletions mirai-core-api/src/commonMain/kotlin/spi/SPIServiceLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}


internal fun <T : BaseService> SpiServiceLoader(
serviceType: KClass<T>
): SpiServiceLoader<T?> {
return SpiServiceLoaderImpl(serviceType, null)
}

internal interface SpiServiceLoader<T : BaseService?> {
val service: T
}

fun reload()
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")
}
}
}
42 changes: 0 additions & 42 deletions mirai-core-api/src/jvmBaseMain/kotlin/spi/SPIServiceLoader.kt

This file was deleted.

39 changes: 0 additions & 39 deletions mirai-core-api/src/nativeMain/kotlin/spi/SPIServiceLoader.kt

This file was deleted.

4 changes: 2 additions & 2 deletions mirai-core/src/commonMain/kotlin/contact/FriendImpl.kt
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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 ->

Expand Down
6 changes: 3 additions & 3 deletions mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down