exaV / screeps-kotlin-types

Screep's Kotlin type definitions
MIT License
17 stars 18 forks source link

Problems with typed array #42

Closed thigg closed 5 months ago

thigg commented 5 years ago

To be able to supply a list of RoomObjects to findClosestByPath I had to manually map it to the type.

Either I didn't understand very well, how kotlin does typing here, kkotlin messes up the type inference, or this is an issue with the definition.

val targets: Array<RoomObject> = (room.find(FIND_SOURCES) +
            room.find(FIND_DROPPED_ENERGY) +
            room.find(FIND_STRUCTURES).filter { s ->
                when (s.structureType) {
                    STRUCTURE_CONTAINER, STRUCTURE_STORAGE -> true
                    else -> false
                }
            }).map { a -> a as RoomObject }.toTypedArray()
    val target :RoomObject? = pos.findClosestByPath<RoomObject>(targets)
Jomik commented 5 years ago

That's probably because the filter is using Structure and not RoomObject. You can avoid the map, by casting

AWRyder commented 5 years ago

I believe the issue is, as Jomik said, not the cast to typed array but the cast to a typed array using a specific generic. Try adding a generic on find so that you get a collection of the type you want.

find<RoomObject>(...) for example.
thigg commented 5 years ago

No, I tried pos.findClosestByPath<RoomObject>((targets + creepTargets).map { a -> a as RoomObject }.toTypedArray()) and it does not work without the map, at least intellij doesnt like it then.

exaV commented 5 years ago

It does not work out of the box with 1.3.41. The editor does not show an error because it already uses the new type inference algorithm that will become the default in 1.4. The new algorithm is able to figure out the type of the targets array by combining all of the constraints and the result is what you'd expect. To enable new inference for the compiler add this snippet to the kotlinoptions block in your build.gradle:

freeCompilerArgs = listOf("-Xnew-inference")

Afterwards you should be able to write the following:

 val targets : Array<RoomObject> =
                room.find(FIND_SOURCES) +
                room.find(FIND_DROPPED_ENERGY) +
                room.find(FIND_STRUCTURES).filter { s ->
                    when (s.structureType) {
                        STRUCTURE_CONTAINER, STRUCTURE_STORAGE -> true
                        else -> false
                    }
                }
val target :RoomObject? = pos.findClosestByPath(targets)

It is a bit annoying to write the type of targets down. This is an error on our part because pos.findClosestByPath() does not accept a subtype of RoomObject as an argument, even though it should! We'll fix it soon.

exaV commented 5 months ago

this should be fixed with the upgrade to Kotlin 2.0