1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-31 18:41:20 +00:00

Merge pull request #107969 from chocola-mint/tile-map-layer-editor-optimize-undo

Reduce TileMapLayerEditor's undo/redo memory usage
This commit is contained in:
Thaddeus Crews
2025-11-14 14:22:48 -06:00
2 changed files with 21 additions and 14 deletions

View File

@@ -52,6 +52,12 @@ TileMapLayer *TileMapLayerSubEditorPlugin::_get_edited_layer() const {
return ObjectDB::get_instance<TileMapLayer>(edited_tile_map_layer_id);
}
void TileMapLayerSubEditorPlugin::_add_to_output_if_tile_changed(HashMap<Vector2i, TileMapCell> &p_output, const TileMapLayer *p_layer, Vector2i p_coords, const TileMapCell &p_cell) {
if (p_cell != p_layer->get_cell(p_coords)) {
p_output[p_coords] = p_cell;
}
}
void TileMapLayerSubEditorPlugin::draw_tile_coords_over_viewport(Control *p_overlay, const TileMapLayer *p_edited_layer, Ref<TileSet> p_tile_set, bool p_show_rectangle_size, const Vector2i &p_rectangle_origin) {
Point2 msgpos = Point2(20 * EDSCALE, p_overlay->get_size().y - 20 * EDSCALE);
String text = String(p_tile_set->local_to_map(p_edited_layer->get_local_mouse_position()));
@@ -1074,7 +1080,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_line(Vector2
// Paint a random tile.
Vector<Vector2i> line = TileMapLayerEditor::get_line(edited_layer, tile_set->local_to_map(p_from_mouse_pos), tile_set->local_to_map(p_to_mouse_pos));
for (int i = 0; i < line.size(); i++) {
output.insert(line[i], _pick_random_tile(pattern));
_add_to_output_if_tile_changed(output, edited_layer, line[i], _pick_random_tile(pattern));
}
} else {
// Paint the pattern.
@@ -1091,7 +1097,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_line(Vector2
Vector2i top_left = line[i] * pattern->get_size() + offset;
for (int j = 0; j < used_cells.size(); j++) {
Vector2i coords = tile_set->map_pattern(top_left, used_cells[j], pattern);
output.insert(coords, TileMapCell(pattern->get_cell_source_id(used_cells[j]), pattern->get_cell_atlas_coords(used_cells[j]), pattern->get_cell_alternative_tile(used_cells[j])));
_add_to_output_if_tile_changed(output, edited_layer, coords, TileMapCell(pattern->get_cell_source_id(used_cells[j]), pattern->get_cell_atlas_coords(used_cells[j]), pattern->get_cell_alternative_tile(used_cells[j])));
}
}
}
@@ -1131,7 +1137,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_rect(Vector2
for (int x = 0; x < rect.size.x; x++) {
for (int y = 0; y < rect.size.y; y++) {
Vector2i coords = rect.position + Vector2i(x, y);
output.insert(coords, _pick_random_tile(pattern));
_add_to_output_if_tile_changed(output, edited_layer, coords, _pick_random_tile(pattern));
}
}
} else {
@@ -1143,7 +1149,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_rect(Vector2
for (int j = 0; j < used_cells.size(); j++) {
Vector2i coords = pattern_coords + used_cells[j];
if (rect.has_point(coords)) {
output.insert(coords, TileMapCell(pattern->get_cell_source_id(used_cells[j]), pattern->get_cell_atlas_coords(used_cells[j]), pattern->get_cell_alternative_tile(used_cells[j])));
_add_to_output_if_tile_changed(output, edited_layer, coords, TileMapCell(pattern->get_cell_source_id(used_cells[j]), pattern->get_cell_atlas_coords(used_cells[j]), pattern->get_cell_alternative_tile(used_cells[j])));
}
}
}
@@ -1194,16 +1200,16 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_bucket_fill(
(source_cell.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) {
if (!p_erase && random_tile_toggle->is_pressed()) {
// Paint a random tile.
output.insert(coords, _pick_random_tile(pattern));
_add_to_output_if_tile_changed(output, edited_layer, coords, _pick_random_tile(pattern));
} else {
// Paint the pattern.
Vector2i pattern_coords = (coords - p_coords) % pattern->get_size(); // Note: it would be good to have posmodv for Vector2i.
pattern_coords.x = pattern_coords.x < 0 ? pattern_coords.x + pattern->get_size().x : pattern_coords.x;
pattern_coords.y = pattern_coords.y < 0 ? pattern_coords.y + pattern->get_size().y : pattern_coords.y;
if (pattern->has_cell(pattern_coords)) {
output.insert(coords, TileMapCell(pattern->get_cell_source_id(pattern_coords), pattern->get_cell_atlas_coords(pattern_coords), pattern->get_cell_alternative_tile(pattern_coords)));
_add_to_output_if_tile_changed(output, edited_layer, coords, TileMapCell(pattern->get_cell_source_id(pattern_coords), pattern->get_cell_atlas_coords(pattern_coords), pattern->get_cell_alternative_tile(pattern_coords)));
} else {
output.insert(coords, TileMapCell());
_add_to_output_if_tile_changed(output, edited_layer, coords, TileMapCell());
}
}
@@ -1240,16 +1246,16 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTilesPlugin::_draw_bucket_fill(
(source_cell.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) {
if (!p_erase && random_tile_toggle->is_pressed()) {
// Paint a random tile.
output.insert(coords, _pick_random_tile(pattern));
_add_to_output_if_tile_changed(output, edited_layer, coords, _pick_random_tile(pattern));
} else {
// Paint the pattern.
Vector2i pattern_coords = (coords - p_coords) % pattern->get_size(); // Note: it would be good to have posmodv for Vector2i.
pattern_coords.x = pattern_coords.x < 0 ? pattern_coords.x + pattern->get_size().x : pattern_coords.x;
pattern_coords.y = pattern_coords.y < 0 ? pattern_coords.y + pattern->get_size().y : pattern_coords.y;
if (pattern->has_cell(pattern_coords)) {
output.insert(coords, TileMapCell(pattern->get_cell_source_id(pattern_coords), pattern->get_cell_atlas_coords(pattern_coords), pattern->get_cell_alternative_tile(pattern_coords)));
_add_to_output_if_tile_changed(output, edited_layer, coords, TileMapCell(pattern->get_cell_source_id(pattern_coords), pattern->get_cell_atlas_coords(pattern_coords), pattern->get_cell_alternative_tile(pattern_coords)));
} else {
output.insert(coords, TileMapCell());
_add_to_output_if_tile_changed(output, edited_layer, coords, TileMapCell());
}
}
}
@@ -2522,7 +2528,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_terrain_p
for (const KeyValue<Vector2i, TileSet::TerrainsPattern> &kv : terrain_fill_output) {
if (painted_set.has(kv.key)) {
// Paint a random tile with the correct terrain for the painted path.
output[kv.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value);
_add_to_output_if_tile_changed(output, edited_layer, kv.key, tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value));
} else {
// Avoids updating the painted path from the output if the new pattern is the same as before.
TileSet::TerrainsPattern in_map_terrain_pattern = TileSet::TerrainsPattern(*tile_set, p_terrain_set);
@@ -2539,7 +2545,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_terrain_p
}
}
if (in_map_terrain_pattern != kv.value) {
output[kv.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value);
_add_to_output_if_tile_changed(output, edited_layer, kv.key, tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value));
}
}
}
@@ -2569,7 +2575,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_terrain_p
for (const KeyValue<Vector2i, TileSet::TerrainsPattern> &kv : terrain_fill_output) {
if (painted_set.has(kv.key)) {
// Paint a random tile with the correct terrain for the painted path.
output[kv.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value);
_add_to_output_if_tile_changed(output, edited_layer, kv.key, tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value));
} else {
// Avoids updating the painted path from the output if the new pattern is the same as before.
TileSet::TerrainsPattern in_map_terrain_pattern = TileSet::TerrainsPattern(*tile_set, p_terrain_set);
@@ -2586,7 +2592,7 @@ HashMap<Vector2i, TileMapCell> TileMapLayerEditorTerrainsPlugin::_draw_terrain_p
}
}
if (in_map_terrain_pattern != kv.value) {
output[kv.key] = tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value);
_add_to_output_if_tile_changed(output, edited_layer, kv.key, tile_set->get_random_tile_from_terrains_pattern(p_terrain_set, kv.value));
}
}
}

View File

@@ -55,6 +55,7 @@ class TileMapLayerSubEditorPlugin : public Object {
protected:
ObjectID edited_tile_map_layer_id;
TileMapLayer *_get_edited_layer() const;
static void _add_to_output_if_tile_changed(HashMap<Vector2i, TileMapCell> &p_output, const TileMapLayer *p_layer, Vector2i p_coords, const TileMapCell &p_cell);
public:
struct TabData {