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

fix: Resolve issue about the onShutDown function for Live entities #273

Merged
merged 4 commits into from
May 2, 2021
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
13 changes: 10 additions & 3 deletions core/src/main/kotlin/live/LiveGuild.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ import dev.kord.core.event.role.RoleDeleteEvent
import dev.kord.core.event.role.RoleUpdateEvent
import dev.kord.core.event.user.PresenceUpdateEvent
import dev.kord.core.event.user.VoiceStateUpdateEvent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun Guild.live(): LiveGuild = LiveGuild(this)
fun Guild.live(dispatcher: CoroutineDispatcher = Dispatchers.Default): LiveGuild =
LiveGuild(this, dispatcher)

@KordPreview
inline fun Guild.live(block: LiveGuild.() -> Unit) = this.live().apply(block)
inline fun Guild.live(dispatcher: CoroutineDispatcher = Dispatchers.Default, block: LiveGuild.() -> Unit) =
this.live(dispatcher).apply(block)

@KordPreview
fun LiveGuild.onEmojisUpdate(block: suspend (EmojisUpdateEvent) -> Unit) = on(consumer = block)
Expand Down Expand Up @@ -119,7 +123,10 @@ fun LiveGuild.onGuildUpdate(block: suspend (GuildUpdateEvent) -> Unit) = on(cons
fun LiveGuild.onGuildDelete(block: suspend (GuildDeleteEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveGuild(guild: Guild) : AbstractLiveKordEntity(), KordEntity by guild {
class LiveGuild(
guild: Guild,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : AbstractLiveKordEntity(dispatcher), KordEntity by guild {

var guild: Guild = guild
private set
Expand Down
23 changes: 13 additions & 10 deletions core/src/main/kotlin/live/LiveKordEntity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ import dev.kord.core.event.Event
import dev.kord.core.event.message.MessageUpdateEvent
import dev.kord.core.event.message.ReactionAddEvent
import dev.kord.core.kordLogger
import kotlinx.atomicfu.atomic
import kotlinx.atomicfu.update
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlin.coroutines.CoroutineContext

/**
* A Discord entity that only emits events *related* to this entity.
Expand All @@ -22,38 +21,42 @@ import kotlinx.coroutines.sync.withLock
* [reactions][ReactionAddEvent] to that message.
*/
@KordPreview
interface LiveKordEntity : KordEntity {
interface LiveKordEntity : KordEntity, CoroutineScope {
val events: Flow<Event>

fun shutDown()
}

@KordPreview
abstract class AbstractLiveKordEntity : LiveKordEntity {
abstract class AbstractLiveKordEntity(dispatcher: CoroutineDispatcher) : LiveKordEntity {

override val coroutineContext: CoroutineContext = dispatcher + SupervisorJob()

private val mutex = Mutex()
private val running = atomic(true)

@Suppress("EXPERIMENTAL_API_USAGE")
override val events: Flow<Event>
get() = kord.events
.takeWhile { running.value }
.takeWhile { isActive }
.filter { filter(it) }
.onEach { mutex.withLock { update(it) } }

protected abstract fun filter(event: Event): Boolean
protected abstract fun update(event: Event)
override fun shutDown() = running.update { false }

override fun shutDown() {
cancel("Shutdown executed")
}
}

/**
* Convenience method that will invoke the [consumer] on every event [T], the consumer is launched in the given [scope]
* or [Kord] by default and will not propagate any exceptions.
*/
@KordPreview
inline fun <reified T : Event> LiveKordEntity.on(scope: CoroutineScope = kord, noinline consumer: suspend (T) -> Unit) =
inline fun <reified T : Event> LiveKordEntity.on(noinline consumer: suspend (T) -> Unit) =
events.buffer(Channel.UNLIMITED).filterIsInstance<T>().onEach {
runCatching { consumer(it) }.onFailure { kordLogger.catching(it) }
}.catch { kordLogger.catching(it) }.launchIn(scope)
}.catch { kordLogger.catching(it) }.launchIn(this)


12 changes: 9 additions & 3 deletions core/src/main/kotlin/live/LiveMember.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import dev.kord.core.event.guild.GuildDeleteEvent
import dev.kord.core.event.guild.MemberLeaveEvent
import dev.kord.core.event.guild.MemberUpdateEvent
import dev.kord.core.live.channel.LiveGuildChannel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun Member.live() = LiveMember(this)
fun Member.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) = LiveMember(this, dispatcher)

@KordPreview
inline fun Member.live(block: LiveMember.() -> Unit) = this.live().apply(block)
inline fun Member.live(dispatcher: CoroutineDispatcher = Dispatchers.Default, block: LiveMember.() -> Unit) =
this.live(dispatcher).apply(block)

@KordPreview
fun LiveMember.onLeave(block: suspend (MemberLeaveEvent) -> Unit) = on(consumer = block)
Expand All @@ -36,7 +39,10 @@ inline fun LiveGuildChannel.onShutDown(crossinline block: suspend (Event) -> Uni
fun LiveGuildChannel.onGuildDelete(block: suspend (GuildDeleteEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveMember(member: Member) : AbstractLiveKordEntity(), KordEntity by member {
class LiveMember(
member: Member,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : AbstractLiveKordEntity(dispatcher), KordEntity by member {
var member = member
private set

Expand Down
15 changes: 11 additions & 4 deletions core/src/main/kotlin/live/LiveMessage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ import dev.kord.core.event.channel.ChannelDeleteEvent
import dev.kord.core.event.guild.GuildDeleteEvent
import dev.kord.core.event.message.*
import dev.kord.core.supplier.EntitySupplyStrategy
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
suspend fun Message.live() =
LiveMessage(this, withStrategy(EntitySupplyStrategy.cacheWithRestFallback).getGuildOrNull()?.id)
suspend fun Message.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) =
LiveMessage(this, withStrategy(EntitySupplyStrategy.cacheWithRestFallback).getGuildOrNull()?.id, dispatcher)

@KordPreview
suspend fun Message.live(block: LiveMessage.() -> Unit) = this.live().apply(block)
suspend fun Message.live(dispatcher: CoroutineDispatcher = Dispatchers.Default, block: LiveMessage.() -> Unit) =
this.live(dispatcher).apply(block)

@KordPreview
fun LiveMessage.onReactionAdd(block: suspend (ReactionAddEvent) -> Unit) = on(consumer = block)
Expand Down Expand Up @@ -78,7 +81,11 @@ fun LiveMessage.onChannelDelete(block: suspend (ChannelDeleteEvent) -> Unit) = o
fun LiveMessage.onGuildDelete(block: suspend (GuildDeleteEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveMessage(message: Message, val guildId: Snowflake?) : AbstractLiveKordEntity(), KordEntity by message {
class LiveMessage(
message: Message,
val guildId: Snowflake?,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : AbstractLiveKordEntity(dispatcher), KordEntity by message {

var message: Message = message
private set
Expand Down
12 changes: 9 additions & 3 deletions core/src/main/kotlin/live/LiveRole.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import dev.kord.core.event.Event
import dev.kord.core.event.guild.GuildDeleteEvent
import dev.kord.core.event.role.RoleDeleteEvent
import dev.kord.core.event.role.RoleUpdateEvent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun Role.live() = LiveRole(this)
fun Role.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) = LiveRole(this, dispatcher)

@KordPreview
inline fun Role.live(block: LiveRole.() -> Unit) = this.live().apply(block)
inline fun Role.live(dispatcher: CoroutineDispatcher = Dispatchers.Default, block: LiveRole.() -> Unit) =
this.live(dispatcher).apply(block)

@KordPreview
fun LiveRole.onDelete(block: suspend (RoleDeleteEvent) -> Unit) = on(consumer = block)
Expand All @@ -31,7 +34,10 @@ inline fun LiveRole.onShutDown(crossinline block: suspend (Event) -> Unit) = on<
fun LiveRole.onGuildDelete(block: suspend (GuildDeleteEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveRole(role: Role) : AbstractLiveKordEntity(), KordEntity by role {
class LiveRole(
role: Role,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : AbstractLiveKordEntity(dispatcher), KordEntity by role {
var role = role
private set

Expand Down
14 changes: 11 additions & 3 deletions core/src/main/kotlin/live/LiveUser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@ import dev.kord.core.entity.KordEntity
import dev.kord.core.entity.User
import dev.kord.core.event.Event
import dev.kord.core.event.user.UserUpdateEvent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun User.live() = LiveUser(this)
fun User.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) = LiveUser(this, dispatcher)

@KordPreview
inline fun User.live(block: LiveUser.() -> Unit) = this.live().apply(block)
inline fun User.live(
dispatcher: CoroutineDispatcher = Dispatchers.Default,
block: LiveUser.() -> Unit
) = this.live(dispatcher).apply(block)

@KordPreview
fun LiveUser.onUpdate(block: suspend (UserUpdateEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveUser(user: User) : AbstractLiveKordEntity(), KordEntity by user {
class LiveUser(
user: User,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : AbstractLiveKordEntity(dispatcher), KordEntity by user {

var user: User = user
private set
Expand Down
15 changes: 12 additions & 3 deletions core/src/main/kotlin/live/channel/LiveCategory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ import dev.kord.core.event.channel.CategoryDeleteEvent
import dev.kord.core.event.channel.CategoryUpdateEvent
import dev.kord.core.event.guild.GuildDeleteEvent
import dev.kord.core.live.on
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun Category.live() = LiveCategory(this)
fun Category.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) =
LiveCategory(this, dispatcher)

@KordPreview
inline fun Category.live(block: LiveCategory.() -> Unit) = this.live().apply(block)
inline fun Category.live(
dispatcher: CoroutineDispatcher = Dispatchers.Default,
block: LiveCategory.() -> Unit
) = this.live(dispatcher).apply(block)

@KordPreview
fun LiveCategory.onCreate(block: suspend (CategoryCreateEvent) -> Unit) = on(consumer = block)
Expand All @@ -36,7 +42,10 @@ fun LiveCategory.onDelete(block: suspend (CategoryDeleteEvent) -> Unit) = on(con
fun LiveCategory.onGuildDelete(block: suspend (GuildDeleteEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveCategory(channel: Category) : LiveChannel(), KordEntity by channel {
class LiveCategory(
channel: Category,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : LiveChannel(dispatcher), KordEntity by channel {

override var channel: Category = channel
private set
Expand Down
19 changes: 11 additions & 8 deletions core/src/main/kotlin/live/channel/LiveChannel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,22 @@ import dev.kord.core.event.message.*
import dev.kord.core.event.user.VoiceStateUpdateEvent
import dev.kord.core.live.AbstractLiveKordEntity
import dev.kord.core.live.on
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun Channel.live() = when (this) {
is DmChannel -> this.live()
is NewsChannel -> this.live()
is StoreChannel -> this.live()
is TextChannel -> this.live()
is VoiceChannel -> this.live()
fun Channel.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) = when (this) {
is DmChannel -> this.live(dispatcher)
is NewsChannel -> this.live(dispatcher)
is StoreChannel -> this.live(dispatcher)
is TextChannel -> this.live(dispatcher)
is VoiceChannel -> this.live(dispatcher)
else -> error("unsupported channel type")
}

@KordPreview
inline fun Channel.live(block: LiveChannel.() -> Unit) = this.live().apply(block)
inline fun Channel.live(dispatcher: CoroutineDispatcher = Dispatchers.Default, block: LiveChannel.() -> Unit) =
this.live(dispatcher).apply(block)

@KordPreview
fun LiveChannel.onVoiceStateUpdate(block: suspend (VoiceStateUpdateEvent) -> Unit) = on(consumer = block)
Expand Down Expand Up @@ -85,7 +88,7 @@ fun LiveChannel.onGuildCreate(block: suspend (GuildCreateEvent) -> Unit) = on(co
fun LiveChannel.onGuildUpdate(block: suspend (GuildUpdateEvent) -> Unit) = on(consumer = block)

@KordPreview
abstract class LiveChannel : AbstractLiveKordEntity() {
abstract class LiveChannel(dispatcher: CoroutineDispatcher = Dispatchers.Default) : AbstractLiveKordEntity(dispatcher) {

abstract val channel: Channel

Expand Down
14 changes: 11 additions & 3 deletions core/src/main/kotlin/live/channel/LiveDmChannel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@ import dev.kord.core.event.channel.DMChannelDeleteEvent
import dev.kord.core.event.channel.DMChannelUpdateEvent
import dev.kord.core.event.guild.GuildDeleteEvent
import dev.kord.core.live.on
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun DmChannel.live() = LiveDmChannel(this)
fun DmChannel.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) = LiveDmChannel(this, dispatcher)

@KordPreview
inline fun DmChannel.live(block: LiveDmChannel.() -> Unit) = this.live().apply(block)
inline fun DmChannel.live(
dispatcher: CoroutineDispatcher = Dispatchers.Default,
block: LiveDmChannel.() -> Unit
) = this.live(dispatcher).apply(block)

@KordPreview
fun LiveDmChannel.onCreate(block: suspend (DMChannelCreateEvent) -> Unit) = on(consumer = block)
Expand All @@ -36,7 +41,10 @@ fun LiveDmChannel.onDelete(block: suspend (DMChannelDeleteEvent) -> Unit) = on(c
fun LiveDmChannel.onGuildDelete(block: suspend (GuildDeleteEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveDmChannel(channel: DmChannel) : LiveChannel(), KordEntity by channel {
class LiveDmChannel(
channel: DmChannel,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : LiveChannel(dispatcher), KordEntity by channel {

override var channel: DmChannel = channel
private set
Expand Down
15 changes: 12 additions & 3 deletions core/src/main/kotlin/live/channel/LiveGuildChannel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@ import dev.kord.core.event.channel.ChannelDeleteEvent
import dev.kord.core.event.channel.ChannelUpdateEvent
import dev.kord.core.event.guild.GuildDeleteEvent
import dev.kord.core.live.on
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun GuildChannel.live() = LiveGuildChannel(this)
fun GuildChannel.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) =
LiveGuildChannel(this, dispatcher)

@KordPreview
inline fun GuildChannel.live(block: LiveGuildChannel.() -> Unit) = this.live().apply(block)
inline fun GuildChannel.live(
dispatcher: CoroutineDispatcher = Dispatchers.Default,
block: LiveGuildChannel.() -> Unit
) = this.live(dispatcher).apply(block)

@KordPreview
fun LiveGuildChannel.onCreate(block: suspend (ChannelCreateEvent) -> Unit) = on(consumer = block)
Expand All @@ -37,7 +43,10 @@ fun LiveGuildChannel.onDelete(block: suspend (ChannelDeleteEvent) -> Unit) = on(
fun LiveGuildChannel.onGuildDelete(block: suspend (GuildDeleteEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveGuildChannel(channel: GuildChannel) : LiveChannel(), KordEntity by channel {
class LiveGuildChannel(
channel: GuildChannel,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : LiveChannel(dispatcher), KordEntity by channel {

override var channel: GuildChannel = channel
private set
Expand Down
15 changes: 12 additions & 3 deletions core/src/main/kotlin/live/channel/LiveGuildMessageChannel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ import dev.kord.core.event.channel.ChannelDeleteEvent
import dev.kord.core.event.channel.ChannelUpdateEvent
import dev.kord.core.event.guild.GuildDeleteEvent
import dev.kord.core.live.on
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@KordPreview
fun GuildMessageChannel.live() = LiveGuildMessageChannel(this)
fun GuildMessageChannel.live(dispatcher: CoroutineDispatcher = Dispatchers.Default) =
LiveGuildMessageChannel(this, dispatcher)

@KordPreview
inline fun GuildMessageChannel.live(block: LiveGuildMessageChannel.() -> Unit) = this.live().apply(block)
inline fun GuildMessageChannel.live(
dispatcher: CoroutineDispatcher = Dispatchers.Default,
block: LiveGuildMessageChannel.() -> Unit
) = this.live(dispatcher).apply(block)

@KordPreview
fun LiveGuildMessageChannel.onCreate(block: suspend (ChannelCreateEvent) -> Unit) = on(consumer = block)
Expand All @@ -36,7 +42,10 @@ fun LiveGuildMessageChannel.onChannelDelete(block: suspend (ChannelDeleteEvent)
fun LiveGuildMessageChannel.onDelete(block: suspend (GuildDeleteEvent) -> Unit) = on(consumer = block)

@KordPreview
class LiveGuildMessageChannel(channel: GuildMessageChannel) : LiveChannel(), KordEntity by channel {
class LiveGuildMessageChannel(
channel: GuildMessageChannel,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : LiveChannel(dispatcher), KordEntity by channel {

override var channel: GuildMessageChannel = channel
private set
Expand Down
Loading