@@ -30,6 +30,7 @@ import kotlinx.coroutines.CoroutineDispatcher
3030import kotlinx.coroutines.Dispatchers
3131import kotlin.properties.ReadOnlyProperty
3232import kotlin.properties.ReadWriteProperty
33+ import kotlin.reflect.KClass
3334import kotlin.reflect.KProperty
3435
3536
@@ -130,6 +131,51 @@ class SafeListener<T : Event>(
130131 return listener
131132 }
132133
134+ /* *
135+ * This function registers a new [SafeListener] for a generic [Event] type [T] with the given [KClass] instance to circumvent type erasure.
136+ * The [function] is executed on the same thread where the [Event] was dispatched.
137+ * The [function] will only be executed when the context satisfies certain safety conditions.
138+ * These conditions are met when none of the following [SafeContext] properties are null:
139+ * - [SafeContext.world]
140+ * - [SafeContext.player]
141+ * - [SafeContext.interaction]
142+ * - [SafeContext.connection]
143+ *
144+ * This typically occurs when the user is in-game.
145+ *
146+ * Usage:
147+ * ```kotlin
148+ * listen(MyEvent::class) { event ->
149+ * player.sendMessage("Event received: $event")
150+ * }
151+ *
152+ * listen(MyEvent::class, priority = 1) { event ->
153+ * player.sendMessage("Event received before the previous listener: $event")
154+ * }
155+ * ```
156+ *
157+ * @param kClass The KClass instance of covariant type [T] used to circumvent type erasure.
158+ * @param T The type of the event to listen for. This should be a subclass of Event.
159+ * @param priority The priority of the listener. Listeners with higher priority will be executed first. The Default value is 0.
160+ * @param alwaysListen If true, the listener will be executed even if it is muted. The Default value is false.
161+ * @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.
162+ * @return The newly created and registered [SafeListener].
163+ */
164+ fun <T : Event > Any.listen (
165+ kClass : KClass <out T >,
166+ priority : Int = 0,
167+ alwaysListen : Boolean = false,
168+ function : SafeContext .(T ) -> Unit = {},
169+ ): SafeListener <T > {
170+ val listener = SafeListener <T >(priority, this , alwaysListen) { event ->
171+ runGameScheduled { function(event) }
172+ }
173+
174+ EventFlow .syncListeners.subscribe(kClass, listener)
175+
176+ return listener
177+ }
178+
133179 /* *
134180 * This function registers a new [SafeListener] for a generic [Event] type [T].
135181 * The [predicate] is executed on the same thread where the [Event] was dispatched.
@@ -176,7 +222,7 @@ class SafeListener<T : Event>(
176222 }
177223 }
178224
179- EventFlow .syncListeners.subscribe< T > (destroyable)
225+ EventFlow .syncListeners.subscribe(destroyable)
180226
181227 return pointer
182228 }
@@ -218,7 +264,7 @@ class SafeListener<T : Event>(
218264 }
219265 }
220266
221- EventFlow .concurrentListeners.subscribe< T > (listener)
267+ EventFlow .concurrentListeners.subscribe(listener)
222268
223269 return listener
224270 }
0 commit comments