1717
1818package com.lambda.event.listener
1919
20+ import com.lambda.context.SafeContext
2021import com.lambda.event.Event
2122import com.lambda.event.EventFlow
2223import com.lambda.event.Muteable
@@ -31,6 +32,7 @@ import kotlinx.coroutines.CoroutineDispatcher
3132import kotlinx.coroutines.Dispatchers
3233import kotlin.properties.ReadOnlyProperty
3334import kotlin.properties.ReadWriteProperty
35+ import kotlin.reflect.KClass
3436import kotlin.reflect.KProperty
3537
3638/* *
@@ -98,7 +100,7 @@ class UnsafeListener<T : Event>(
98100 * // no safe access to player or world
99101 * }
100102 *
101- * listenUnsafe<MyEvent>(priority = 1 ) { event ->
103+ * listenUnsafe<MyEvent>(priority = { 1 } ) { event ->
102104 * println("Unsafe event received before the previous listener: $event")
103105 * }
104106 * ```
@@ -121,6 +123,45 @@ class UnsafeListener<T : Event>(
121123 return listener
122124 }
123125
126+ /* *
127+ * This function registers a new [UnsafeListener] for a generic [Event] type [T] with the given [KClass] instance to circumvent type erasure.
128+ * The [function] is executed on the same thread where the [Event] was dispatched.
129+ * The execution of the [function] is independent of the safety conditions of the context.
130+ * Use this function when you need to listen to an [Event] in a context that is not in-game.
131+ * For only in-game related contexts, use the [SafeListener.listen] function instead.
132+ *
133+ * Usage:
134+ * ```kotlin
135+ * listenUnsafe(MyEvent::class) { event ->
136+ * println("Unsafe event received: $event")
137+ * // no safe access to player or world
138+ * }
139+ *
140+ * listenUnsafe(MyEvent::class, priority = { 1 }) { event ->
141+ * println("Unsafe event received before the previous listener: $event")
142+ * }
143+ * ```
144+ *
145+ * @param kClass The KClass instance of covariant type [T] used to circumvent type erasure.
146+ * @param T The type of the event to listen for. This should be a subclass of Event.
147+ * @param priority The priority of the listener. Listeners with higher priority will be executed first.
148+ * @param alwaysListen If true, the listener will be executed even if it is muted.
149+ * @param function The function to be executed when the event is posted. This function should take an event of type T as a parameter.
150+ * @return The newly created and registered [UnsafeListener].
151+ */
152+ fun <T : Event > Any.listenUnsafe (
153+ kClass : KClass <out T >,
154+ priority : () -> Int = ownerPriorityOr0Getter,
155+ alwaysListen : Boolean = false,
156+ function : (T ) -> Unit = {},
157+ ): UnsafeListener <T > {
158+ val listener = UnsafeListener <T >(priority, this , alwaysListen) { function(it) }
159+
160+ EventFlow .syncListeners.subscribe(kClass, listener)
161+
162+ return listener
163+ }
164+
124165 /* *
125166 * Registers a new [UnsafeListener] for a generic [Event] type [T].
126167 * The [function] is executed only once when the [Event] is dispatched.
@@ -183,12 +224,12 @@ class UnsafeListener<T : Event>(
183224 * // no safe access to player or world
184225 * }
185226 *
186- * listenUnsafeConcurrently<MyEvent>(priority = 1 ) { event ->
227+ * listenUnsafeConcurrently<MyEvent>(priority = { 1 } ) { event ->
187228 * println("Concurrent event received before the previous listener: $event")
188229 * }
189230 * ```
190231 * @param T The type of the event to listen for. This should be a subclass of Event.
191- * @param priority The priority of the listener. Listeners with higher priority will be executed first. The Default value is 0 .
232+ * @param priority The priority of the listener. Listeners with higher priority will be executed first. The Default value is { 0 } .
192233 * @param alwaysListen If true, the listener will be executed even if it is muted. The Default value is false.
193234 * @param function The function to be executed when the event is posted. This function should take a SafeContext and an event of type T as parameters.
194235 * @return The newly created and registered [UnsafeListener].
0 commit comments