Commit 9e2b9d86 authored by Setako's avatar Setako

[Add] Event service support ignoreCancelled

parent 52fb8178
......@@ -16,36 +16,44 @@ import kotlin.reflect.KClass
@Component
class ReactantEventService : LifeCycleHook, Listener, EventService {
private val eventPrioritySubjectMap = HashMap<Class<out Event>, HashMap<EventPriority, PublishSubject<Event>>>();
private val listeningEventClasses = HashSet<Class<out Event>>();
/**
* Map which using Pair<EventClass, Boolean> as key, while the Boolean is ignoreCancelled
*/
private val eventPrioritySubjectMap = HashMap<Pair<Class<out Event>, Boolean>, HashMap<EventPriority, PublishSubject<Event>>>();
private val listeningEventClasses = HashSet<Pair<Class<out Event>, Boolean>>();
override fun onDisable() {
HandlerList.unregisterAll(this)
eventPrioritySubjectMap.flatMap { it.value.map { it.value } }.map { it.onComplete() }
}
private fun onEvent(event: Event, priority: EventPriority) {
if (eventPrioritySubjectMap.containsKey(event::class.java)
&& eventPrioritySubjectMap[event::class.java]!!.containsKey(priority)) {
eventPrioritySubjectMap[event::class.java]!![priority]!!.onNext(event)
private fun onEvent(event: Event, ignoreCancelled: Boolean, priority: EventPriority) {
if (eventPrioritySubjectMap.containsKey(event::class.java to ignoreCancelled)
&& eventPrioritySubjectMap[event::class.java to ignoreCancelled]!!.containsKey(priority)) {
eventPrioritySubjectMap[event::class.java to ignoreCancelled]!![priority]!!.onNext(event)
} else {
throw IllegalStateException("Event not listening: ${event::class.qualifiedName}")
}
}
private fun listen(eventClass: Class<out Event>) {
EventPriority.values().forEach { priority ->
Bukkit.getPluginManager().registerEvent(eventClass, this, priority, { _, event -> onEvent(event, priority) }, ReactantCore.instance)
listOf(true, false).forEach { ignoreCancelled ->
Bukkit.getPluginManager().registerEvent(eventClass, this, priority,
{ _, event -> onEvent(event, ignoreCancelled, priority) }, ReactantCore.instance, ignoreCancelled)
}
}
listeningEventClasses.add(eventClass)
}
override fun <T : Event> on(componentRegistrant: Any, eventClass: KClass<T>, eventPriority: EventPriority): Observable<T> {
if (!listeningEventClasses.contains(eventClass.java)) {
override fun <T : Event> on(componentRegistrant: Any, eventClass: KClass<T>,
ignoreCancelled: Boolean, eventPriority: EventPriority): Observable<T> {
if (!listeningEventClasses.contains(eventClass.java to ignoreCancelled)) {
listen(eventClass.java)
}
@Suppress("UNCHECKED_CAST")
return (eventPrioritySubjectMap
.getOrPut(eventClass.java, { HashMap() })
.getOrPut(eventPriority, { PublishSubject.create<Event>() }))
.getOrPut(eventClass.java to ignoreCancelled, { HashMap() })
.getOrPut(eventPriority, { PublishSubject.create() }))
.doOnError { it.printStackTrace() }
as Observable<T>
}
......
......@@ -8,7 +8,7 @@ import kotlin.reflect.KClass
interface EventService : Registrable<EventService.Registering> {
fun <T : Event> on(componentRegistrant: Any, eventClass: KClass<T>,
eventPriority: EventPriority = EventPriority.NORMAL): Observable<T>;
ignoreCancelled: Boolean, eventPriority: EventPriority = EventPriority.NORMAL): Observable<T>;
fun pushEvent(event: Event)
......@@ -20,27 +20,28 @@ interface EventService : Registrable<EventService.Registering> {
inline infix fun <reified T : Event> KClass<T>.listen(eventPriority: EventPriority) = observable(eventPriority)
inline fun <reified T : Event> KClass<T>.observable(eventPriority: EventPriority = EventPriority.NORMAL) =
eventService.on(componentRegistrant, this, eventPriority)
eventService.on(componentRegistrant, this, false, eventPriority)
// Block registering style
inline fun <reified T : Event> KClass<T>.observable(ignoreCancelled: Boolean, eventPriority: EventPriority = EventPriority.NORMAL) =
eventService.on(componentRegistrant, this, ignoreCancelled, eventPriority)
inner class EventRegistering<T : Event>(var eventClass: KClass<T>?,
var eventPriority: EventPriority?,
val consumer: (Observable<T>.() -> Unit)?) {
fun execute() {
eventService.on(componentRegistrant, eventClass!!, eventPriority!!).apply(consumer!!)
eventService.on(componentRegistrant, eventClass!!, false, eventPriority!!).apply(consumer!!)
}
}
@Deprecated("Use EventClass.observable() instead", ReplaceWith(""))
inline operator fun <reified T : Event> KClass<T>.invoke(noinline func: Observable<T>.() -> Unit): Unit =
EventRegistering(this, EventPriority.NORMAL, func).execute()
@Deprecated("Use EventClass.observable() instead", ReplaceWith(""))
inline infix fun <reified T : Event> KClass<T>.priority(eventRegistering: EventRegistering<T>): Unit =
eventRegistering.also { it.eventClass = this }.execute()
@Deprecated("Use EventClass.observable() instead", ReplaceWith(""))
inline operator fun <reified T : Event> EventPriority.invoke(noinline func: Observable<T>.() -> Unit): EventRegistering<T> =
EventRegistering(null, this, func)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment