Combine IMapGenerator interfaces.

This removes the need to instantiate a dummy
trait instance and is more idiomatic.
This commit is contained in:
Paul Chote
2025-03-02 08:39:56 +00:00
committed by Gustas Kažukauskas
parent 7ee79a0e64
commit 23b7b56c28
6 changed files with 29 additions and 62 deletions

View File

@@ -19,9 +19,9 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)] [TraitLocation(SystemActors.EditorWorld)]
[Desc("A map generator that clears a map.")] [Desc("A map generator that clears a map.")]
public sealed class ClearMapGeneratorInfo : TraitInfo, IMapGeneratorInfo public sealed class ClearMapGeneratorInfo : TraitInfo<ClearMapGenerator>, IMapGeneratorInfo
{ {
[FieldLoader.Require] [FieldLoader.Require]
[Desc("Human-readable name this generator uses.")] [Desc("Human-readable name this generator uses.")]
@@ -44,8 +44,6 @@ namespace OpenRA.Mods.Common.Traits
string IMapGeneratorInfo.Name => Name; string IMapGeneratorInfo.Name => Name;
public override object Create(ActorInitializer init) { return new ClearMapGenerator(this); }
static MiniYaml SettingsLoader(MiniYaml my) static MiniYaml SettingsLoader(MiniYaml my)
{ {
return my.NodeWithKey("Settings").Value; return my.NodeWithKey("Settings").Value;
@@ -55,22 +53,10 @@ namespace OpenRA.Mods.Common.Traits
{ {
return MapGeneratorSettings.DumpFluent(my.NodeWithKey("Settings").Value); return MapGeneratorSettings.DumpFluent(my.NodeWithKey("Settings").Value);
} }
}
public sealed class ClearMapGenerator : IMapGenerator
{
readonly ClearMapGeneratorInfo info;
IMapGeneratorInfo IMapGenerator.Info => info;
public ClearMapGenerator(ClearMapGeneratorInfo info)
{
this.info = info;
}
public MapGeneratorSettings GetSettings(Map map) public MapGeneratorSettings GetSettings(Map map)
{ {
return MapGeneratorSettings.LoadSettings(info.Settings, map); return MapGeneratorSettings.LoadSettings(Settings, map);
} }
public void Generate(Map map, MiniYaml settings) public void Generate(Map map, MiniYaml settings)
@@ -112,4 +98,6 @@ namespace OpenRA.Mods.Common.Traits
map.ActorDefinitions = ImmutableArray<MiniYamlNode>.Empty; map.ActorDefinitions = ImmutableArray<MiniYamlNode>.Empty;
} }
} }
public class ClearMapGenerator { /* we're only interested in the Info */ }
} }

View File

@@ -22,8 +22,8 @@ using static OpenRA.Mods.Common.Traits.ResourceLayerInfo;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)] [TraitLocation(SystemActors.EditorWorld)]
public sealed class RaMapGeneratorInfo : TraitInfo, IMapGeneratorInfo public sealed class RaMapGeneratorInfo : TraitInfo<RaMapGenerator>, IMapGeneratorInfo
{ {
[FieldLoader.Require] [FieldLoader.Require]
public readonly string Type = null; public readonly string Type = null;
@@ -43,8 +43,6 @@ namespace OpenRA.Mods.Common.Traits
string IMapGeneratorInfo.Type => Type; string IMapGeneratorInfo.Type => Type;
string IMapGeneratorInfo.Name => Name; string IMapGeneratorInfo.Name => Name;
public override object Create(ActorInitializer init) { return new RaMapGenerator(this); }
static MiniYaml SettingsLoader(MiniYaml my) static MiniYaml SettingsLoader(MiniYaml my)
{ {
return my.NodeWithKey("Settings").Value; return my.NodeWithKey("Settings").Value;
@@ -54,10 +52,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
return MapGeneratorSettings.DumpFluent(my.NodeWithKey("Settings").Value); return MapGeneratorSettings.DumpFluent(my.NodeWithKey("Settings").Value);
} }
}
public sealed class RaMapGenerator : IMapGenerator
{
const int FractionMax = 1000; const int FractionMax = 1000;
const int EntityBonusMax = 1000000; const int EntityBonusMax = 1000000;
@@ -486,18 +481,9 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
readonly RaMapGeneratorInfo info;
IMapGeneratorInfo IMapGenerator.Info => info;
public RaMapGenerator(RaMapGeneratorInfo info)
{
this.info = info;
}
public MapGeneratorSettings GetSettings(Map map) public MapGeneratorSettings GetSettings(Map map)
{ {
return MapGeneratorSettings.LoadSettings(info.Settings, map); return MapGeneratorSettings.LoadSettings(Settings, map);
} }
public void Generate(Map map, MiniYaml settings) public void Generate(Map map, MiniYaml settings)
@@ -1815,4 +1801,6 @@ namespace OpenRA.Mods.Common.Traits
return amplitude; return amplitude;
} }
} }
public class RaMapGenerator { /* we're only interested in the Info */ }
} }

View File

@@ -973,10 +973,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
string Type { get; } string Type { get; }
string Name { get; } string Name { get; }
}
public interface IMapGenerator
{
/// <summary> /// <summary>
/// Get the generator settings available for this map. /// Get the generator settings available for this map.
/// Returns null if not compatible with the given map. /// Returns null if not compatible with the given map.
@@ -993,7 +990,5 @@ namespace OpenRA.Mods.Common.Traits
/// Thrown if the map could not be generated with the requested configuration. Map should be discarded. /// Thrown if the map could not be generated with the requested configuration. Map should be discarded.
/// </exception> /// </exception>
void Generate(Map map, MiniYaml settings); void Generate(Map map, MiniYaml settings);
IMapGeneratorInfo Info { get; }
} }
} }

View File

@@ -16,7 +16,6 @@ using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.UtilityCommands namespace OpenRA.Mods.Common.UtilityCommands
{ {
@@ -205,14 +204,12 @@ namespace OpenRA.Mods.Common.UtilityCommands
.Select(variable => config.Choices[variable].Length) .Select(variable => config.Choices[variable].Length)
.ToImmutableArray(); .ToImmutableArray();
var generatorInfo = var generator =
modData.DefaultRules.Actors[SystemActors.EditorWorld].TraitInfos<IMapGeneratorInfo>() modData.DefaultRules.Actors[SystemActors.EditorWorld].TraitInfos<IMapGeneratorInfo>()
.FirstOrDefault(info => info.Type == config.MapGeneratorType); .FirstOrDefault(info => info.Type == config.MapGeneratorType);
if (generatorInfo == null) if (generator == null)
throw new ArgumentException($"No map generator with type `{config.MapGeneratorType}`"); throw new ArgumentException($"No map generator with type `{config.MapGeneratorType}`");
var generator = (generatorInfo as TraitInfo).Create(null) as IMapGenerator;
long maxSerial = 1; long maxSerial = 1;
long tests = 0; long tests = 0;
long failures = 0; long failures = 0;

View File

@@ -40,10 +40,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ModData modData; readonly ModData modData;
// nullable // nullable
IMapGenerator selectedGenerator; IMapGeneratorInfo selectedGenerator;
readonly Dictionary<IMapGenerator, MapGeneratorSettings> generatorsToSettings; readonly Dictionary<IMapGeneratorInfo, MapGeneratorSettings> generatorsToSettings;
readonly Dictionary<IMapGenerator, Dictionary<MapGeneratorSettings.Option, MapGeneratorSettings.Choice>> generatorsToSettingsChoices; readonly Dictionary<IMapGeneratorInfo, Dictionary<MapGeneratorSettings.Option, MapGeneratorSettings.Choice>> generatorsToSettingsChoices;
readonly ScrollPanelWidget settingsPanel; readonly ScrollPanelWidget settingsPanel;
readonly Widget checkboxSettingTemplate; readonly Widget checkboxSettingTemplate;
@@ -60,11 +60,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
this.modData = modData; this.modData = modData;
selectedGenerator = null; selectedGenerator = null;
generatorsToSettings = new Dictionary<IMapGenerator, MapGeneratorSettings>(); generatorsToSettings = new Dictionary<IMapGeneratorInfo, MapGeneratorSettings>();
generatorsToSettingsChoices = new Dictionary<IMapGenerator, Dictionary<MapGeneratorSettings.Option, MapGeneratorSettings.Choice>>(); generatorsToSettingsChoices = new Dictionary<IMapGeneratorInfo, Dictionary<MapGeneratorSettings.Option, MapGeneratorSettings.Choice>>();
var mapGenerators = new List<IMapGenerator>(); var mapGenerators = new List<IMapGeneratorInfo>();
foreach (var generator in world.WorldActor.TraitsImplementing<IMapGenerator>()) foreach (var generator in world.Map.Rules.Actors[SystemActors.EditorWorld].TraitInfos<IMapGeneratorInfo>())
{ {
var settings = generator.GetSettings(world.Map); var settings = generator.GetSettings(world.Map);
if (settings == null) if (settings == null)
@@ -91,18 +91,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}; };
var generatorDropDown = widget.Get<DropDownButtonWidget>("GENERATOR"); var generatorDropDown = widget.Get<DropDownButtonWidget>("GENERATOR");
ChangeGenerator(mapGenerators.FirstOrDefault((IMapGenerator)null)); ChangeGenerator(mapGenerators.FirstOrDefault());
if (selectedGenerator != null) if (selectedGenerator != null)
{ {
generatorDropDown.GetText = () => FluentProvider.GetMessage(selectedGenerator.Info.Name); generatorDropDown.GetText = () => FluentProvider.GetMessage(selectedGenerator.Name);
generatorDropDown.OnMouseDown = _ => generatorDropDown.OnMouseDown = _ =>
{ {
ScrollItemWidget SetupItem(IMapGenerator g, ScrollItemWidget template) ScrollItemWidget SetupItem(IMapGeneratorInfo g, ScrollItemWidget template)
{ {
bool IsSelected() => g.Info.Type == selectedGenerator.Info.Type; bool IsSelected() => g.Type == selectedGenerator.Type;
void OnClick() => ChangeGenerator(mapGenerators.First(generator => generator.Info.Type == g.Info.Type)); void OnClick() => ChangeGenerator(mapGenerators.First(generator => generator.Type == g.Type));
var item = ScrollItemWidget.Setup(template, IsSelected, OnClick); var item = ScrollItemWidget.Setup(template, IsSelected, OnClick);
item.Get<LabelWidget>("LABEL").GetText = () => FluentProvider.GetMessage(g.Info.Name); item.Get<LabelWidget>("LABEL").GetText = () => FluentProvider.GetMessage(g.Name);
return item; return item;
} }
@@ -147,7 +147,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
} }
// newGenerator may be null. // newGenerator may be null.
void ChangeGenerator(IMapGenerator newGenerator) void ChangeGenerator(IMapGeneratorInfo newGenerator)
{ {
selectedGenerator = newGenerator; selectedGenerator = newGenerator;
@@ -307,7 +307,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// Run main generator logic. May throw. // Run main generator logic. May throw.
var generateStopwatch = Stopwatch.StartNew(); var generateStopwatch = Stopwatch.StartNew();
Log.Write("debug", $"Running '{selectedGenerator.Info.Type}' map generator with settings:\n{MiniYamlExts.WriteToString(settings.Nodes)}\n\n"); Log.Write("debug", $"Running '{selectedGenerator.Type}' map generator with settings:\n{MiniYamlExts.WriteToString(settings.Nodes)}\n\n");
selectedGenerator.Generate(generatedMap, settings); selectedGenerator.Generate(generatedMap, settings);
Log.Write("debug", $"Generator finished, taking {generateStopwatch.ElapsedMilliseconds}ms"); Log.Write("debug", $"Generator finished, taking {generateStopwatch.ElapsedMilliseconds}ms");
@@ -354,7 +354,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
false); false);
var description = FluentProvider.GetMessage(StrGenerated, var description = FluentProvider.GetMessage(StrGenerated,
"name", FluentProvider.GetMessage(selectedGenerator.Info.Name)); "name", FluentProvider.GetMessage(selectedGenerator.Name));
var action = new RandomMapEditorAction(editorBlit, description); var action = new RandomMapEditorAction(editorBlit, description);
editorActionManager.Add(action); editorActionManager.Add(action);
} }

View File

@@ -10,7 +10,6 @@
#endregion #endregion
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Widgets; using OpenRA.Widgets;
@@ -48,7 +47,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var markerToolPanel = widget.Get("MARKER_TOOL_PANEL"); var markerToolPanel = widget.Get("MARKER_TOOL_PANEL");
toolPanels.Add(MapTool.MarkerTiles, markerToolPanel); toolPanels.Add(MapTool.MarkerTiles, markerToolPanel);
if (world.WorldActor.TraitsImplementing<IMapGenerator>().Any()) if (world.Map.Rules.Actors[SystemActors.EditorWorld].HasTraitInfo<IMapGeneratorInfo>())
{ {
var mapGeneratorToolPanel = widget.GetOrNull("MAP_GENERATOR_TOOL_PANEL"); var mapGeneratorToolPanel = widget.GetOrNull("MAP_GENERATOR_TOOL_PANEL");
if (mapGeneratorToolPanel != null) if (mapGeneratorToolPanel != null)