diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 68455d1e2f..2e759294a3 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -985,7 +985,7 @@ namespace OpenRA Order.Command($"state {Session.ClientState.Ready}") }; - var map = ModData.MapCache.SingleOrDefault(m => m.Uid == launchMap || Path.GetFileName(m.Package.Name) == launchMap); + var map = ModData.MapCache.SingleOrDefault(m => m.Uid == launchMap || Path.GetFileName(m.PackageName) == launchMap); if (map == null) throw new ArgumentException($"Could not find map '{launchMap}'."); diff --git a/OpenRA.Game/Map/MapCache.cs b/OpenRA.Game/Map/MapCache.cs index 12573558d2..05c8fcc170 100644 --- a/OpenRA.Game/Map/MapCache.cs +++ b/OpenRA.Game/Map/MapCache.cs @@ -153,6 +153,9 @@ namespace OpenRA var uid = Map.ComputeUID(mapPackage); previews[uid].UpdateFromMap(mapPackage, package, classification, modData.Manifest.MapCompatibility, mapGrid.Type, modDataRules); + // Freeing the package to save memory if there is a lot of Maps + previews[uid].DisposePackage(); + if (oldMap != uid) { LastModifiedMap = uid; diff --git a/OpenRA.Game/Map/MapDirectoryTracker.cs b/OpenRA.Game/Map/MapDirectoryTracker.cs index ea579960dc..69001cfa5a 100644 --- a/OpenRA.Game/Map/MapDirectoryTracker.cs +++ b/OpenRA.Game/Map/MapDirectoryTracker.cs @@ -86,7 +86,7 @@ namespace OpenRA dirty = false; foreach (var mapAction in mapActionQueue) { - var map = mapcache.FirstOrDefault(x => x.Package?.Name == mapAction.Key && x.Status == MapStatus.Available); + var map = mapcache.FirstOrDefault(x => x.PackageName == mapAction.Key && x.Status == MapStatus.Available); if (map != null) { if (mapAction.Value == MapAction.Delete) diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index 393ad68905..f4c7a53f45 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -174,7 +174,19 @@ namespace OpenRA readonly ModData modData; public readonly string Uid; - public IReadOnlyPackage Package { get; private set; } + public string PackageName { get; private set; } + IReadOnlyPackage package; + public IReadOnlyPackage Package + { + get + { + package ??= parentPackage.OpenPackage(PackageName, modData.ModFiles); + return package; + } + + private set => package = value; + } + IReadOnlyPackage parentPackage; volatile InnerData innerData; @@ -286,7 +298,7 @@ namespace OpenRA cache = modData.MapCache; Uid = map.Uid; - Package = map.Package; + PackageName = map.Package.Name; var mapPlayers = new MapPlayers(map.PlayerDefinitions); var spawns = new List(); @@ -338,7 +350,7 @@ namespace OpenRA yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, $"{p.Name}:map.yaml", stringPool: cache.StringPool)).ToDictionary(); } - Package = p; + PackageName = p.Name; parentPackage = parent; var newData = innerData.Clone(); @@ -587,10 +599,15 @@ namespace OpenRA public void Dispose() { - if (Package != null) + DisposePackage(); + } + + public void DisposePackage() + { + if (package != null) { - Package.Dispose(); - Package = null; + package.Dispose(); + package = null; } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs index 7ce757c78f..f2326fe9f2 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/SaveMapLogic.cs @@ -247,7 +247,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (map.Package?.Name != combinedPath) { // When creating a new map or when file paths don't match - if (modData.MapCache.Any(m => m.Status == MapStatus.Available && m.Package?.Name == combinedPath)) + if (modData.MapCache.Any(m => m.Status == MapStatus.Available && m.PackageName == combinedPath)) { ConfirmationDialogs.ButtonPrompt(modData, title: OverwriteMapFailedTitle, diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index d6a8cfa57b..c45d0af594 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -141,7 +141,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic .Select(p => new { Preview = p, - Index = missionMapPaths.IndexOf(Path.GetFileName(p.Package.Name)) + Index = missionMapPaths.IndexOf(Path.GetFileName(p.PackageName)) }) .Where(x => x.Index != -1) .OrderBy(x => x.Index)