You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MessageHandler.kt 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package com.dmdirc.ktirc.io
  2. import com.dmdirc.ktirc.IrcClient
  3. import com.dmdirc.ktirc.events.IrcEvent
  4. import com.dmdirc.ktirc.events.handlers.EventHandler
  5. import com.dmdirc.ktirc.events.mutators.EventMutator
  6. import com.dmdirc.ktirc.messages.processors.MessageProcessor
  7. import com.dmdirc.ktirc.model.IrcMessage
  8. import com.dmdirc.ktirc.util.logger
  9. import kotlinx.coroutines.channels.ReceiveChannel
  10. internal interface MessageEmitter {
  11. fun handleEvent(ircClient: IrcClient, ircEvent: IrcEvent, processOnly: Boolean = false) = handleEvents(ircClient, listOf(ircEvent), processOnly)
  12. fun handleEvents(ircClient: IrcClient, ircEvents: List<IrcEvent>, processOnly: Boolean = false)
  13. }
  14. internal class MessageHandler(
  15. processors: List<MessageProcessor>,
  16. private val mutators: List<EventMutator>,
  17. private val handlers: List<EventHandler>) : MessageEmitter {
  18. private val log by logger()
  19. private val emitters = mutableListOf<(IrcEvent) -> Unit>()
  20. private val processorMap = processors.flatMap { it.commands.map { c -> c to it } }.toMap()
  21. suspend fun processMessages(ircClient: IrcClient, messages: ReceiveChannel<IrcMessage>) {
  22. for (message in messages) {
  23. handleEvents(ircClient, message.toEvents())
  24. }
  25. }
  26. override fun handleEvents(ircClient: IrcClient, ircEvents: List<IrcEvent>, processOnly: Boolean) {
  27. val events = if (processOnly) ircEvents else ircEvents.mutate(ircClient)
  28. events.forEach { event ->
  29. event.process(ircClient)
  30. if (!processOnly) {
  31. log.fine { "Dispatching event of type ${event::class}" }
  32. emitters.forEach { it(event) }
  33. }
  34. }
  35. }
  36. fun addEmitter(emitter: (IrcEvent) -> Unit) {
  37. emitters.add(emitter)
  38. }
  39. private fun IrcEvent.process(ircClient: IrcClient) = handlers.forEach { it.processEvent(ircClient, this) }
  40. private fun List<IrcEvent>.mutate(ircClient: IrcClient) = mutators.fold(this) { events, mutator ->
  41. events.flatMap { mutator.mutateEvent(ircClient, this@MessageHandler, it) }
  42. }
  43. private fun IrcMessage.toEvents() = this.getProcessor()?.process(this) ?: emptyList()
  44. private fun IrcMessage.getProcessor() = processorMap[command] ?: run {
  45. log.warning { "No processor found for $command" }
  46. null
  47. }
  48. }