[1.20.x] [All] Feat: Delegates listeners by emyfops · Pull Request #58 · lambda-client/lambda · GitHub
Skip to content
137 changes: 119 additions & 18 deletions common/src/main/kotlin/com/lambda/event/EventFlow.kt
34 changes: 15 additions & 19 deletions common/src/main/kotlin/com/lambda/event/Subscriber.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,34 @@ import kotlin.reflect.KClass
*
* @property defaultListenerSet A [ConcurrentSkipListSet] of [Listener]s, sorted in reverse order.
*/
class Subscriber : ConcurrentHashMap<KClass<*>, ConcurrentSkipListSet<Listener>>() {
val defaultListenerSet: ConcurrentSkipListSet<Listener>
get() = ConcurrentSkipListSet(Comparator.reverseOrder())
class Subscriber : ConcurrentHashMap<KClass<out Event>, ConcurrentSkipListSet<Listener<out Event>>>() {
val defaultListenerSet: ConcurrentSkipListSet<Listener<out Event>>
get() = ConcurrentSkipListSet(Listener.comparator.reversed())


/** Allows a [Listener] to start receiving a specific type of [Event] */
inline fun <reified T : Event> subscribe(listener: Listener) =
inline fun <reified T : Event> subscribe(listener: Listener<T>) =
getOrPut(T::class) { defaultListenerSet }.add(listener)


/** Forgets about every [Listener]s association to [eventType] */
fun unsubscribe(eventType: KClass<*>) = remove(eventType)

/** Allows a [Listener] to stop receiving a specific type of [Event] */
fun unsubscribe(listener: Listener) {
values.forEach { listeners ->
listeners.remove(listener)
}
}

/** Allows a [Subscriber] to start receiving all [Event]s of another [Subscriber]. */
infix fun subscribe(subscriber: Subscriber) {
subscriber.forEach { (eventType, listeners) ->
getOrPut(eventType) { defaultListenerSet }.addAll(listeners)
}
}

/** Forgets about every [Listener]'s association to [eventType] */
fun <T : Event> unsubscribe(eventType: KClass<T>) =
remove(eventType)

/** Allows a [Listener] to stop receiving a specific type of [Event] */
inline fun <reified T : Event> unsubscribe(listener: Listener<T>) =
getOrElse(T::class) { defaultListenerSet }.remove(listener)

/** Allows a [Subscriber] to stop receiving all [Event]s of another [Subscriber] */
infix fun unsubscribe(subscriber: Subscriber) {
entries.removeAll { (eventType, listeners) ->
subscriber[eventType]?.let { listeners.removeAll(it) }
listeners.isEmpty()
subscriber.forEach { (eventType, listeners) ->
getOrElse(eventType) { defaultListenerSet }.removeAll(listeners)
}
}
}
}
26 changes: 11 additions & 15 deletions common/src/main/kotlin/com/lambda/event/listener/Listener.kt
Loading