Advertisement
Guest User

Untitled

a guest
Mar 20th, 2023
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.58 KB | None | 0 0
  1. import com.nomadgcs.data.event.EventPriority
  2. import kotlinx.coroutines.CoroutineScope
  3. import kotlinx.coroutines.Job
  4. import kotlinx.coroutines.flow.MutableSharedFlow
  5. import kotlinx.coroutines.flow.catch
  6. import kotlinx.coroutines.flow.launchIn
  7. import kotlinx.coroutines.flow.onEach
  8. import kotlinx.coroutines.runBlocking
  9. import kotlinx.coroutines.sync.Mutex
  10. import kotlinx.coroutines.sync.withLock
  11. import java.util.*
  12. import kotlin.reflect.KClass
  13.  
  14. fun main(): Unit = runBlocking {
  15.     // Create and register the handler
  16.     val bus = EventRegistrar()
  17.     var event: Any? = null
  18.     val mutex = Mutex(true)
  19.     bus.register(Any::class, EventPriority.NORMAL) {
  20.         println("Called")
  21.         event = it
  22.         mutex.unlock()
  23.     }
  24.     // Call the event
  25.     val testEvent = bus.emit(Any())
  26.     println("Suspending")
  27.     mutex.withLock {
  28.         println("Acquired")
  29.         println(testEvent == event)
  30.     }
  31. }
  32.  
  33. @Suppress("UNCHECKED_CAST")
  34. class EventRegistrar(job: Job = Job()) : Job by job {
  35.  
  36.     private val scope = CoroutineScope(this)
  37.     private val handlers = mutableMapOf<KClass<*>, EnumMap<EventPriority, MutableSharedFlow<*>>>()
  38.  
  39.     fun <T : Any> register(
  40.         type: KClass<T>,
  41.         priority: EventPriority,
  42.         handler: suspend (T) -> Unit
  43.     ): Job {
  44.         println("Registering")
  45.         val job = create(priority, type)
  46.             .onEach(handler)
  47.             .catch { println("Exception caught while handling event for ${type.simpleName}") }
  48.             .launchIn(scope)
  49.         println("Registered")
  50.         return job
  51.     }
  52.  
  53.     suspend fun <T : Any> emit(event: T): T {
  54.         println("Emitting")
  55.         val handlers = handlers[event::class] ?: return event
  56.         // Since we're using an EnumMap, we know that values will always
  57.         // be iterated in the order of the EventPriority declaration
  58.         println("Emitting here")
  59. //        println("Emitting to ${handlers.size}") // << Uncommenting will cause the problem to "fix" itself
  60.         handlers.values.forEach {
  61.             println("Subscribers")
  62.             println("${it.subscriptionCount.value}")
  63. //            println("Subscribers ${it.subscriptionCount.value}") // << Uncommenting will cause the problem to "fix" itself
  64.             (it as MutableSharedFlow<T>).emit(event)
  65.         }
  66.         println("Done")
  67.         return event
  68.     }
  69.  
  70.     private fun <T : Any> create(priority: EventPriority, type: KClass<T>) =
  71.         handlers.getOrPut(type) { EnumMap(EventPriority::class.java) }
  72.             .getOrPut(priority) { MutableSharedFlow<T>() } as MutableSharedFlow<T>
  73. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement