From 461389487ab63cdd3e096f88cc2ff49d71be94c1 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Sat, 22 Jun 2024 16:06:52 +0300 Subject: [PATCH 1/6] Fix clear-smoke memory leaks (thanks @Bumber64 for the help!) --- changelog.txt | 1 + clear-smoke.lua | 23 +++++++++++------------ docs/clear-smoke.rst | 1 - 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/changelog.txt b/changelog.txt index d21bd28bcd..cb397215b3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -56,6 +56,7 @@ Template for new versions: - `quickfort`: allow farm plots to be built on muddy stone - `suspend`: remove broken ``--onlyblocking`` option; restore functionality to ``suspend all`` - `gui/create-item`: allow creation of adamantine thread, wool, and yarn +- `clear-smoke`: fix memory leak caused by the smoke flow not being deleted from memory ## Misc Improvements - `gui/launcher`: "space space to toggle pause" behavior is skipped if the game was paused when `gui/launcher` came up to prevent accidental unpausing diff --git a/clear-smoke.lua b/clear-smoke.lua index 987ab40365..ef12dab44b 100644 --- a/clear-smoke.lua +++ b/clear-smoke.lua @@ -1,19 +1,11 @@ --- Removes all smoke from the map - ---[====[ - -clear-smoke -=========== - -Removes all smoke from the map. Note that this can leak memory and should be -used sparingly. - -]====] +local flowsToDelete = {} function clearSmoke(flows) for i = #flows - 1, 0, -1 do - if flows[i].type == df.flow_type.Smoke then + local flow = flows[i] + if flow.type == df.flow_type.Smoke then flows:erase(i) + flowsToDelete[flow] = true end end end @@ -22,4 +14,11 @@ clearSmoke(df.global.flows) for _, block in pairs(df.global.world.map.map_blocks) do clearSmoke(block.flows) + dfhack.maps.enableBlockUpdates(block, true) end + +for flow,_ in pairs(flowsToDelete) do + if flow then + flow:delete() + end +end \ No newline at end of file diff --git a/docs/clear-smoke.rst b/docs/clear-smoke.rst index 58f49a8274..403efd8ed3 100644 --- a/docs/clear-smoke.rst +++ b/docs/clear-smoke.rst @@ -5,7 +5,6 @@ clear-smoke :summary: Removes all smoke from the map. :tags: fort armok fps map -Note that this can leak memory and should be used sparingly. Usage ----- From 2f2677e8d03f04c94449574072f41a393dda5538 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Sat, 22 Jun 2024 16:08:18 +0300 Subject: [PATCH 2/6] funny newline --- clear-smoke.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clear-smoke.lua b/clear-smoke.lua index ef12dab44b..e98f83c3b2 100644 --- a/clear-smoke.lua +++ b/clear-smoke.lua @@ -21,4 +21,4 @@ for flow,_ in pairs(flowsToDelete) do if flow then flow:delete() end -end \ No newline at end of file +end From 15788a461c33490f5502a4ee7d339a3b3c7c1a09 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Sat, 22 Jun 2024 16:27:02 +0300 Subject: [PATCH 3/6] Update the block only if clearing smoke was a success --- clear-smoke.lua | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/clear-smoke.lua b/clear-smoke.lua index e98f83c3b2..13f5362a94 100644 --- a/clear-smoke.lua +++ b/clear-smoke.lua @@ -1,24 +1,28 @@ -local flowsToDelete = {} +local flows_to_delete = {} function clearSmoke(flows) + local success for i = #flows - 1, 0, -1 do local flow = flows[i] if flow.type == df.flow_type.Smoke then flows:erase(i) - flowsToDelete[flow] = true + flows_to_delete[flow] = true + success = true end end + return success end clearSmoke(df.global.flows) -for _, block in pairs(df.global.world.map.map_blocks) do - clearSmoke(block.flows) - dfhack.maps.enableBlockUpdates(block, true) +for _,block in pairs(df.global.world.map.map_blocks) do + if clearSmoke(block.flows) then + dfhack.maps.enableBlockUpdates(block, true) + end end -for flow,_ in pairs(flowsToDelete) do +for flow,_ in pairs(flows_to_delete) do if flow then flow:delete() end -end +end \ No newline at end of file From 3e9dd28a1fc71a1b19b0141f952c03c3fd07e9ea Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Mon, 24 Jun 2024 15:37:39 +0300 Subject: [PATCH 4/6] implement @Bumber64 code add to module --- clear-smoke.lua | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/clear-smoke.lua b/clear-smoke.lua index 13f5362a94..cb5d0e7747 100644 --- a/clear-smoke.lua +++ b/clear-smoke.lua @@ -1,28 +1,37 @@ -local flows_to_delete = {} +--@module = true -function clearSmoke(flows) - local success - for i = #flows - 1, 0, -1 do - local flow = flows[i] - if flow.type == df.flow_type.Smoke then - flows:erase(i) - flows_to_delete[flow] = true - success = true - end +function removeFlow(flow) --have DF remove the flow + if not flow then + return end - return success -end + flow.flags.DEAD = true -clearSmoke(df.global.flows) + local block = dfhack.maps.getTileBlock(flow.pos) + if block then + block.flow_pool.flags.active = true + else + df.global.world.orphaned_flow_pool.flags.active = true + end +end -for _,block in pairs(df.global.world.map.map_blocks) do - if clearSmoke(block.flows) then - dfhack.maps.enableBlockUpdates(block, true) +function removeFlows(flow_type) --remove all if flow_type is nil + local count = 0 + for _,flow in ipairs(df.global.flows) do + if not flow.flags.DEAD and (flow_type == nil or flow.type == flow_type) then + removeFlow(flow) + count = count + 1 + end end + + return count end -for flow,_ in pairs(flows_to_delete) do - if flow then - flow:delete() +function clearSmoke() + if dfhack.isWorldLoaded() then + print(('%d smoke flows removed.'):format(removeFlows(df.flow_type.Smoke))) + else + qerror('World not loaded!') end -end \ No newline at end of file +end + +clearSmoke() \ No newline at end of file From 7f73b9d64f01daf2460533a39563449146eebe96 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 22:14:22 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- clear-smoke.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clear-smoke.lua b/clear-smoke.lua index cb5d0e7747..79cf7e4797 100644 --- a/clear-smoke.lua +++ b/clear-smoke.lua @@ -34,4 +34,4 @@ function clearSmoke() end end -clearSmoke() \ No newline at end of file +clearSmoke() From c07a432f22776741d661fc6c4508f0d649f6290a Mon Sep 17 00:00:00 2001 From: Myk Date: Mon, 24 Jun 2024 15:16:38 -0700 Subject: [PATCH 6/6] Update clear-smoke.lua --- clear-smoke.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clear-smoke.lua b/clear-smoke.lua index 79cf7e4797..ee3b82c017 100644 --- a/clear-smoke.lua +++ b/clear-smoke.lua @@ -34,4 +34,6 @@ function clearSmoke() end end -clearSmoke() +if not dfhack_flags.module then + clearSmoke() +end