Created
May 17, 2019 15:34
-
-
Save Proximyst/1883d35bed861f3d93a3c0b997088521 to your computer and use it in GitHub Desktop.
overengineered events for discord4j lol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.proximyst.eisaku.eventhandling.framework | |
import com.proximyst.eisaku.Main | |
import discord4j.core.event.domain.Event | |
import kotlin.reflect.KClass | |
import kotlin.reflect.full.companionObject | |
object EventHandler { | |
val handlers = mutableListOf<EventHandlerClassWrapper<*>>() | |
fun fireEvent(event: Event) { | |
handlers | |
.mapNotNull { it.listeners[event.javaClass.kotlin] } | |
.flatten() | |
.forEach { it(event) } | |
} | |
fun <T : Any> register(companion: KClass<out EventHandlerClass<T>>, instance: T) { | |
if (!companion.isCompanion) { | |
throw IllegalArgumentException("A companion was not given where one is required") | |
} | |
val owner = companion.java.enclosingClass.kotlin | |
// Good measure, right? | |
if (owner.companionObject != companion) { | |
throw IllegalStateException() | |
} | |
handlers.add(EventHandlerClassWrapper(owner, instance)) | |
} | |
inline fun <reified T : EventHandlerClass<O>, O : Any> register(instance: O) = | |
register(T::class, instance) | |
class DiscordEventListener<T : Event> { | |
private fun subscriber(event: T) { | |
fireEvent(event) | |
} | |
private fun register(kclass: KClass<T>) { | |
if (listeners.add(this)) { | |
Main.discordClient.eventDispatcher | |
.on(kclass.java) | |
.subscribe { subscriber(it) } | |
} | |
} | |
companion object { | |
private val listeners = mutableSetOf<DiscordEventListener<*>>() | |
internal fun <T : Event> handleEventType(kclass: KClass<T>) { | |
DiscordEventListener<T>().register(kclass) | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.proximyst.eisaku.eventhandling.framework | |
interface EventHandlerClass<T: Any> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.proximyst.eisaku.eventhandling.framework | |
import discord4j.core.event.domain.Event | |
import kotlin.reflect.KClass | |
import kotlin.reflect.KFunction | |
import kotlin.reflect.full.declaredMemberFunctions | |
import kotlin.reflect.full.findAnnotation | |
import kotlin.reflect.full.valueParameters | |
class EventHandlerClassWrapper<T: Any>( | |
val kclass: KClass<*>, | |
val instance: T | |
) { | |
val listeners by lazy { | |
val map = mutableMapOf<KClass<out Event>, MutableList<EventListenerWrapper<T>>>() | |
.withDefault { mutableListOf() } | |
for (func in kclass.declaredMemberFunctions) { | |
if (func.findAnnotation<EventListener>() == null | |
|| func.returnType.classifier != Unit::class | |
) { | |
continue | |
} | |
val eventType = func.valueParameters.firstOrNull() | |
?.type?.classifier as? KClass<out Event> | |
?: continue | |
map[eventType] = map[eventType]!!.also { | |
it.add( | |
EventListenerWrapper( | |
func as KFunction<Unit>, eventType, instance | |
) | |
) | |
} | |
} | |
map.keys.forEach { EventHandler.DiscordEventListener.handleEventType(it) } | |
map | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.proximyst.eisaku.eventhandling.framework | |
@Retention(AnnotationRetention.RUNTIME) | |
@Target(AnnotationTarget.FUNCTION) | |
annotation class EventListener |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.proximyst.eisaku.eventhandling.framework | |
import discord4j.core.event.domain.Event | |
import kotlinx.coroutines.GlobalScope | |
import kotlinx.coroutines.launch | |
import kotlin.reflect.KClass | |
import kotlin.reflect.KFunction | |
import kotlin.reflect.full.callSuspend | |
class EventListenerWrapper<T: Any>( | |
val method: KFunction<Unit>, | |
val eventType: KClass<out Event>, | |
val instance: T | |
) { | |
operator fun invoke(event: Event) { | |
if (!eventType.java.isInstance(event)) { | |
return | |
} | |
if (method.isSuspend) { | |
GlobalScope.launch { | |
method.callSuspend(instance, event) | |
} | |
} else { | |
method.call(instance, event) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment