mirror of
https://github.com/MaSzyna-EU07/StarterNG.git
synced 2026-07-17 17:09:19 +02:00
Some optimisations
This commit is contained in:
@@ -35,7 +35,8 @@ public sealed class GameData
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Load(IProgress<LoadStatus>? progress = null,
|
public void Load(IProgress<LoadStatus>? progress = null,
|
||||||
string vehiclesDir = "databases/vehicles/",
|
string vehiclesDir = "databases/vehicles/",
|
||||||
string sceneryDir = "scenery/")
|
string sceneryDir = "scenery/",
|
||||||
|
string miniDir = "textures/mini/")
|
||||||
{
|
{
|
||||||
if (Loaded)
|
if (Loaded)
|
||||||
return;
|
return;
|
||||||
@@ -57,6 +58,10 @@ public sealed class GameData
|
|||||||
}
|
}
|
||||||
Vehicles.EndLoad();
|
Vehicles.EndLoad();
|
||||||
|
|
||||||
|
// Preload the miniature .bmp index now (behind the splash) so the depot's
|
||||||
|
// first thumbnail render doesn't scan textures/mini/ on the UI thread.
|
||||||
|
VehicleDatabase.PreloadMiniIndex(miniDir);
|
||||||
|
|
||||||
// Phase 2 - sceneries
|
// Phase 2 - sceneries
|
||||||
foreach (string file in scnFiles)
|
foreach (string file in scnFiles)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,6 +55,16 @@ public class VehicleTexture
|
|||||||
|
|
||||||
/// <summary>Full skin path = directory + skinfile.</summary>
|
/// <summary>Full skin path = directory + skinfile.</summary>
|
||||||
[JsonIgnore] public string FullPath => Directory + Skinfile;
|
[JsonIgnore] public string FullPath => Directory + Skinfile;
|
||||||
|
|
||||||
|
// ── cached lookups, populated once after load (VehicleDatabase.BuildTextureIndex) ──
|
||||||
|
// These mirror the depot's ClassOf / CategoryOf so the search/filter hot path
|
||||||
|
// never recomputes them (no per-keystroke dictionary lookups over every texture).
|
||||||
|
|
||||||
|
/// <summary>Group's "mini" (or this texture's mini_ref) — the vehicle class. Never null.</summary>
|
||||||
|
[JsonIgnore] public string ResolvedClass { get; internal set; } = "";
|
||||||
|
|
||||||
|
/// <summary>Group's "category" letter, or null when the group is unknown.</summary>
|
||||||
|
[JsonIgnore] public string? ResolvedCategory { get; internal set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Alternate mapping from a malformed multi-= legacy line.</summary>
|
/// <summary>Alternate mapping from a malformed multi-= legacy line.</summary>
|
||||||
@@ -132,7 +142,11 @@ public class VehicleDatabase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Finalises an incremental load (builds lookup indexes).</summary>
|
/// <summary>Finalises an incremental load (builds lookup indexes).</summary>
|
||||||
public void EndLoad() => BuildSetIndex();
|
public void EndLoad()
|
||||||
|
{
|
||||||
|
BuildSetIndex();
|
||||||
|
BuildTextureIndex();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Files that make up the database: the merged vehicles.json if present,
|
/// Files that make up the database: the merged vehicles.json if present,
|
||||||
@@ -246,6 +260,24 @@ public class VehicleDatabase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolves each texture's class (group mini / mini_ref) and category letter
|
||||||
|
// once, after all groups are loaded, so the depot reads cached fields instead
|
||||||
|
// of doing a GroupsById lookup per texture on every search keystroke.
|
||||||
|
private void BuildTextureIndex()
|
||||||
|
{
|
||||||
|
foreach (var t in Textures)
|
||||||
|
{
|
||||||
|
VehicleGroup? g = null;
|
||||||
|
if (t.Group != null)
|
||||||
|
GroupsById.TryGetValue(t.Group, out g);
|
||||||
|
|
||||||
|
t.ResolvedCategory = g?.Category;
|
||||||
|
t.ResolvedClass = g != null && !string.IsNullOrEmpty(g.Mini)
|
||||||
|
? g.Mini!
|
||||||
|
: t.MiniRef ?? "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Miniature name for a texture: the texture_mini property, but if no .bmp
|
/// Miniature name for a texture: the texture_mini property, but if no .bmp
|
||||||
/// for it exists, falls back to the mini of the group it belongs to.
|
/// for it exists, falls back to the mini of the group it belongs to.
|
||||||
@@ -292,6 +324,14 @@ public class VehicleDatabase
|
|||||||
// Case-insensitive index of mini .bmp files (built once).
|
// Case-insensitive index of mini .bmp files (built once).
|
||||||
private static Dictionary<string, string>? _miniIndex;
|
private static Dictionary<string, string>? _miniIndex;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds the miniature .bmp index up front (called from the startup load,
|
||||||
|
/// behind the splash) so the first thumbnail render never stalls the UI
|
||||||
|
/// thread scanning textures/mini/. No-op if it was already built.
|
||||||
|
/// </summary>
|
||||||
|
public static void PreloadMiniIndex(string miniDir = "textures/mini/") =>
|
||||||
|
_miniIndex ??= BuildMiniIndex(miniDir);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves a miniature .bmp path under textures/mini/ case-insensitively,
|
/// Resolves a miniature .bmp path under textures/mini/ case-insensitively,
|
||||||
/// or null if missing. The directory is indexed once and reused.
|
/// or null if missing. The directory is indexed once and reused.
|
||||||
|
|||||||
@@ -238,16 +238,12 @@ public partial class Depot : UserControl
|
|||||||
private static bool IsUnitCar(Dynamic d) => UnitKey(d) != Base(d.SkinFile);
|
private static bool IsUnitCar(Dynamic d) => UnitKey(d) != Base(d.SkinFile);
|
||||||
|
|
||||||
// Vehicle class = the "mini" of the group the texture belongs to (e.g. EU07).
|
// Vehicle class = the "mini" of the group the texture belongs to (e.g. EU07).
|
||||||
private string ClassOf(VehicleTexture t)
|
// Resolved once at load (see VehicleDatabase.BuildTextureIndex); read the cache
|
||||||
{
|
// here so search/filter never repeats the group lookup per keystroke.
|
||||||
if (t.Group != null && _db.GroupsById.TryGetValue(t.Group, out var g) && !string.IsNullOrEmpty(g.Mini))
|
private static string ClassOf(VehicleTexture t) => t.ResolvedClass;
|
||||||
return g.Mini!;
|
|
||||||
return t.MiniRef ?? "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vehicle type = the group's "category" letter.
|
// Vehicle type = the group's "category" letter (also resolved once at load).
|
||||||
private string? CategoryOf(VehicleTexture t) =>
|
private static string? CategoryOf(VehicleTexture t) => t.ResolvedCategory;
|
||||||
t.Group != null && _db.GroupsById.TryGetValue(t.Group, out var g) ? g.Category : null;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------ category combo
|
// ------------------------------------------------------------ category combo
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user