kotlingenericskotlin-reified-type-parameters

How do I pass a receiver with Generic type Kotlin


I am trying to figure out how to pass a receiver with a Generic type to another function to attempt to implement the necessary functionality within that other function. However, I keep getting a type mismatch error.

What I've tried: Tried turning the generic of the second function to the corresponding type and tried to reify the corresponding generic T as well. I'm scratching my head at this point with the issue. Any help would be appreciated

Error: Type mismatch required T found Player Type mismatch required T found NPC

The problem occurs within the second function where I have the forLoop with the argument function

class EntityFinder {

companion object {

    inline fun<reified T: Entity> forEach(
        radius: Int,
        entityList: List<T>,
        position: Position,
        function: (entity: T) -> Boolean
    ): Boolean {

        return false
    }

    inline fun <reified T : Entity> forEach(
        position: Position,
        radius: Int,
        function: (entity: T) -> Boolean
    ) {
        val radiusChunkSize = ceil((radius / 8.0f).toDouble()).toInt()
        val fullWidth = radiusChunkSize shl 3
        val centerX: Int = position.x
        val centerY: Int = position.y
        val centerZ: Int = position.height
        val checkPlayers = T::class.java.isAssignableFrom(Player::class.java)
        val checkNpcs = T::class.java.isAssignableFrom(NPC::class.java)
        val startX = max(0, centerX - fullWidth)
        val startY = max(0, centerY - fullWidth)
        val endX = max(0x3FFF, centerX + fullWidth)
        val endY = max(0x3FFF, centerY + fullWidth)
        for (x in startX..endX step 8) {
            for (y in startY..endY step 8) {
                val chunk = ChunkManager[Position(x, y, centerZ)] ?: continue
                if (checkPlayers) if (!forEach(radius, chunk.players, position, function)) return
                if (checkNpcs) if (!forEach(radius, chunk.npcs, position, function)) return
            }
        }
    }
}

}


Solution

  • The problem is that even if you check for isAssignableFrom, the compiler is not able to infer anything about T (in subsequent lines). So you will have to cast chunk.players and chunk.npcs yourself. Try this

    if (checkPlayers) if (!forEach(radius, chunk.players as List<T>, position, function)) return
    if (checkNpcs) if (!forEach(radius, chunk.npcs as List<T>, position, function)) return