236 lines
8.1 KiB
C#
236 lines
8.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// Honest live-verification ledger (Phase 0). Regenerated each run; not committed.
|
|
/// Levels: none | feed | pipeline | id_drop | id | unsupported | fail
|
|
/// </summary>
|
|
public sealed class EventLiveCoverageRow
|
|
{
|
|
public string Domain = "";
|
|
public string Id = "";
|
|
public bool Camera;
|
|
public bool Inject;
|
|
public string LiveLevel = "none";
|
|
public string Pipeline = "";
|
|
public string Notes = "";
|
|
}
|
|
|
|
public sealed class EventLiveCoverageSummary
|
|
{
|
|
public int Id;
|
|
public int IdDrop;
|
|
public int Pipeline;
|
|
public int Feed;
|
|
public int None;
|
|
public int Unsupported;
|
|
public int Fail;
|
|
public int CameraRows;
|
|
public int CameraNone;
|
|
|
|
public string Detail =>
|
|
$"id={Id} id_drop={IdDrop} pipeline={Pipeline} feed={Feed} none={None} "
|
|
+ $"unsupported={Unsupported} fail={Fail} camera={CameraRows} camera_none={CameraNone}";
|
|
}
|
|
|
|
public static class EventLiveCoverageLedger
|
|
{
|
|
private static readonly Dictionary<string, EventLiveCoverageRow> Rows =
|
|
new Dictionary<string, EventLiveCoverageRow>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
private static string Key(string domain, string id) => (domain ?? "") + "\t" + (id ?? "");
|
|
|
|
public static int RowCount => Rows.Count;
|
|
|
|
public static void Clear()
|
|
{
|
|
Rows.Clear();
|
|
}
|
|
|
|
public static void SeedFromCatalogs()
|
|
{
|
|
Clear();
|
|
|
|
foreach (string id in EventCatalog.Happiness.AuthoredIds)
|
|
{
|
|
HappinessCatalogEntry e = EventCatalog.Happiness.GetOrFallback(id);
|
|
bool camera = EventCatalog.IsCameraWorthy(e);
|
|
AddSeed("happiness", id, camera, camera);
|
|
}
|
|
|
|
foreach (string id in EventCatalog.Status.AuthoredIds)
|
|
{
|
|
StatusInterestEntry e = EventCatalog.Status.GetOrFallback(id);
|
|
bool camera = EventCatalog.IsCameraWorthy(e);
|
|
AddSeed("status", id, camera, camera);
|
|
}
|
|
|
|
foreach (string id in EventCatalog.WorldLog.AuthoredIds)
|
|
{
|
|
WorldLogEventEntry e = EventCatalog.WorldLog.GetOrFallback(id);
|
|
bool camera = EventCatalog.IsCameraWorthy(e);
|
|
AddSeed("worldLog", id, camera, camera);
|
|
}
|
|
|
|
foreach (string id in EventCatalog.Disaster.AuthoredIds)
|
|
{
|
|
DisasterInterestEntry e = EventCatalog.Disaster.GetOrFallback(id);
|
|
bool camera = e != null && EventCatalog.IsCameraWorthy(e.CreatesInterest);
|
|
AddSeed("disasters", id, camera, camera);
|
|
}
|
|
|
|
foreach (string id in EventCatalog.WarType.AuthoredIds)
|
|
{
|
|
WarTypeInterestEntry e = EventCatalog.WarType.GetOrFallback(id);
|
|
bool camera = e != null && EventCatalog.IsCameraWorthy(e.CreatesInterest);
|
|
AddSeed("warTypes", id, camera, camera);
|
|
}
|
|
|
|
SeedDiscrete("relationship", EventCatalog.Relationship.AuthoredIds, id => EventCatalog.Relationship.GetOrFallback(id));
|
|
SeedDiscrete("plots", EventCatalog.Plot.AuthoredIds, id => EventCatalog.Plot.GetOrFallback(id));
|
|
SeedDiscrete("books", EventCatalog.Book.AuthoredIds, id => EventCatalog.Book.GetOrFallback(id));
|
|
SeedDiscrete("eras", EventCatalog.Era.AuthoredIds, id => EventCatalog.Era.GetOrFallback(id));
|
|
SeedDiscrete("traits", EventCatalog.Trait.AuthoredIds, id => EventCatalog.Trait.GetOrFallback(id));
|
|
|
|
foreach (string id in EventCatalog.Decision.AuthoredIds)
|
|
{
|
|
bool camera = EventCatalog.Decision.IsCameraWorthy(id);
|
|
AddSeed("decisions", id, camera, camera);
|
|
}
|
|
|
|
SeedDiscrete("spell", EventCatalog.Spell.AuthoredIds, id => EventCatalog.Spell.GetOrFallback(id));
|
|
SeedDiscrete("item", EventCatalog.Item.AuthoredIds, id => EventCatalog.Item.GetOrFallback(id));
|
|
SeedDiscrete("power", EventCatalog.Power.AuthoredIds, id => EventCatalog.Power.GetOrFallback(id));
|
|
SeedDiscrete("gene", EventCatalog.Gene.AuthoredIds, id => EventCatalog.Gene.GetOrFallback(id));
|
|
SeedDiscrete("phenotype", EventCatalog.Phenotype.AuthoredIds, id => EventCatalog.Phenotype.GetOrFallback(id));
|
|
SeedDiscrete("worldLaw", EventCatalog.WorldLaw.AuthoredIds, id => EventCatalog.WorldLaw.GetOrFallback(id));
|
|
SeedDiscrete("subspecies_trait", EventCatalog.SubspeciesTrait.AuthoredIds, id => EventCatalog.SubspeciesTrait.GetOrFallback(id));
|
|
SeedDiscrete("biome", EventCatalog.Biome.AuthoredIds, id => EventCatalog.Biome.GetOrFallback(id));
|
|
}
|
|
|
|
private static void SeedDiscrete(string domain, IEnumerable<string> ids, Func<string, DiscreteEventEntry> get)
|
|
{
|
|
if (ids == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (string raw in ids)
|
|
{
|
|
string id = (raw ?? "").Trim();
|
|
if (string.IsNullOrEmpty(id))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
DiscreteEventEntry e = get(id);
|
|
bool camera = EventCatalog.IsCameraWorthy(e);
|
|
AddSeed(domain, id, camera, camera);
|
|
}
|
|
}
|
|
|
|
private static void AddSeed(string domain, string id, bool camera, bool inject)
|
|
{
|
|
string key = Key(domain, id);
|
|
Rows[key] = new EventLiveCoverageRow
|
|
{
|
|
Domain = domain,
|
|
Id = id,
|
|
Camera = camera,
|
|
Inject = inject,
|
|
LiveLevel = "none",
|
|
Pipeline = "",
|
|
Notes = ""
|
|
};
|
|
}
|
|
|
|
/// <summary>Overwrite live proof for one id. Does not invent catalog rows.</summary>
|
|
public static void Claim(string domain, string id, string liveLevel, string pipeline, string notes)
|
|
{
|
|
string key = Key(domain, id);
|
|
if (!Rows.TryGetValue(key, out EventLiveCoverageRow row))
|
|
{
|
|
row = new EventLiveCoverageRow
|
|
{
|
|
Domain = domain ?? "",
|
|
Id = id ?? "",
|
|
Camera = true,
|
|
Inject = false
|
|
};
|
|
Rows[key] = row;
|
|
}
|
|
|
|
row.LiveLevel = string.IsNullOrEmpty(liveLevel) ? "none" : liveLevel.Trim();
|
|
row.Pipeline = pipeline ?? "";
|
|
row.Notes = notes ?? "";
|
|
}
|
|
|
|
public static EventLiveCoverageSummary Summarize()
|
|
{
|
|
var s = new EventLiveCoverageSummary();
|
|
foreach (EventLiveCoverageRow row in Rows.Values)
|
|
{
|
|
if (row.Camera)
|
|
{
|
|
s.CameraRows++;
|
|
}
|
|
|
|
switch ((row.LiveLevel ?? "none").Trim().ToLowerInvariant())
|
|
{
|
|
case "id":
|
|
s.Id++;
|
|
break;
|
|
case "id_drop":
|
|
s.IdDrop++;
|
|
break;
|
|
case "pipeline":
|
|
s.Pipeline++;
|
|
break;
|
|
case "feed":
|
|
s.Feed++;
|
|
break;
|
|
case "unsupported":
|
|
s.Unsupported++;
|
|
break;
|
|
case "fail":
|
|
s.Fail++;
|
|
break;
|
|
default:
|
|
s.None++;
|
|
if (row.Camera)
|
|
{
|
|
s.CameraNone++;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
public static string Write(string outputDirectory)
|
|
{
|
|
var tsv = new StringBuilder();
|
|
tsv.AppendLine("domain\tid\tcamera\tinject\tlive_level\tpipeline\tnotes");
|
|
var keys = new List<string>(Rows.Keys);
|
|
keys.Sort(StringComparer.OrdinalIgnoreCase);
|
|
for (int i = 0; i < keys.Count; i++)
|
|
{
|
|
EventLiveCoverageRow row = Rows[keys[i]];
|
|
tsv.Append(row.Domain).Append('\t')
|
|
.Append(row.Id).Append('\t')
|
|
.Append(row.Camera ? "true" : "false").Append('\t')
|
|
.Append(row.Inject ? "true" : "false").Append('\t')
|
|
.Append(row.LiveLevel ?? "none").Append('\t')
|
|
.Append(row.Pipeline ?? "").Append('\t')
|
|
.Append(row.Notes ?? "").Append('\n');
|
|
}
|
|
|
|
CatalogCoverageAudit.WriteReport(outputDirectory, "event-live-coverage.tsv", tsv.ToString());
|
|
return Summarize().Detail;
|
|
}
|
|
}
|