Reduce GC pressure when generating dungeons

This commit is contained in:
DBotThePony 2024-12-07 13:27:02 +07:00
parent 3efedd7d22
commit de34b8ac5f
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 58 additions and 28 deletions

View File

@ -130,7 +130,7 @@ class DungeonWorld(
private val boundingBoxes = ArrayList<AABBi>()
fun clearTileEntityAt(x: Int, y: Int) {
clearTileEntitiesAt.add(geometry.wrap(Vector2i(x, y)))
clearTileEntitiesAt.add(geometry.wrap(x, y))
}
fun clearTileEntityAt(position: Vector2i) {
@ -138,7 +138,7 @@ class DungeonWorld(
}
fun isClearingTileEntityAt(x: Int, y: Int): Boolean {
return geometry.wrap(Vector2i(x, y)) in clearTileEntitiesAt
return geometry.wrap(x, y) in clearTileEntitiesAt
}
fun clearTileEntity(entity: TileEntity) {
@ -163,15 +163,15 @@ class DungeonWorld(
}
fun isTouched(x: Int, y: Int): Boolean {
return touchedTiles.contains(geometry.wrap(Vector2i(x, y)))
return touchedTiles.contains(geometry.wrap(x, y))
}
fun touchPlacement(x: Int, y: Int) {
protectTile.add(geometry.wrap(Vector2i(x, y)))
protectTile.add(geometry.wrap(x, y))
}
fun hasPlacement(x: Int, y: Int): Boolean {
return protectTile.contains(geometry.wrap(Vector2i(x, y)))
return protectTile.contains(geometry.wrap(x, y))
}
private val biomeItems = HashSet<Vector2i>(8192, 0.5f)
@ -206,32 +206,32 @@ class DungeonWorld(
}
fun placeObject(x: Int, y: Int, prototype: Registry.Entry<ObjectDefinition>, direction: Direction = Direction.LEFT, parameters: JsonObject = JsonObject()) {
placedObjects[geometry.wrap(Vector2i(x, y))] = PlacedObject(prototype, direction, parameters)
placedObjects[geometry.wrap(x, y)] = PlacedObject(prototype, direction, parameters)
}
fun placeWiring(x: Int, y: Int, group: String, partLocal: Boolean) {
val table = if (partLocal) openLocalWires else globalWires
table.computeIfAbsent(group) { LinkedHashSet() }.add(geometry.wrap(Vector2i(x, y)))
table.computeIfAbsent(group) { LinkedHashSet() }.add(geometry.wrap(x, y))
}
fun placeNPC(x: Int, y: Int, species: Registry.Entry<Species>, type: String, seed: Long, overrides: JsonElement = JsonNull.INSTANCE) {
placedNPCs.computeIfAbsent(geometry.wrap(Vector2i(x, y))) { ArrayList() }.add(NPCData(species, type, seed, overrides))
placedNPCs.computeIfAbsent(geometry.wrap(x, y)) { ArrayList() }.add(NPCData(species, type, seed, overrides))
}
fun placeMonster(x: Int, y: Int, type: Registry.Entry<MonsterTypeDefinition>, seed: Long, overrides: JsonObject = JsonObject()) {
placedMonsters.computeIfAbsent(geometry.wrap(Vector2i(x, y))) { ArrayList() }.add(MonsterData(type, seed, overrides))
placedMonsters.computeIfAbsent(geometry.wrap(x, y)) { ArrayList() }.add(MonsterData(type, seed, overrides))
}
fun requestLiquid(x: Int, y: Int, liquid: AbstractLiquidState) {
pendingLiquids[geometry.wrap(Vector2i(x, y))] = liquid
pendingLiquids[geometry.wrap(x, y)] = liquid
}
fun setDungeonID(x: Int, y: Int, id: Int) {
dungeonIDs[geometry.wrap(Vector2i(x, y))] = id
dungeonIDs[geometry.wrap(x, y)] = id
}
fun setDungeonID(x: Int, y: Int) {
dungeonIDs.remove(geometry.wrap(Vector2i(x, y)))
dungeonIDs.remove(geometry.wrap(x, y))
}
fun setDungeonID(id: Int) {
@ -244,35 +244,35 @@ class DungeonWorld(
}
fun placeBiomeTree(x: Int, y: Int) {
biomeTrees.add(geometry.wrap(Vector2i(x, y)))
biomeTrees.add(geometry.wrap(x, y))
}
fun placeBiomeItems(x: Int, y: Int) {
biomeItems.add(geometry.wrap(Vector2i(x, y)))
biomeItems.add(geometry.wrap(x, y))
}
fun dropItem(x: Int, y: Int, item: ItemDescriptor) {
itemDrops.computeIfAbsent(geometry.wrap(Vector2i(x, y))) { ArrayList() }.add(item)
itemDrops.computeIfAbsent(geometry.wrap(x, y)) { ArrayList() }.add(item)
}
fun dropRandomizedItem(x: Int, y: Int, item: ItemDescriptor) {
randomizedItemDrops.computeIfAbsent(geometry.wrap(Vector2i(x, y))) { ArrayList() }.add(item)
randomizedItemDrops.computeIfAbsent(geometry.wrap(x, y)) { ArrayList() }.add(item)
}
fun setLiquid(x: Int, y: Int, liquid: AbstractLiquidState) {
this.liquid[geometry.wrap(Vector2i(x, y))] = liquid
this.liquid[geometry.wrap(x, y)] = liquid
}
fun getLiquid(x: Int, y: Int): AbstractLiquidState {
return this.liquid[geometry.wrap(Vector2i(x, y))] ?: AbstractLiquidState.EMPTY
return this.liquid[geometry.wrap(x, y)] ?: AbstractLiquidState.EMPTY
}
fun setForeground(x: Int, y: Int, tile: Material) {
this.foregroundMaterial[geometry.wrap(Vector2i(x, y))] = tile
this.foregroundMaterial[geometry.wrap(x, y)] = tile
}
fun setForeground(x: Int, y: Int, tile: Modifier) {
this.foregroundModifier[geometry.wrap(Vector2i(x, y))] = tile
this.foregroundModifier[geometry.wrap(x, y)] = tile
}
fun setForeground(x: Int, y: Int, material: Registry.Entry<TileDefinition>, hueShift: Float = 0f, color: TileColor = TileColor.DEFAULT) {
@ -284,11 +284,11 @@ class DungeonWorld(
}
fun setBackground(x: Int, y: Int, tile: Material) {
this.backgroundMaterial[geometry.wrap(Vector2i(x, y))] = tile
this.backgroundMaterial[geometry.wrap(x, y)] = tile
}
fun setBackground(x: Int, y: Int, tile: Modifier) {
this.backgroundModifier[geometry.wrap(Vector2i(x, y))] = tile
this.backgroundModifier[geometry.wrap(x, y)] = tile
}
fun setBackground(x: Int, y: Int, material: Registry.Entry<TileDefinition>, hueShift: Float = 0f, color: TileColor = TileColor.DEFAULT) {
@ -313,7 +313,7 @@ class DungeonWorld(
setBackgroundMaterial: Boolean = true,
setBackgroundModifier: Boolean = true,
) {
val pos = geometry.wrap(Vector2i(x, y))
val pos = geometry.wrap(x, y)
if (foreground != null) {
if (setForegroundMaterial)
@ -336,7 +336,7 @@ class DungeonWorld(
}
fun clearTile(x: Int, y: Int) {
val pos = geometry.wrap(Vector2i(x, y))
val pos = geometry.wrap(x, y)
this.foregroundMaterial[pos] = emptyMaterial
this.foregroundModifier[pos] = emptyModifier
@ -348,24 +348,24 @@ class DungeonWorld(
}
fun needsForegroundBiomeMod(x: Int, y: Int): Boolean {
val pos = geometry.wrap(Vector2i(x, y))
val pos = geometry.wrap(x, y)
val material = foregroundMaterial[pos] ?: return false
if (material.material !in BuiltinMetaMaterials.BIOME_META_MATERIALS)
return false
val above = geometry.wrap(Vector2i(x, y + 1))
val above = geometry.wrap(x, y + 1)
return foregroundMaterial[above]?.material?.isNotEmptyTile == false
}
fun needsBackgroundBiomeMod(x: Int, y: Int): Boolean {
val pos = geometry.wrap(Vector2i(x, y))
val pos = geometry.wrap(x, y)
val material = backgroundMaterial[pos] ?: return false
if (material.material !in BuiltinMetaMaterials.BIOME_META_MATERIALS)
return false
val above = geometry.wrap(Vector2i(x, y + 1))
val above = geometry.wrap(x, y + 1)
return backgroundMaterial[above]?.material?.isNotEmptyTile == false
}

View File

@ -40,10 +40,40 @@ data class WorldGeometry(val size: Vector2i, val loopX: Boolean = true, val loop
return Vector2i(x.cell(pos.component1()), y.cell(pos.component2()))
}
fun wrap(pos: Vector2i): Vector2i {
val x = this.x.cell(pos.x)
val y = this.y.cell(pos.y)
// avoid allocating heap garbage
if (x == pos.x && y == pos.y)
return pos
return Vector2i(x, y)
}
fun wrap(x: Int, y: Int): Vector2i {
return Vector2i(this.x.cell(x), this.y.cell(y))
}
fun wrap(pos: IStruct2d): Vector2d {
return Vector2d(x.cell(pos.component1()), y.cell(pos.component2()))
}
fun wrap(pos: Vector2d): Vector2d {
val x = this.x.cell(pos.x)
val y = this.y.cell(pos.y)
// avoid allocating heap garbage
if (x == pos.x && y == pos.y)
return pos
return Vector2d(x, y)
}
fun wrap(x: Double, y: Double): Vector2d {
return Vector2d(this.x.cell(x), this.y.cell(y))
}
fun chunkFromCell(pos: IStruct2i): ChunkPos {
return ChunkPos(x.chunkFromCell(pos.component1()), y.chunkFromCell(pos.component2()))
}