From 9e548fd0f036b2e826d6cb5640c830e661e9bb14 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Thu, 4 Dec 2025 20:45:21 +0000 Subject: [PATCH] Freeze non-mutable readonly static dictionaries. Since these will live for the lifetime of the process, it is worth freezing them on creation to improve lookup performance. If the dictionaries were iterated, change to an immutable array instead to preserve the order. --- OpenRA.Game/FieldLoader.cs | 12 +-- OpenRA.Game/Scripting/ScriptMemberExts.cs | 5 +- OpenRA.Game/Sync.cs | 5 +- .../Traits/World/TSVeinsRenderer.cs | 4 +- .../UtilityCommands/ImportGen1MapCommand.cs | 5 +- .../ImportRedAlertMapCommand.cs | 5 +- .../ImportTiberianDawnMapCommand.cs | 5 +- .../Graphics/BorderedRegionRenderable.cs | 24 +++--- .../ServerTraits/MasterServerPinger.cs | 5 +- .../Documentation/ExtractEmmyLuaAPI.cs | 5 +- .../Widgets/ViewportControllerWidget.cs | 77 ++++++++++--------- .../Traits/World/D2kResourceRenderer.cs | 5 +- OpenRA.Platforms.Default/OpenGL.cs | 17 ++-- 13 files changed, 92 insertions(+), 82 deletions(-) diff --git a/OpenRA.Game/FieldLoader.cs b/OpenRA.Game/FieldLoader.cs index 24f262bcae..b3884ef487 100644 --- a/OpenRA.Game/FieldLoader.cs +++ b/OpenRA.Game/FieldLoader.cs @@ -61,8 +61,8 @@ namespace OpenRA static readonly ConcurrentCache IntegerExpressionCache = new(expression => new IntegerExpression(expression)); - static readonly Dictionary> TypeParsers = - new() + static readonly FrozenDictionary> TypeParsers = + new Dictionary> { { typeof(int), ParseInt }, { typeof(ushort), ParseUShort }, @@ -93,10 +93,10 @@ namespace OpenRA { typeof(float3), ParseFloat3 }, { typeof(Rectangle), ParseRectangle }, { typeof(DateTime), ParseDateTime } - }; + }.ToFrozenDictionary(); - static readonly Dictionary> GenericTypeParsers = - new() + static readonly FrozenDictionary> GenericTypeParsers = + new Dictionary> { { typeof(HashSet<>), ParseHashSetOrList }, { typeof(List<>), ParseHashSetOrList }, @@ -106,7 +106,7 @@ namespace OpenRA { typeof(FrozenDictionary<,>), ParseFrozenDictionary }, { typeof(BitSet<>), ParseBitSet }, { typeof(Nullable<>), ParseNullable }, - }; + }.ToFrozenDictionary(); static readonly object BoxedTrue = true; static readonly object BoxedFalse = false; diff --git a/OpenRA.Game/Scripting/ScriptMemberExts.cs b/OpenRA.Game/Scripting/ScriptMemberExts.cs index 44f8a9bcda..7dd3e1799e 100644 --- a/OpenRA.Game/Scripting/ScriptMemberExts.cs +++ b/OpenRA.Game/Scripting/ScriptMemberExts.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -18,13 +19,13 @@ namespace OpenRA.Scripting { public static class ScriptMemberExts { - static readonly Dictionary LuaTypeNameReplacements = new() + static readonly FrozenDictionary LuaTypeNameReplacements = new Dictionary { { "Void", "void" }, { "Int32", "int" }, { "String", "string" }, { "Boolean", "bool" } - }; + }.ToFrozenDictionary(); public static string LuaDocString(this Type t) { diff --git a/OpenRA.Game/Sync.cs b/OpenRA.Game/Sync.cs index d33624e4f1..e4ed5af4d6 100644 --- a/OpenRA.Game/Sync.cs +++ b/OpenRA.Game/Sync.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -40,7 +41,7 @@ namespace OpenRA return GetHashFunction(sync)(sync); } - static readonly Dictionary CustomHashFunctions = new() + static readonly FrozenDictionary CustomHashFunctions = new Dictionary { { typeof(int2), ((Func)HashInt2).Method }, { typeof(CPos), ((Func)HashCPos).Method }, @@ -53,7 +54,7 @@ namespace OpenRA { typeof(Actor), ((Func)HashActor).Method }, { typeof(Player), ((Func)HashPlayer).Method }, { typeof(Target), ((Func)HashTarget).Method }, - }; + }.ToFrozenDictionary(); static void EmitSyncOpcodes(Type type, ILGenerator il) { diff --git a/OpenRA.Mods.Cnc/Traits/World/TSVeinsRenderer.cs b/OpenRA.Mods.Cnc/Traits/World/TSVeinsRenderer.cs index fb9b7fa935..887b012399 100644 --- a/OpenRA.Mods.Cnc/Traits/World/TSVeinsRenderer.cs +++ b/OpenRA.Mods.Cnc/Traits/World/TSVeinsRenderer.cs @@ -122,7 +122,7 @@ namespace OpenRA.Mods.Cnc.Traits PlusY = 0x8, } - static readonly Dictionary BorderIndices = new() + static readonly FrozenDictionary BorderIndices = new Dictionary { { Adjacency.MinusY, new[] { 3, 4, 5 } }, { Adjacency.PlusX, new[] { 6, 7, 8 } }, @@ -139,7 +139,7 @@ namespace OpenRA.Mods.Cnc.Traits { Adjacency.MinusX | Adjacency.MinusY | Adjacency.PlusY, new[] { 39, 40, 41 } }, { Adjacency.MinusX | Adjacency.PlusX | Adjacency.PlusY, new[] { 42, 43, 44 } }, { Adjacency.MinusX | Adjacency.PlusX | Adjacency.MinusY | Adjacency.PlusY, new[] { 45, 46, 47 } }, - }; + }.ToFrozenDictionary(); static readonly int[] HeavyIndices = [48, 49, 50, 51]; static readonly int[] LightIndices = [52]; diff --git a/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs b/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs index c96d858380..95561f5edb 100644 --- a/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs +++ b/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Collections.Immutable; using System.IO; @@ -364,7 +365,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands } // TODO: fix this -- will have bitrotted pretty badly. - static readonly Dictionary NamedColorMapping = new() + static readonly FrozenDictionary NamedColorMapping = new Dictionary { { "gold", Color.FromArgb(246, 214, 121) }, { "blue", Color.FromArgb(226, 230, 246) }, @@ -376,7 +377,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands { "green", Color.FromArgb(160, 240, 140) }, { "white", Color.FromArgb(255, 255, 255) }, { "black", Color.FromArgb(80, 80, 80) }, - }; + }.ToFrozenDictionary(); public static void SetMapPlayers(string section, string faction, string color, IniFile file, List players, MapPlayers mapPlayers) { diff --git a/OpenRA.Mods.Cnc/UtilityCommands/ImportRedAlertMapCommand.cs b/OpenRA.Mods.Cnc/UtilityCommands/ImportRedAlertMapCommand.cs index aca6872633..51feea9c12 100644 --- a/OpenRA.Mods.Cnc/UtilityCommands/ImportRedAlertMapCommand.cs +++ b/OpenRA.Mods.Cnc/UtilityCommands/ImportRedAlertMapCommand.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.IO; using System.Linq; @@ -47,7 +48,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands "fpls", "wcrate", "scrate", "fenc", "sbag", ]; - static readonly Dictionary OverlayResourceMapping = new() + static readonly FrozenDictionary OverlayResourceMapping = new Dictionary { // RA ore & crystals { "gold01", (1, 0) }, @@ -58,7 +59,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands { "gem02", (2, 1) }, { "gem03", (2, 2) }, { "gem04", (2, 3) }, - }; + }.ToFrozenDictionary(); void UnpackTileData(MemoryStream ms) { diff --git a/OpenRA.Mods.Cnc/UtilityCommands/ImportTiberianDawnMapCommand.cs b/OpenRA.Mods.Cnc/UtilityCommands/ImportTiberianDawnMapCommand.cs index 5c78aa603c..b4fbd64219 100644 --- a/OpenRA.Mods.Cnc/UtilityCommands/ImportTiberianDawnMapCommand.cs +++ b/OpenRA.Mods.Cnc/UtilityCommands/ImportTiberianDawnMapCommand.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.IO; using System.Linq; @@ -35,7 +36,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands Console.WriteLine($"ERROR: Detected NewINIFormat {format}. Are you trying to import a Red Alert map?"); } - static readonly Dictionary OverlayResourceMapping = new() + static readonly FrozenDictionary OverlayResourceMapping = new Dictionary { // Tiberium { "ti1", (1, 0) }, @@ -50,7 +51,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands { "ti10", (1, 9) }, { "ti11", (1, 10) }, { "ti12", (1, 11) }, - }; + }.ToFrozenDictionary(); void UnpackTileData(Stream ms) { diff --git a/OpenRA.Mods.Common/Graphics/BorderedRegionRenderable.cs b/OpenRA.Mods.Common/Graphics/BorderedRegionRenderable.cs index 7027a7900f..3fd44a1051 100644 --- a/OpenRA.Mods.Common/Graphics/BorderedRegionRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/BorderedRegionRenderable.cs @@ -9,7 +9,7 @@ */ #endregion -using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using OpenRA.Graphics; using OpenRA.Primitives; @@ -22,13 +22,13 @@ namespace OpenRA.Mods.Common.Graphics // Maps a cell offset to the index of the corner (in the 'Corner' arrays in the MapGrid.CellRamp structs) // from which a border should be drawn. The index of the end corner will be (cornerIndex + 1) % 4. - static readonly Dictionary Offset2CornerIndex = new() - { - { new CVec(0, -1), (int)Corner.TopLeft }, - { new CVec(1, 0), (int)Corner.TopRight }, - { new CVec(0, 1), (int)Corner.BottomRight }, - { new CVec(-1, 0), (int)Corner.BottomLeft }, - }; + static readonly ImmutableArray<(CVec Offset, int CornerIndex)> Offset2CornerIndex = + [ + (new CVec(0, -1), (int)Corner.TopLeft), + (new CVec(1, 0), (int)Corner.TopRight), + (new CVec(0, 1), (int)Corner.BottomRight), + (new CVec(-1, 0), (int)Corner.BottomLeft), + ]; readonly CPos[] region; readonly Color color, contrastColor; @@ -77,14 +77,14 @@ namespace OpenRA.Mods.Common.Graphics var corners = map.Grid.Ramps[ramp].Corners; var pos = map.CenterOfCell(c) - new WVec(0, 0, map.Grid.Ramps[ramp].CenterHeightOffset); - foreach (var o in Offset2CornerIndex) + foreach (var (offset, cornerIndex) in Offset2CornerIndex) { // If the neighboring cell is part of the region, don't draw a border between the cells. - if (region.Contains(c + o.Key)) + if (region.Contains(c + offset)) continue; - var start = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos + corners[o.Value])); - var end = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos + corners[(o.Value + 1) % 4])); + var start = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos + corners[cornerIndex])); + var end = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos + corners[(cornerIndex + 1) % 4])); if (constrastWidth > 0) cr.DrawLine(start, end, constrastWidth, constrastColor); diff --git a/OpenRA.Mods.Common/ServerTraits/MasterServerPinger.cs b/OpenRA.Mods.Common/ServerTraits/MasterServerPinger.cs index b9379873a6..03a1793007 100644 --- a/OpenRA.Mods.Common/ServerTraits/MasterServerPinger.cs +++ b/OpenRA.Mods.Common/ServerTraits/MasterServerPinger.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Net.Http; using System.Text.RegularExpressions; @@ -49,11 +50,11 @@ namespace OpenRA.Mods.Common.Server const string GameOffline = "notification-game-offline"; static readonly ushort LanAdvertisePort = (ushort)new Random(DateTime.Now.Millisecond).Next(2048, 60000); - static readonly Dictionary MasterServerErrors = new() + static readonly FrozenDictionary MasterServerErrors = new Dictionary { { 1, NoPortForward }, { 2, BlacklistedTitle } - }; + }.ToFrozenDictionary(); Beacon lanGameBeacon; long lastPing = 0; diff --git a/OpenRA.Mods.Common/UtilityCommands/Documentation/ExtractEmmyLuaAPI.cs b/OpenRA.Mods.Common/UtilityCommands/Documentation/ExtractEmmyLuaAPI.cs index 7baa812b11..20a2695dac 100644 --- a/OpenRA.Mods.Common/UtilityCommands/Documentation/ExtractEmmyLuaAPI.cs +++ b/OpenRA.Mods.Common/UtilityCommands/Documentation/ExtractEmmyLuaAPI.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -386,7 +387,7 @@ namespace OpenRA.Mods.Common.UtilityCommands.Documentation public static class EmmyLuaExts { - static readonly Dictionary LuaTypeNameReplacements = new() + static readonly FrozenDictionary LuaTypeNameReplacements = new Dictionary { // These are weak type mappings, don't add these. // Instead, use ScriptEmmyTypeOverrideAttribute to provide a specific type. @@ -409,7 +410,7 @@ namespace OpenRA.Mods.Common.UtilityCommands.Documentation { "Color", "color" }, { "Actor", "actor" }, { "Player", "player" }, - }; + }.ToFrozenDictionary(); public static string EmmyLuaString(this Type type, string notSupportedExceptionContext) { diff --git a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs index a51aae0440..748b771174 100644 --- a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Lint; @@ -54,37 +55,37 @@ namespace OpenRA.Mods.Common.Widgets public FrozenActor FrozenActorTooltip { get; private set; } public string ResourceTooltip { get; private set; } - static readonly Dictionary ScrollCursors = new() - { - { ScrollDirection.Up | ScrollDirection.Left, "scroll-tl" }, - { ScrollDirection.Up | ScrollDirection.Right, "scroll-tr" }, - { ScrollDirection.Down | ScrollDirection.Left, "scroll-bl" }, - { ScrollDirection.Down | ScrollDirection.Right, "scroll-br" }, - { ScrollDirection.Up, "scroll-t" }, - { ScrollDirection.Down, "scroll-b" }, - { ScrollDirection.Left, "scroll-l" }, - { ScrollDirection.Right, "scroll-r" }, - }; + static readonly ImmutableArray<(ScrollDirection Direction, string Cursor)> ScrollCursors = + [ + (ScrollDirection.Up | ScrollDirection.Left, "scroll-tl"), + (ScrollDirection.Up | ScrollDirection.Right, "scroll-tr"), + (ScrollDirection.Down | ScrollDirection.Left, "scroll-bl"), + (ScrollDirection.Down | ScrollDirection.Right, "scroll-br"), + (ScrollDirection.Up, "scroll-t"), + (ScrollDirection.Down, "scroll-b"), + (ScrollDirection.Left, "scroll-l"), + (ScrollDirection.Right, "scroll-r"), + ]; - static readonly Dictionary JoystickCursors = new() - { - { ScrollDirection.Up | ScrollDirection.Left, "joystick-tl-blocked" }, - { ScrollDirection.Up | ScrollDirection.Right, "joystick-tr-blocked" }, - { ScrollDirection.Down | ScrollDirection.Left, "joystick-bl-blocked" }, - { ScrollDirection.Down | ScrollDirection.Right, "joystick-br-blocked" }, - { ScrollDirection.Up, "joystick-t-blocked" }, - { ScrollDirection.Down, "joystick-b-blocked" }, - { ScrollDirection.Left, "joystick-l-blocked" }, - { ScrollDirection.Right, "joystick-r-blocked" }, - }; + static readonly ImmutableArray<(ScrollDirection Direction, string Cursor)> JoystickCursors = + [ + (ScrollDirection.Up | ScrollDirection.Left, "joystick-tl-blocked"), + (ScrollDirection.Up | ScrollDirection.Right, "joystick-tr-blocked"), + (ScrollDirection.Down | ScrollDirection.Left, "joystick-bl-blocked"), + (ScrollDirection.Down | ScrollDirection.Right, "joystick-br-blocked"), + (ScrollDirection.Up, "joystick-t-blocked"), + (ScrollDirection.Down, "joystick-b-blocked"), + (ScrollDirection.Left, "joystick-l-blocked"), + (ScrollDirection.Right, "joystick-r-blocked"), + ]; - static readonly Dictionary ScrollOffsets = new() - { - { ScrollDirection.Up, new float2(0, -1) }, - { ScrollDirection.Down, new float2(0, 1) }, - { ScrollDirection.Left, new float2(-1, 0) }, - { ScrollDirection.Right, new float2(1, 0) }, - }; + static readonly ImmutableArray<(ScrollDirection Direction, float2 Offset)> ScrollOffsets = + [ + (ScrollDirection.Up, new float2(0, -1)), + (ScrollDirection.Down, new float2(0, 1)), + (ScrollDirection.Left, new float2(-1, 0)), + (ScrollDirection.Right, new float2(1, 0)), + ]; readonly Lazy tooltipContainer; readonly World world; @@ -202,9 +203,9 @@ namespace OpenRA.Mods.Common.Widgets { var scroll = float2.Zero; - foreach (var kv in ScrollOffsets) - if (keyboardDirections.Includes(kv.Key) || edgeDirections.Includes(kv.Key)) - scroll += kv.Value; + foreach (var (direction, offset) in ScrollOffsets) + if (keyboardDirections.Includes(direction) || edgeDirections.Includes(direction)) + scroll += offset; // Scroll rate is defined for a 40ms interval var deltaScale = Math.Min(Game.RunTime - lastScrollTime, 25f); @@ -292,15 +293,15 @@ namespace OpenRA.Mods.Common.Widgets if (IsJoystickScrolling || isStandardScrolling) { - foreach (var dir in JoystickCursors) - if (blockedDirections.Includes(dir.Key)) - return dir.Value; + foreach (var (direction, cursor) in JoystickCursors) + if (blockedDirections.Includes(direction)) + return cursor; return "joystick-all"; } - foreach (var dir in ScrollCursors) - if (edgeDirections.Includes(dir.Key)) - return dir.Value + (blockedDirections.Includes(dir.Key) ? "-blocked" : ""); + foreach (var (direction, cursor) in ScrollCursors) + if (edgeDirections.Includes(direction)) + return cursor + (blockedDirections.Includes(direction) ? "-blocked" : ""); return null; } diff --git a/OpenRA.Mods.D2k/Traits/World/D2kResourceRenderer.cs b/OpenRA.Mods.D2k/Traits/World/D2kResourceRenderer.cs index b649817f48..050da36020 100644 --- a/OpenRA.Mods.D2k/Traits/World/D2kResourceRenderer.cs +++ b/OpenRA.Mods.D2k/Traits/World/D2kResourceRenderer.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using OpenRA.Mods.Common.Traits; using OpenRA.Traits; @@ -42,7 +43,7 @@ namespace OpenRA.Mods.D2k.Traits All = Left | Top | Right | Bottom | TopLeft | TopRight | BottomLeft | BottomRight } - public static readonly Dictionary SpriteMap = new() + public static readonly FrozenDictionary SpriteMap = new Dictionary { { ClearSides.Left | ClearSides.Top | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 2 }, { ClearSides.Top | ClearSides.Right | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 3 }, @@ -90,7 +91,7 @@ namespace OpenRA.Mods.D2k.Traits { ClearSides.Right | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomRight, 47 }, { ClearSides.Bottom | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 48 }, { ClearSides.Bottom | ClearSides.TopLeft | ClearSides.BottomLeft | ClearSides.BottomRight, 49 }, - }; + }.ToFrozenDictionary(); public D2kResourceRenderer(Actor self, D2kResourceRendererInfo info) : base(self, info) { } diff --git a/OpenRA.Platforms.Default/OpenGL.cs b/OpenRA.Platforms.Default/OpenGL.cs index d431c2934a..043e4a5d8f 100644 --- a/OpenRA.Platforms.Default/OpenGL.cs +++ b/OpenRA.Platforms.Default/OpenGL.cs @@ -10,6 +10,7 @@ #endregion using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -65,7 +66,7 @@ namespace OpenRA.Platforms.Default public const int GL_CONTEXT_LOST = 0x0507; public const int GL_TABLE_TOO_LARGE = 0x8031; - static readonly Dictionary ErrorToText = new() + static readonly FrozenDictionary ErrorToText = new Dictionary { { GL_NO_ERROR, "No Error" }, { GL_INVALID_ENUM, "Invalid Enum" }, @@ -77,7 +78,7 @@ namespace OpenRA.Platforms.Default { GL_INVALID_FRAMEBUFFER_OPERATION, "Invalid Framebuffer Operation" }, { GL_CONTEXT_LOST, "Context Lost" }, { GL_TABLE_TOO_LARGE, "Table Too Large" }, - }; + }.ToFrozenDictionary(); // BeginMode public const int GL_POINTS = 0; @@ -161,7 +162,7 @@ namespace OpenRA.Platforms.Default public const int GL_DEBUG_SOURCE_APPLICATION = 0x824A; public const int GL_DEBUG_SOURCE_OTHER = 0x824B; - static readonly Dictionary DebugSourceToText = new() + static readonly FrozenDictionary DebugSourceToText = new Dictionary { { GL_DEBUG_SOURCE_API, "API" }, { GL_DEBUG_SOURCE_WINDOW_SYSTEM, "Window System" }, @@ -169,7 +170,7 @@ namespace OpenRA.Platforms.Default { GL_DEBUG_SOURCE_THIRD_PARTY, "Third Party" }, { GL_DEBUG_SOURCE_APPLICATION, "Application" }, { GL_DEBUG_SOURCE_OTHER, "Other" } - }; + }.ToFrozenDictionary(); public const int GL_DEBUG_TYPE_ERROR = 0x824C; public const int GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR = 0x824D; @@ -181,7 +182,7 @@ namespace OpenRA.Platforms.Default public const int GL_DEBUG_TYPE_POP_GROUP = 0x826A; public const int GL_DEBUG_TYPE_OTHER = 0x8251; - static readonly Dictionary DebugTypeToText = new() + static readonly FrozenDictionary DebugTypeToText = new Dictionary { { GL_DEBUG_TYPE_ERROR, "Error" }, { GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, "Deprecated Behaviour" }, @@ -192,20 +193,20 @@ namespace OpenRA.Platforms.Default { GL_DEBUG_TYPE_PUSH_GROUP, "Push Group" }, { GL_DEBUG_TYPE_POP_GROUP, "Pop Group" }, { GL_DEBUG_TYPE_OTHER, "Other" } - }; + }.ToFrozenDictionary(); public const int GL_DEBUG_SEVERITY_HIGH = 0x9146; public const int GL_DEBUG_SEVERITY_MEDIUM = 0x9147; public const int GL_DEBUG_SEVERITY_LOW = 0x9148; public const int GL_DEBUG_SEVERITY_NOTIFICATION = 0x826B; - static readonly Dictionary DebugSeverityToText = new() + static readonly FrozenDictionary DebugSeverityToText = new Dictionary { { GL_DEBUG_SEVERITY_HIGH, "High" }, { GL_DEBUG_SEVERITY_MEDIUM, "Medium" }, { GL_DEBUG_SEVERITY_LOW, "Low" }, { GL_DEBUG_SEVERITY_NOTIFICATION, "Notification" } - }; + }.ToFrozenDictionary(); // Pixel Mode / Transfer public const int GL_PACK_ROW_LENGTH = 0x0D02;