summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-02-22 14:39:14 +0100
committerRémi Verschelde <rverschelde@gmail.com>2024-02-22 14:39:14 +0100
commitde272fffe95f0dee4b2d13e0172fc52890b2d535 (patch)
treeee555ebcfc4b77de4db05fbd007f4da1a21ae88b
parentcf20bd7a0760ddcff3df4c6e7661fa3fd5949e4c (diff)
parent33485e654e93a84fb01e5201e71da6d062796283 (diff)
downloadredot-engine-de272fffe95f0dee4b2d13e0172fc52890b2d535.tar.gz
Merge pull request #88629 from groud/fix_runtime_update_mem_leak
Fix a memory leak with TileMap runtime updates
-rw-r--r--scene/2d/tile_map_layer.cpp27
-rw-r--r--scene/2d/tile_map_layer.h2
2 files changed, 21 insertions, 8 deletions
diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp
index bc052f9034..8b2542b34e 100644
--- a/scene/2d/tile_map_layer.cpp
+++ b/scene/2d/tile_map_layer.cpp
@@ -1360,6 +1360,7 @@ void TileMapLayer::_build_runtime_update_tile_data() {
if (!forced_cleanup) {
if (tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_use_tile_data_runtime_update) && tile_map_node->GDVIRTUAL_IS_OVERRIDDEN(_tile_data_runtime_update)) {
if (_runtime_update_tile_data_was_cleaned_up || dirty.flags[DIRTY_FLAGS_LAYER_GROUP_TILE_SET]) {
+ _runtime_update_needs_all_cells_cleaned_up = true;
for (KeyValue<Vector2i, CellData> &E : tile_map) {
_build_runtime_update_tile_data_for_cell(E.value);
}
@@ -1414,14 +1415,24 @@ void TileMapLayer::_build_runtime_update_tile_data_for_cell(CellData &r_cell_dat
}
void TileMapLayer::_clear_runtime_update_tile_data() {
- for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
- CellData &cell_data = *cell_data_list_element->self();
-
- // Clear the runtime tile data.
- if (cell_data.runtime_tile_data_cache) {
- memdelete(cell_data.runtime_tile_data_cache);
- cell_data.runtime_tile_data_cache = nullptr;
+ if (_runtime_update_needs_all_cells_cleaned_up) {
+ for (KeyValue<Vector2i, CellData> &E : tile_map) {
+ _clear_runtime_update_tile_data_for_cell(E.value);
}
+ _runtime_update_needs_all_cells_cleaned_up = false;
+ } else {
+ for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) {
+ CellData &r_cell_data = *cell_data_list_element->self();
+ _clear_runtime_update_tile_data_for_cell(r_cell_data);
+ }
+ }
+}
+
+void TileMapLayer::_clear_runtime_update_tile_data_for_cell(CellData &r_cell_data) {
+ // Clear the runtime tile data.
+ if (r_cell_data.runtime_tile_data_cache) {
+ memdelete(r_cell_data.runtime_tile_data_cache);
+ r_cell_data.runtime_tile_data_cache = nullptr;
}
}
@@ -1632,7 +1643,7 @@ void TileMapLayer::_deferred_internal_update() {
void TileMapLayer::_internal_update() {
// Find TileData that need a runtime modification.
- // This may add cells to the dirty list is a runtime modification has been notified.
+ // This may add cells to the dirty list if a runtime modification has been notified.
_build_runtime_update_tile_data();
// Update all subsystems.
diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h
index 6cf432bc24..ac03f3155f 100644
--- a/scene/2d/tile_map_layer.h
+++ b/scene/2d/tile_map_layer.h
@@ -283,7 +283,9 @@ private:
bool _runtime_update_tile_data_was_cleaned_up = false;
void _build_runtime_update_tile_data();
void _build_runtime_update_tile_data_for_cell(CellData &r_cell_data, bool p_auto_add_to_dirty_list = false);
+ bool _runtime_update_needs_all_cells_cleaned_up = false;
void _clear_runtime_update_tile_data();
+ void _clear_runtime_update_tile_data_for_cell(CellData &r_cell_data);
// Per-system methods.
#ifdef DEBUG_ENABLED