diff --git a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs index 75137fa40f..983b241502 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; +using OpenRA.FileSystem; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; using OpenRA.Widgets; @@ -128,7 +129,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic string selectedUid; readonly Action onSelect; - MapGenerationArgs generatedMap; + MapGenerationArgs generatedMapArgs; + IReadWritePackage generatedMapPackage; string category; string mapFilter; @@ -150,8 +152,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic var approving = new Action(() => { Ui.CloseWindow(); - if (currentTab == MapClassification.Generated && generatedMap != null) - onSelectGenerated?.Invoke(generatedMap); + if (currentTab == MapClassification.Generated && generatedMapArgs != null) + { + // PERF: Add the map directly into the map cache to allow an instant map switch for the local player + var p = modData.MapCache[generatedMapArgs.Uid]; + if (p.Status != MapStatus.Available && generatedMapPackage is ZipFileLoader.ReadWriteZipFile zipPackage) + { + // The original package will be disposed, so take a deep copy + var package = ZipFileLoader.ReadWriteZipFile.FromBase64String(zipPackage.ToBase64String()); + p.UpdateFromMap(package, MapClassification.Generated); + } + + onSelectGenerated?.Invoke(generatedMapArgs); + } else onSelect?.Invoke(selectedUid); }); @@ -160,7 +173,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var okButton = widget.Get("BUTTON_OK"); if (onSelect != null) - okButton.IsDisabled = () => currentTab == MapClassification.Generated && generatedMap == null; + okButton.IsDisabled = () => currentTab == MapClassification.Generated && generatedMapArgs == null; else okButton.Disabled = true; @@ -394,7 +407,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic { { "modData", modData }, { "initialSettings", initialSettings }, - { "onGenerate", (Action)(data => generatedMap = data) } + { + "onGenerate", (Action)((args, package) => + { + generatedMapArgs = args; + generatedMapPackage = package; + }) + } }); } diff --git a/OpenRA.Mods.Common/Widgets/Logic/MapGeneratorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MapGeneratorLogic.cs index 8981b48056..ce65a20846 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MapGeneratorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MapGeneratorLogic.cs @@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly ModData modData; readonly IEditorMapGeneratorInfo generator; readonly IMapGeneratorSettings settings; - readonly Action onGenerate; + readonly Action onGenerate; readonly GeneratedMapPreviewWidget preview; readonly ScrollPanelWidget settingsPanel; @@ -76,6 +76,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly Widget dropdownSettingTemplate; readonly Widget tilesetSetting; readonly Widget sizeSetting; + readonly IReadWritePackage package; ITerrainInfo selectedTerrain; string selectedSize; @@ -85,10 +86,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic volatile bool failed; [ObjectCreator.UseCtor] - internal MapGeneratorLogic(Widget widget, ModData modData, MapGenerationArgs initialSettings, Action onGenerate) + internal MapGeneratorLogic(Widget widget, ModData modData, MapGenerationArgs initialSettings, Action onGenerate) { this.modData = modData; this.onGenerate = onGenerate; + package = new ZipFileLoader.ReadWriteZipFile(); generator = modData.DefaultRules.Actors[SystemActors.EditorWorld].TraitInfos().First(); settings = generator.GetSettings(); @@ -215,7 +217,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (map.Status == MapStatus.Available) { preview.Update(map); - onGenerate(initialSettings); + onGenerate(initialSettings, null); } else GenerateMap(); @@ -385,7 +387,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic void GenerateMap() { generating = true; - onGenerate(null); + onGenerate(null, null); failed = false; preview.Clear(); Task.Run(() => @@ -398,14 +400,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic var map = generator.Generate(modData, args); // Map UID and preview image are generated on save - var package = new ZipFileLoader.ReadWriteZipFile(); map.Save(package); args.Uid = map.Uid; Game.RunAfterTick(() => { preview.Update(map); - onGenerate(args); + onGenerate(args, package); generating = false; }); return; @@ -420,5 +421,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic generating = false; }); } + + bool disposed; + protected override void Dispose(bool disposing) + { + if (disposing && !disposed) + { + disposed = true; + package.Dispose(); + } + + base.Dispose(disposing); + } } }