Change classes that use FieldLoader to use read-only collections.

This commit is contained in:
RoosterDragon
2025-11-08 12:40:56 +00:00
committed by Paul Chote
parent 797c71e500
commit 649e7e8c28
308 changed files with 1233 additions and 901 deletions

View File

@@ -9,6 +9,7 @@
*/
#endregion
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
@@ -40,9 +41,9 @@ namespace OpenRA.Mods.Common.Terrain
public class DefaultTerrainTemplateInfo : TerrainTemplateInfo
{
public readonly string[] Images;
public readonly string[] DepthImages;
public readonly int[] Frames;
public readonly ImmutableArray<string> Images;
public readonly ImmutableArray<string> DepthImages;
public readonly ImmutableArray<int> Frames;
public readonly string Palette;
public DefaultTerrainTemplateInfo(ITerrainInfo terrainInfo, MiniYaml my)
@@ -75,8 +76,8 @@ namespace OpenRA.Mods.Common.Terrain
public readonly string Id;
public readonly Size TileSize = new(24, 24);
public readonly int SheetSize = 512;
public readonly Color[] HeightDebugColors = [Color.Red];
public readonly string[] EditorTemplateOrder;
public readonly ImmutableArray<Color> HeightDebugColors = [Color.Red];
public readonly ImmutableArray<string> EditorTemplateOrder;
public readonly bool IgnoreTileSpriteOffsets;
public readonly bool EnableDepth = false;
public readonly float MinHeightColorBrightness = 1.0f;
@@ -84,13 +85,13 @@ namespace OpenRA.Mods.Common.Terrain
public readonly string Palette = TileSet.TerrainPaletteInternalName;
[FieldLoader.Ignore]
public readonly IReadOnlyDictionary<ushort, TerrainTemplateInfo> Templates;
public readonly FrozenDictionary<ushort, TerrainTemplateInfo> Templates;
[FieldLoader.Ignore]
public readonly IReadOnlyDictionary<string, IEnumerable<MultiBrushInfo>> MultiBrushCollections;
public readonly FrozenDictionary<string, ImmutableArray<MultiBrushInfo>> MultiBrushCollections;
[FieldLoader.Ignore]
public readonly TerrainTypeInfo[] TerrainInfo;
readonly Dictionary<string, byte> terrainIndexByType = [];
public readonly ImmutableArray<TerrainTypeInfo> TerrainInfo;
readonly FrozenDictionary<string, byte> terrainIndexByType;
readonly byte defaultWalkableTerrainIndex;
public DefaultTerrain(IReadOnlyFileSystem fileSystem, string filepath)
@@ -105,35 +106,38 @@ namespace OpenRA.Mods.Common.Terrain
TerrainInfo = yaml["Terrain"].ToDictionary().Values
.Select(y => new TerrainTypeInfo(y))
.OrderBy(tt => tt.Type)
.ToArray();
.ToImmutableArray();
if (TerrainInfo.Length >= byte.MaxValue)
throw new YamlException("Too many terrain types.");
var tiby = new Dictionary<string, byte>(TerrainInfo.Length);
for (byte i = 0; i < TerrainInfo.Length; i++)
{
var tt = TerrainInfo[i].Type;
if (terrainIndexByType.ContainsKey(tt))
if (!tiby.TryAdd(tt, i))
throw new YamlException($"Duplicate terrain type '{tt}' in '{filepath}'.");
terrainIndexByType.Add(tt, i);
}
terrainIndexByType = tiby.ToFrozenDictionary();
defaultWalkableTerrainIndex = GetTerrainIndex("Clear");
// Templates
Templates = yaml["Templates"].ToDictionary().Values
.Select(y => (TerrainTemplateInfo)new DefaultTerrainTemplateInfo(this, y)).ToDictionary(t => t.Id);
.Select(y => (TerrainTemplateInfo)new DefaultTerrainTemplateInfo(this, y))
.ToDictionary(t => t.Id)
.ToFrozenDictionary();
MultiBrushCollections =
yaml.TryGetValue("MultiBrushCollections", out var collectionDefinitions)
? collectionDefinitions.ToDictionary()
.Select(kv => new KeyValuePair<string, IEnumerable<MultiBrushInfo>>(
.Select(kv => new KeyValuePair<string, ImmutableArray<MultiBrushInfo>>(
kv.Key,
MultiBrushInfo.ParseCollection(kv.Value)))
.ToImmutableDictionary()
: ImmutableDictionary<string, IEnumerable<MultiBrushInfo>>.Empty;
.ToFrozenDictionary()
: FrozenDictionary<string, ImmutableArray<MultiBrushInfo>>.Empty;
}
public TerrainTypeInfo this[byte index] => TerrainInfo[index];
@@ -175,19 +179,19 @@ namespace OpenRA.Mods.Common.Terrain
string ITerrainInfo.Id => Id;
string ITerrainInfo.Name => Name;
Size ITerrainInfo.TileSize => TileSize;
TerrainTypeInfo[] ITerrainInfo.TerrainTypes => TerrainInfo;
ImmutableArray<TerrainTypeInfo> ITerrainInfo.TerrainTypes => TerrainInfo;
TerrainTileInfo ITerrainInfo.GetTerrainInfo(TerrainTile r) { return GetTileInfo(r); }
bool ITerrainInfo.TryGetTerrainInfo(TerrainTile r, out TerrainTileInfo info) { return TryGetTileInfo(r, out info); }
Color[] ITerrainInfo.HeightDebugColors => HeightDebugColors;
ImmutableArray<Color> ITerrainInfo.HeightDebugColors => HeightDebugColors;
IEnumerable<Color> ITerrainInfo.RestrictedPlayerColors { get { return TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color); } }
float ITerrainInfo.MinHeightColorBrightness => MinHeightColorBrightness;
float ITerrainInfo.MaxHeightColorBrightness => MaxHeightColorBrightness;
TerrainTile ITerrainInfo.DefaultTerrainTile => new(Templates.First().Key, 0);
string[] ITemplatedTerrainInfo.EditorTemplateOrder => EditorTemplateOrder;
IReadOnlyDictionary<ushort, TerrainTemplateInfo> ITemplatedTerrainInfo.Templates => Templates;
IReadOnlyDictionary<string, IEnumerable<MultiBrushInfo>> ITemplatedTerrainInfo.MultiBrushCollections => MultiBrushCollections;
ImmutableArray<string> ITemplatedTerrainInfo.EditorTemplateOrder => EditorTemplateOrder;
FrozenDictionary<ushort, TerrainTemplateInfo> ITemplatedTerrainInfo.Templates => Templates;
FrozenDictionary<string, ImmutableArray<MultiBrushInfo>> ITemplatedTerrainInfo.MultiBrushCollections => MultiBrushCollections;
void IDumpSheetsTerrainInfo.DumpSheets(string terrainName, ImmutablePalette palette, ref int sheetCount)
{