Files
Claude f5ed13b98d Validate DistroDatabase and split MainMenuController's starter/collection logic out
- DistroDatabase.TryValidate() catches empty slots, blank ids, and
  duplicate ids at edit time (OnValidate) and runtime, instead of only
  surfacing as a runtime count check.
- StarterSelectionController centralizes the "do we have a usable
  starter set" check (previously re-derived in five places) and shows a
  dismissible in-UI error when the database is misconfigured, rather
  than silently leaving the modal hidden with just a console warning.
- Boot-intro's bootIntroPlayed flag now resets via
  RuntimeInitializeOnLoadMethod so it stays session-scoped even when
  the Editor's Reload Domain setting is off.
- Extracted StarterSelectionController and CollectionScreenController
  out of MainMenuController (885 -> ~490 lines), following the same
  plain-class-plus-Bind() pattern already used by FeaturedUnitPanel.
  Shared DisplayName/FormatLanguages formatting and digit-key mapping
  moved into DistroPresentation/CommandKeyBindings to remove the
  duplication that split would otherwise have introduced.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01364Mm9NsPooiSfDHKr4FAx
2026-07-06 09:42:27 +00:00

83 lines
2.4 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace KernelPanic.Data
{
/// <summary>
/// Resolves persisted distro ids to playable distro definitions.
/// </summary>
public sealed class DistroDatabase : ScriptableObject
{
[SerializeField] private List<DistroDefinition> allDistros = new();
public IReadOnlyList<DistroDefinition> AllDistros => allDistros;
public DistroDefinition FindById(string id)
{
if (string.IsNullOrWhiteSpace(id))
{
return null;
}
for (int i = 0; i < allDistros.Count; i++)
{
DistroDefinition distro = allDistros[i];
if (distro != null && string.Equals(distro.Id, id, StringComparison.OrdinalIgnoreCase))
{
return distro;
}
}
return null;
}
/// <summary>
/// Checks that every entry is assigned and has a unique, non-blank id. Used at both
/// edit time (OnValidate) and runtime, so misconfiguration surfaces before it can
/// silently disable a feature that depends on this database.
/// </summary>
public bool TryValidate(out string error)
{
for (int i = 0; i < allDistros.Count; i++)
{
if (allDistros[i] == null)
{
error = $"entry {i} is empty";
return false;
}
}
HashSet<string> seenIds = new(StringComparer.OrdinalIgnoreCase);
for (int i = 0; i < allDistros.Count; i++)
{
string id = allDistros[i].Id;
if (string.IsNullOrWhiteSpace(id))
{
error = $"'{allDistros[i].name}' has a blank id";
return false;
}
if (!seenIds.Add(id))
{
error = $"duplicate distro id '{id}'";
return false;
}
}
error = null;
return true;
}
#if UNITY_EDITOR
private void OnValidate()
{
if (!TryValidate(out string error))
{
Debug.LogError($"DistroDatabase '{name}': {error}.", this);
}
}
#endif
}
}