Entering a common lambda into a card

So, the code below is an event system that performs the following actions:

  • Assign an integer id to a lambda expression
  • Put lambda identifier in mutable event
  • Maps integer identifier to lambda expression
  • Returns an identifier (can be used later to remove events from lambda)

The code is as follows:

class EventHandler {
    companion object {
        val handlers = HashMap<KClass<out Event>, MutableSet<Int>>()
        val idMap = HashMap<Int, (Event) -> Unit>();

        /**
         * @param event     Class of the event you are registering
         * @param handler   What to do when the event is called
         */
        fun <T : Event> register(event: KClass<T>, handler: (T) -> Unit): Int {
            var id: Int = 0;
            while(idMap[id] != null) {
                id++;
            }
            var list = handlers.getOrPut(event, {mutableSetOf()});
            list.add(id);
            idMap[id] = handler;
            return id;
        }
    }
}

The intended use of this method would be something like this:

EventHandler.register(ChatEvent::class) { onChat ->
    println(onChat.message)
}

The following line contains an error: idMap[id] = handler;

The error is due to the fact that the handler has a type (T) -> Unit, although idMapit must be there to add it to it (Event) -> Unit. Although I said that I Tshould expand Eventwhen I created it, so this should not be a problem. Does anyone know why this happens if there is a solution?

+4
3

- , idMap , Event - Event. , Event, , , , . , , .

, , . ...

+4

, , @jacob-zimmerman answer: (T) -> Unit (Event) -> Unit (, ).

unchecked down down :

idMap[id] = handler as (Event) -> Unit

, , , , :

fun invoke(event: Event) {
    val kclass = event.javaClass.kotlin
    val eventHandlers = handlers[kclass]?.map { idMap[it]!! } ?: return
    eventHandlers.forEach { it.invoke(event) }
}
+3

:

class Handlers<T: Event> {
    val backingList = ArrayList<(T) -> Unit>()

    fun add(handler: (T) -> Unit) {
        backingList.add(handler)
    }

    fun remove(handler: (T) -> Unit) {
         backingList.remove(handler)
    }

    fun handleEvent(event: T) {
        backingList.forEach { handle ->
            handle(event)
        }
    }
}

class HandlerMap {
     val handlerMap = HashMap<KClass<out Event>, Handlers<out Event>>()

    fun <T : Event> register(event: KClass<T>, handler: (T) -> Unit) {
        val list: Handlers<T>
        if(!handlerMap.containsKey(event)) {
            list = Handlers<T>()
            handlerMap.put(event, list)
        }
        else {
            list = handlerMap.get(event) as Handlers<T>
        }

        list.add(handler)        
    }

    fun <T: Event> getHandlers(event: KClass<T>): Handlers<T> {
        return handlerMap.get(event) as Handlers<T>
    }
}

- , , , Handlers . - , / "id", , ; , .

+1

All Articles