hibiscus/src/main/kotlin/codes/som/hibiscus/api/event/EventBus.kt

44 lines
1.6 KiB
Kotlin

package codes.som.hibiscus.api.event
import codes.som.hibiscus.util.Resettable
import java.util.concurrent.CopyOnWriteArrayList
class EventBus : Resettable {
private val allListeners = mutableMapOf<EventPhase, MutableMap<Class<*>, MutableList<Listener<*>>>>()
inline fun <reified T : Event> register(listener: Listener<T>, phase: EventPhase) {
this.register(T::class.java, listener, phase)
}
inline fun <reified T : Event> register(listener: Listener<T>) {
this.register(T::class.java, listener)
}
fun <T : Event> register(type: Class<T>, listener: Listener<T>, phase: EventPhase = EventPhase.NORMAL) {
val listenerMap = allListeners.getOrPut(phase, ::mutableMapOf)
listenerMap.getOrPut(type, ::CopyOnWriteArrayList).add(listener)
}
inline fun <reified T : Event> unregister(listener: Listener<T>, phase: EventPhase = EventPhase.NORMAL) =
unregister(T::class.java, listener, phase)
fun <T : Event> unregister(type: Class<T>, listener: Listener<T>, phase: EventPhase = EventPhase.NORMAL) {
val listenerMap = allListeners[phase] ?: return
listenerMap[type]?.remove(listener)
}
fun <T : Event> fire(event: T) {
for (phase in EventPhase.values()) {
val listenerMap = allListeners[phase] ?: continue
@Suppress("UNCHECKED_CAST")
val listeners = (listenerMap[event.javaClass] ?: continue) as List<Listener<T>>
listeners.forEach { it.on(event) }
}
}
override fun reset() {
allListeners.clear()
}
}