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

GatewayEventInterceptor customization #391

Merged
merged 15 commits into from
Sep 28, 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
19 changes: 15 additions & 4 deletions core/src/main/kotlin/Kord.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import dev.kord.core.event.Event
import dev.kord.core.exception.EntityNotFoundException
import dev.kord.core.exception.KordInitializationException
import dev.kord.core.gateway.MasterGateway
import dev.kord.core.gateway.handler.DefaultGatewayEventInterceptor
import dev.kord.core.gateway.handler.GatewayEventInterceptor
import dev.kord.core.gateway.start
import dev.kord.core.supplier.*
Expand Down Expand Up @@ -53,8 +54,12 @@ class Kord(
val selfId: Snowflake,
private val eventFlow: MutableSharedFlow<Event>,
dispatcher: CoroutineDispatcher,
interceptorBuilder: () -> GatewayEventInterceptor = {
DefaultGatewayEventInterceptor(cache)
}
) : CoroutineScope {
private val interceptor = GatewayEventInterceptor(this, gateway, cache, eventFlow)

private val interceptor = interceptorBuilder.invoke()

/**
* Global commands made by the bot under this Kord instance.
Expand Down Expand Up @@ -104,7 +109,13 @@ class Kord(
get() = defaultSupplier.guilds

init {
launch { interceptor.start() }
gateway.events
.buffer(kotlinx.coroutines.channels.Channel.UNLIMITED)
.onEach { event ->
val coreEvent = interceptor.handle(event, this)
coreEvent?.let { eventFlow.emit(it) }
}
.launchIn(this)
}

/**
Expand Down Expand Up @@ -595,7 +606,7 @@ suspend inline fun Kord(token: String, builder: KordBuilder.() -> Unit = {}): Ko
*/
inline fun <reified T : Event> Kord.on(scope: CoroutineScope = this, noinline consumer: suspend T.() -> Unit): Job =
events.buffer(CoroutineChannel.UNLIMITED).filterIsInstance<T>()
.onEach {
scope.launch { runCatching { consumer(it) }.onFailure { kordLogger.catching(it) } }
.onEach { event ->
scope.launch(event.coroutineContext) { runCatching { consumer(event) }.onFailure { kordLogger.catching(it) } }
}
.launchIn(scope)
3 changes: 0 additions & 3 deletions core/src/main/kotlin/event/Event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlin.coroutines.CoroutineContext

interface Event : CoroutineScope {
override val coroutineContext: CoroutineContext
get() = kord.coroutineContext

/**
* The Gateway that spawned this event.
*/
Expand Down
51 changes: 41 additions & 10 deletions core/src/main/kotlin/event/channel/ChannelCreateEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,91 @@ package dev.kord.core.event.channel

import dev.kord.core.Kord
import dev.kord.core.entity.channel.*
import dev.kord.core.entity.channel.thread.NewsChannelThread
import dev.kord.core.entity.channel.thread.TextChannelThread
import dev.kord.core.event.Event
import kotlin.coroutines.CoroutineContext

interface ChannelCreateEvent : Event {
val channel: Channel
override val kord: Kord
get() = channel.kord
}

class CategoryCreateEvent(override val channel: Category, override val shard: Int) : ChannelCreateEvent {
class CategoryCreateEvent(
override val channel: Category,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "CategoryCreateEvent(channel=$channel, shard=$shard)"
}
}

class DMChannelCreateEvent(override val channel: DmChannel, override val shard: Int) : ChannelCreateEvent {
class DMChannelCreateEvent(
override val channel: DmChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "DMChannelCreateEvent(channel=$channel, shard=$shard)"
}
}

class NewsChannelCreateEvent(override val channel: NewsChannel, override val shard: Int) : ChannelCreateEvent {
class NewsChannelCreateEvent(
override val channel: NewsChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "NewsChannelCreateEvent(channel=$channel, shard=$shard)"
}
}

class StoreChannelCreateEvent(override val channel: StoreChannel, override val shard: Int) : ChannelCreateEvent {
class StoreChannelCreateEvent(
override val channel: StoreChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "StoreChannelCreateEvent(channel=$channel, shard=$shard)"
}
}

class TextChannelCreateEvent(override val channel: TextChannel, override val shard: Int) : ChannelCreateEvent {
class TextChannelCreateEvent(
override val channel: TextChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "TextChannelCreateEvent(channel=$channel, shard=$shard)"
}
}

class VoiceChannelCreateEvent(override val channel: VoiceChannel, override val shard: Int) : ChannelCreateEvent {
class VoiceChannelCreateEvent(
override val channel: VoiceChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "VoiceChannelCreateEvent(channel=$channel, shard=$shard)"
}
}


class StageChannelCreateEvent(override val channel: StageChannel, override val shard: Int) : ChannelCreateEvent {
class StageChannelCreateEvent(
override val channel: StageChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "StageChannelCreateEvent(channel=$channel, shard=$shard)"
}
}

class UnknownChannelCreateEvent(override val channel: Channel, override val shard: Int) : ChannelCreateEvent {
class UnknownChannelCreateEvent(
override val channel: Channel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "UnknownChannelCreateEvent(channel=$channel, shard=$shard)"
}
Expand Down
52 changes: 41 additions & 11 deletions core/src/main/kotlin/event/channel/ChannelDeleteEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,90 @@ package dev.kord.core.event.channel

import dev.kord.core.Kord
import dev.kord.core.entity.channel.*
import dev.kord.core.entity.channel.thread.DeletedThreadChannel
import dev.kord.core.entity.channel.thread.NewsChannelThread
import dev.kord.core.entity.channel.thread.TextChannelThread
import dev.kord.core.event.Event
import kotlin.coroutines.CoroutineContext

interface ChannelDeleteEvent : Event {
val channel: Channel
override val kord: Kord
get() = channel.kord
}

class CategoryDeleteEvent(override val channel: Category, override val shard: Int) : ChannelDeleteEvent {
class CategoryDeleteEvent(
override val channel: Category,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelDeleteEvent {
override fun toString(): String {
return "CategoryDeleteEvent(channel=$channel, shard=$shard)"
}
}

class DMChannelDeleteEvent(override val channel: DmChannel, override val shard: Int) : ChannelDeleteEvent {
class DMChannelDeleteEvent(
override val channel: DmChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelDeleteEvent {
override fun toString(): String {
return "DMChannelDeleteEvent(channel=$channel, shard=$shard)"
}
}

class NewsChannelDeleteEvent(override val channel: NewsChannel, override val shard: Int) : ChannelDeleteEvent {
class NewsChannelDeleteEvent(
override val channel: NewsChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelDeleteEvent {
override fun toString(): String {
return "NewsChannelDeleteEvent(channel=$channel, shard=$shard)"
}
}

class StoreChannelDeleteEvent(override val channel: StoreChannel, override val shard: Int) : ChannelDeleteEvent {
class StoreChannelDeleteEvent(
override val channel: StoreChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelDeleteEvent {
override fun toString(): String {
return "StoreChannelDeleteEvent(channel=$channel, shard=$shard)"
}
}

class TextChannelDeleteEvent(override val channel: TextChannel, override val shard: Int) : ChannelDeleteEvent {
class TextChannelDeleteEvent(
override val channel: TextChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelDeleteEvent {
override fun toString(): String {
return "TextChannelDeleteEvent(channel=$channel, shard=$shard)"
}
}

class VoiceChannelDeleteEvent(override val channel: VoiceChannel, override val shard: Int) : ChannelDeleteEvent {
class VoiceChannelDeleteEvent(
override val channel: VoiceChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelDeleteEvent {
override fun toString(): String {
return "VoiceChannelDeleteEvent(channel=$channel, shard=$shard)"
}
}

class StageChannelDeleteEvent(override val channel: StageChannel, override val shard: Int) : ChannelDeleteEvent {
class StageChannelDeleteEvent(
override val channel: StageChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelDeleteEvent {
override fun toString(): String {
return "StageChannelDeleteEvent(channel=$channel, shard=$shard)"
}
}

class UnknownChannelDeleteEvent(override val channel: Channel, override val shard: Int) : ChannelCreateEvent {
class UnknownChannelDeleteEvent(
override val channel: Channel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "UnknownChannelDeleteEvent(channel=$channel, shard=$shard)"
}
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/kotlin/event/channel/ChannelPinsUpdateEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import dev.kord.core.supplier.getChannelOf
import dev.kord.core.supplier.getChannelOfOrNull
import kotlinx.datetime.Instant
import kotlinx.datetime.toInstant
import kotlin.coroutines.CoroutineContext

class ChannelPinsUpdateEvent(
val data: ChannelPinsUpdateEventData,
override val kord: Kord,
override val shard: Int,
override val supplier: EntitySupplier = kord.defaultSupplier
override val supplier: EntitySupplier = kord.defaultSupplier,
override val coroutineContext: CoroutineContext = kord.coroutineContext,
) : Event, Strategizable {

val channelId: Snowflake get() = data.channelId
Expand Down
49 changes: 41 additions & 8 deletions core/src/main/kotlin/event/channel/ChannelUpdateEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,90 @@ import dev.kord.core.entity.channel.*
import dev.kord.core.entity.channel.thread.NewsChannelThread
import dev.kord.core.entity.channel.thread.TextChannelThread
import dev.kord.core.event.Event
import kotlin.coroutines.CoroutineContext

interface ChannelUpdateEvent : Event {
val channel: Channel
override val kord: Kord
get() = channel.kord
}

class CategoryUpdateEvent(override val channel: Category, override val shard: Int) : ChannelUpdateEvent {
class CategoryUpdateEvent(
override val channel: Category,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelUpdateEvent {
override fun toString(): String {
return "CategoryUpdateEvent(channel=$channel, shard=$shard)"
}
}

class DMChannelUpdateEvent(override val channel: DmChannel, override val shard: Int) : ChannelUpdateEvent {
class DMChannelUpdateEvent(
override val channel: DmChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelUpdateEvent {
override fun toString(): String {
return "DMChannelUpdateEvent(channel=$channel, shard=$shard)"
}
}

class NewsChannelUpdateEvent(override val channel: NewsChannel, override val shard: Int) : ChannelUpdateEvent {
class NewsChannelUpdateEvent(
override val channel: NewsChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelUpdateEvent {
override fun toString(): String {
return "NewsChannelUpdateEvent(channel=$channel, shard=$shard)"
}
}

class StoreChannelUpdateEvent(override val channel: StoreChannel, override val shard: Int) : ChannelUpdateEvent {
class StoreChannelUpdateEvent(
override val channel: StoreChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelUpdateEvent {
override fun toString(): String {
return "StoreChannelUpdateEvent(channel=$channel, shard=$shard)"
}
}

class TextChannelUpdateEvent(override val channel: TextChannel, override val shard: Int) : ChannelUpdateEvent {
class TextChannelUpdateEvent(
override val channel: TextChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelUpdateEvent {
override fun toString(): String {
return "TextChannelUpdateEvent(channel=$channel, shard=$shard)"
}
}

class VoiceChannelUpdateEvent(override val channel: VoiceChannel, override val shard: Int) : ChannelUpdateEvent {
class VoiceChannelUpdateEvent(
override val channel: VoiceChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelUpdateEvent {
override fun toString(): String {
return "VoiceChannelUpdateEvent(channel=$channel, shard=$shard)"
}
}


class StageChannelUpdateEvent(override val channel: StageChannel, override val shard: Int) : ChannelUpdateEvent {
class StageChannelUpdateEvent(
override val channel: StageChannel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelUpdateEvent {
override fun toString(): String {
return "StageChannelUpdateEvent(channel=$channel, shard=$shard)"
}
}

class UnknownChannelUpdateEvent(override val channel: Channel, override val shard: Int) : ChannelCreateEvent {
class UnknownChannelUpdateEvent(
override val channel: Channel,
override val shard: Int,
override val coroutineContext: CoroutineContext = channel.kord.coroutineContext,
) : ChannelCreateEvent {
override fun toString(): String {
return "UnknownChannelUpdateEvent(channel=$channel, shard=$shard)"
}
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/kotlin/event/channel/TypingStartEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ import dev.kord.core.supplier.getChannelOf
import dev.kord.core.supplier.getChannelOfOrNull
import dev.kord.core.toInstant
import kotlinx.datetime.Instant
import kotlin.coroutines.CoroutineContext

class TypingStartEvent(
val data: TypingStartEventData,
override val kord: Kord,
override val shard: Int,
override val supplier: EntitySupplier = kord.defaultSupplier,
override val coroutineContext: CoroutineContext = kord.coroutineContext,
) : Event, Strategizable {

val channelId: Snowflake get() = data.channelId
Expand Down
Loading