Skip to content

Instantly share code, notes, and snippets.

@abueide
Created September 22, 2021 04:22
Show Gist options
  • Save abueide/4f0b1e4b96368732612f4a7073cf613c to your computer and use it in GitHub Desktop.
Save abueide/4f0b1e4b96368732612f4a7073cf613c to your computer and use it in GitHub Desktop.
class EventService : Service(true) {
// Have to do a MutableList<Any>, then do unsafe cast later. Couldn't think of another way to do it
val subscriptions: MutableMap<KClass<out BaseEvent>, MutableList<Any>> = mutableMapOf()
val packetSubscriptions: MutableMap<KClass<out Packet>, MutableList<Any>> = mutableMapOf()
private val events: ConcurrentLinkedQueue<BaseEvent> = ConcurrentLinkedQueue()
inline fun <reified T : BaseEvent> subscribe(noinline subscriber: (T) -> Unit) {
val event = T::class
subscriptions.getOrPut(event) { mutableListOf() }.add(subscriber)
}
inline fun <reified T : Packet> subscribePacket(noinline subscriber: (T) -> Unit) {
val packet = T::class
packetSubscriptions.getOrPut(packet) { mutableListOf() }.add(subscriber)
}
fun publish(event: BaseEvent) {
events.add(event)
}
private fun <T : BaseEvent> processEvent(event: T) {
if (event is PacketEvent) {
packetSubscriptions.forEach { key, value ->
if(event.packet::class == key){
val castedPacket = key.cast(event.packet)
value.forEach { subscription ->
(subscription as (Packet) -> Unit).invoke(castedPacket)
}
}
}
} else {
subscriptions[event::class]?.forEach {
@Suppress("UNCHECKED_CAST")
(it as (T) -> Unit).invoke(event)
}
}
}
// Clear out the event queue
fun process() {
while (isRunning && events.size > 0) {
processEvent(events.poll())
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment