Editor/Layers/ArchAffectors.cs
namespace Sunless.Architecture;
public interface IArchAffector {
ArchKind Kind { get; }
int Order { get; }
int Resolve( ArchPlan plan, ArchKit kit );
bool Closes( object payload );
void Close( ArchPlan plan, object payload );
}
public sealed class ArchAffectors : ArchTable<ArchAffectors, ArchKind, IArchAffector> {
protected override IEnumerable<IArchAffector> Standing() {
yield return new ArchCutEffects();
yield return new ArchTrimEffects();
yield return new ArchOpeningRunEffects();
yield return new ArchBalconyEffects();
yield return new ArchStairEffects();
yield return new ArchExteriorStairEffects();
yield return new ArchPorchEffects();
yield return new ArchApproachEffects();
yield return new ArchWalkwayAffector();
}
protected override ArchKind KeyOf( IArchAffector affector ) => affector.Kind;
protected override bool Accepts( IArchAffector affector ) => affector.Kind.Known;
protected override string Collision( IArchAffector standing, IArchAffector affector ) {
return $"{affector.Kind.Ident} affector is claimed by both {standing.GetType().Name} and {affector.GetType().Name}";
}
public IArchAffector For( ArchKind kind ) => Held( kind );
public IReadOnlyList<IArchAffector> Ordered => Entries
.OrderBy( affector => affector.Order )
.ThenBy( affector => affector.Kind.Ident, StringComparer.Ordinal )
.ToList();
public int Run( ArchPlan plan, ArchKit kit ) {
var resolved = Ordered.Sum( affector => affector.Resolve( plan, kit ) );
Tidy( plan );
return resolved;
}
public void CloseMatching( ArchPlan plan, object payload ) {
if ( plan is null || payload is null ) {
return;
}
foreach ( var affector in Ordered.Where( candidate => candidate.Closes( payload ) ) ) {
affector.Close( plan, payload );
}
}
public static int Resolve( ArchPlan plan, ArchKit kit ) => Load().Run( plan, kit );
public static void Close( ArchPlan plan, object payload ) => Load().CloseMatching( plan, payload );
static void Tidy( ArchPlan plan ) {
foreach ( var empty in plan.Assemblies.Where( group => group.Children.Count == 0 ).ToList() ) {
ArchLayerGroups.Dissolve( plan, empty );
}
}
}