mirror of
https://github.com/iTracerFacer/Moose_CTLD_Pure.git
synced 2025-12-03 04:11:57 +00:00
All tracked data structures now have proper lifecycle management and will not accumulate indefinitely. The system is production-ready for long-running missions without memory concerns.
This commit is contained in:
parent
9ec7b7ac36
commit
b1a28478c6
108
Moose_CTLD.lua
108
Moose_CTLD.lua
@ -361,7 +361,7 @@ CTLD.Config = {
|
|||||||
-- 2 = INFO - Important state changes, initialization, cleanup (default for production)
|
-- 2 = INFO - Important state changes, initialization, cleanup (default for production)
|
||||||
-- 3 = VERBOSE - Detailed operational info (zone validation, menus, builds, MEDEVAC events)
|
-- 3 = VERBOSE - Detailed operational info (zone validation, menus, builds, MEDEVAC events)
|
||||||
-- 4 = DEBUG - Everything including hover checks, crate pickups, detailed troop spawns
|
-- 4 = DEBUG - Everything including hover checks, crate pickups, detailed troop spawns
|
||||||
LogLevel = 4, -- lowered from DEBUG (4) to INFO (2) for production performance
|
LogLevel = 1, -- lowered from DEBUG (4) to INFO (2) for production performance
|
||||||
MessageDuration = 15, -- seconds for on-screen messages
|
MessageDuration = 15, -- seconds for on-screen messages
|
||||||
|
|
||||||
-- Debug toggles for detailed crate proximity logging (useful when tuning hover coach / ground autoload)
|
-- Debug toggles for detailed crate proximity logging (useful when tuning hover coach / ground autoload)
|
||||||
@ -3460,6 +3460,7 @@ local function _clearPerUnitCachesForGroup(group)
|
|||||||
if CTLD._hoverState then CTLD._hoverState[uname] = nil end
|
if CTLD._hoverState then CTLD._hoverState[uname] = nil end
|
||||||
if CTLD._unitLast then CTLD._unitLast[uname] = nil end
|
if CTLD._unitLast then CTLD._unitLast[uname] = nil end
|
||||||
if CTLD._coachState then CTLD._coachState[uname] = nil end
|
if CTLD._coachState then CTLD._coachState[uname] = nil end
|
||||||
|
if CTLD._groundLoadState then CTLD._groundLoadState[uname] = nil end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -3508,6 +3509,11 @@ function CTLD:_cleanupTransportGroup(group, groupName)
|
|||||||
if mooseGroup then _clearPerUnitCachesForGroup(mooseGroup) end
|
if mooseGroup then _clearPerUnitCachesForGroup(mooseGroup) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Cleanup JTAC registry if this group had JTAC registered
|
||||||
|
if self._jtacRegistry and self._jtacRegistry[gname] then
|
||||||
|
self:_cleanupJTACEntry(gname)
|
||||||
|
end
|
||||||
|
|
||||||
_logDebug(string.format('[MenuCleanup] Cleared CTLD state for group %s', gname))
|
_logDebug(string.format('[MenuCleanup] Cleared CTLD state for group %s', gname))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -5027,6 +5033,12 @@ function CTLD:New(cfg)
|
|||||||
if not ok then _logError('CleanupDeployedTroops scheduler error: '..tostring(err)) end
|
if not ok then _logError('CleanupDeployedTroops scheduler error: '..tostring(err)) end
|
||||||
end, {}, 30, 30)
|
end, {}, 30, 30)
|
||||||
|
|
||||||
|
-- Periodic comprehensive state maintenance (prune orphaned entries)
|
||||||
|
o.StateMaintSched = SCHEDULER:New(nil, function()
|
||||||
|
local ok, err = pcall(function() o:PruneOrphanedState() end)
|
||||||
|
if not ok then _logError('PruneOrphanedState scheduler error: '..tostring(err)) end
|
||||||
|
end, {}, 120, 120) -- Run every 2 minutes
|
||||||
|
|
||||||
-- Optional: auto-build FOBs inside FOB zones when crates present
|
-- Optional: auto-build FOBs inside FOB zones when crates present
|
||||||
if o.Config.AutoBuildFOBInZones then
|
if o.Config.AutoBuildFOBInZones then
|
||||||
o.AutoFOBSched = SCHEDULER:New(nil, function()
|
o.AutoFOBSched = SCHEDULER:New(nil, function()
|
||||||
@ -8504,12 +8516,106 @@ function CTLD:CleanupDeployedTroops()
|
|||||||
if troopMeta.side == self.Side then
|
if troopMeta.side == self.Side then
|
||||||
local troopGroup = GROUP:FindByName(troopGroupName)
|
local troopGroup = GROUP:FindByName(troopGroupName)
|
||||||
if not troopGroup or not troopGroup:IsAlive() then
|
if not troopGroup or not troopGroup:IsAlive() then
|
||||||
|
-- Remove from spatial grid if point is available
|
||||||
|
if troopMeta.point then
|
||||||
|
_removeFromSpatialGrid(troopGroupName, troopMeta.point, 'troops')
|
||||||
|
end
|
||||||
CTLD._deployedTroops[troopGroupName] = nil
|
CTLD._deployedTroops[troopGroupName] = nil
|
||||||
_logDebug('Cleaned up deployed troop group: '..troopGroupName)
|
_logDebug('Cleaned up deployed troop group: '..troopGroupName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Comprehensive state pruning to prevent memory leaks
|
||||||
|
function CTLD:PruneOrphanedState()
|
||||||
|
local pruned = 0
|
||||||
|
|
||||||
|
-- 1. Prune spatial grid entries for non-existent crates/troops
|
||||||
|
for gridKey, cell in pairs(CTLD._spatialGrid) do
|
||||||
|
-- Check crates in this cell
|
||||||
|
for crateName, _ in pairs(cell.crates) do
|
||||||
|
if not CTLD._crates[crateName] then
|
||||||
|
cell.crates[crateName] = nil
|
||||||
|
pruned = pruned + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Check troops in this cell
|
||||||
|
for troopName, _ in pairs(cell.troops) do
|
||||||
|
if not CTLD._deployedTroops[troopName] then
|
||||||
|
cell.troops[troopName] = nil
|
||||||
|
pruned = pruned + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Remove empty cells
|
||||||
|
if not next(cell.crates) and not next(cell.troops) then
|
||||||
|
CTLD._spatialGrid[gridKey] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 2. Prune JTAC registry for non-existent groups
|
||||||
|
if self._jtacRegistry then
|
||||||
|
for gname, _ in pairs(self._jtacRegistry) do
|
||||||
|
local g = Group.getByName(gname)
|
||||||
|
if not g or not g:isExist() then
|
||||||
|
self:_cleanupJTACEntry(gname)
|
||||||
|
pruned = pruned + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 3. Prune hover/coach state for non-existent units
|
||||||
|
local function pruneUnitState(stateTbl, label)
|
||||||
|
if not stateTbl then return end
|
||||||
|
for unitName, _ in pairs(stateTbl) do
|
||||||
|
local u = Unit.getByName(unitName)
|
||||||
|
if not u or not u:isExist() or u:getLife() <= 0 then
|
||||||
|
stateTbl[unitName] = nil
|
||||||
|
pruned = pruned + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pruneUnitState(CTLD._hoverState, 'hover')
|
||||||
|
pruneUnitState(CTLD._coachState, 'coach')
|
||||||
|
pruneUnitState(CTLD._groundLoadState, 'groundLoad')
|
||||||
|
pruneUnitState(CTLD._unitLast, 'unitLast')
|
||||||
|
|
||||||
|
-- 4. Prune group-level state for non-existent groups
|
||||||
|
local function pruneGroupState(stateTbl, label)
|
||||||
|
if not stateTbl then return end
|
||||||
|
for gname, _ in pairs(stateTbl) do
|
||||||
|
local g = GROUP:FindByName(gname)
|
||||||
|
if not g or not g:IsAlive() then
|
||||||
|
stateTbl[gname] = nil
|
||||||
|
pruned = pruned + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pruneGroupState(CTLD._troopsLoaded, 'troopsLoaded')
|
||||||
|
pruneGroupState(CTLD._loadedCrates, 'loadedCrates')
|
||||||
|
pruneGroupState(CTLD._loadedTroopTypes, 'loadedTroopTypes')
|
||||||
|
pruneGroupState(CTLD._buildConfirm, 'buildConfirm')
|
||||||
|
pruneGroupState(CTLD._medevacUnloadStates, 'medevacUnload')
|
||||||
|
pruneGroupState(CTLD._medevacLoadStates, 'medevacLoad')
|
||||||
|
pruneGroupState(CTLD._medevacEnrouteStates, 'medevacEnroute')
|
||||||
|
|
||||||
|
-- 5. Prune _inStockMenus for non-existent groups
|
||||||
|
if CTLD._inStockMenus then
|
||||||
|
for gname, _ in pairs(CTLD._inStockMenus) do
|
||||||
|
local g = GROUP:FindByName(gname)
|
||||||
|
if not g or not g:IsAlive() then
|
||||||
|
CTLD._inStockMenus[gname] = nil
|
||||||
|
pruned = pruned + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if pruned > 0 then
|
||||||
|
_logVerbose(string.format('[StateMaint] Pruned %d orphaned state entries', pruned))
|
||||||
|
end
|
||||||
|
end
|
||||||
-- #endregion Crates
|
-- #endregion Crates
|
||||||
|
|
||||||
-- =========================
|
-- =========================
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user