Utility that decides whether a given architectural scope (building/road) should be skipped during a build. It computes a scope key using ArchLayerHash, records keys for each queried scope, and compares against a provided standing map and refused set to determine skips.
using System.Collections.Generic;
namespace Sunless.Architecture;
// Which scopes this build may leave alone entirely - not generated, not finished, not touched. A scope is a
// building or a road, keyed through ArchLayerHash: the group it stands in, plus everything that reaches out of
// every group. Nothing here decides what a layer's identity IS; it only asks.
//
// Absent, every scope builds - which is what a cold build, a designer stage and a preview all want.
public sealed class ArchBuildGate
{
readonly Dictionary<int, ulong> standing;
readonly IReadOnlySet<int> refused;
readonly ArchPlan plan;
readonly ulong wide;
public ArchBuildGate( ArchPlan plan, ArchKit kit, int terrain, Dictionary<int, ulong> standing, IReadOnlySet<int> refused )
{
this.plan = plan;
this.standing = standing;
this.refused = refused;
wide = ArchLayerHash.Wide( plan, kit, terrain );
}
public Dictionary<int, ulong> Keys { get; } = new();
// Asked once per scope, and it RECORDS as it answers - the key it just computed is what the next build
// compares against, so a scope can never be skipped twice off one stale reading.
public bool Skips( int itemId )
{
var key = ArchLayerHash.Scope( wide, plan, itemId );
Keys[itemId] = key;
if ( refused is not null && refused.Contains( itemId ) )
{
return false;
}
return standing is not null && standing.TryGetValue( itemId, out var held ) && held == key;
}
}