Utility that decides layer ordering for architecture operations. It determines if one layer operation precedes another based on explicit recorded Order within a shared parent, falling back to monotonic ItemId. It also decides whether an operation applies to a given standing layer (including anonymous host 0).
using System.Collections.Generic;
using System.Linq;
namespace Sunless.Architecture;
// WHICH OPERATION HAPPENS FIRST - asked here and nowhere else, because the stack is an ordered operation
// stack and every operation in it obeys the same order. A part standing when a later operation runs is
// subject to it; a part added afterwards is not. Carve a zone and then hang slats in it and the slats are
// whole; hang the slats and then carve over them and the carve takes them.
//
// The answer is the explicit stack position where the author has set one - that is what dragging a row in
// the stack writes - and otherwise the order the two were authored in, which the monotonic id already
// records. Nothing else may re-derive this: a second opinion about order is a part that is carved in the
// generator and whole in the preview.
public static class ArchLayerOrder
{
public static bool Precedes( ArchPlan plan, int itemId, int otherId )
{
if ( itemId == 0 || otherId == 0 || itemId == otherId )
{
return false;
}
var mine = Record( plan, itemId );
var theirs = Record( plan, otherId );
if ( mine is not null && theirs is not null && mine.ParentId == theirs.ParentId && mine.Order != theirs.Order )
{
return mine.Order < theirs.Order;
}
return itemId < otherId;
}
// The operations a host is subject to: the ones authored after it. A host of 0 is anonymous - a derived
// slab with no layer of its own - and everything reaches it, which is how the generator behaved before
// any of this was ordered.
public static bool Applies( ArchPlan plan, int operationId, int standingId )
{
return standingId == 0 || operationId == 0 || Precedes( plan, standingId, operationId );
}
static ArchLayerRecord Record( ArchPlan plan, int itemId )
{
if ( ArchBuildMemo.Current is { } memo )
{
return memo.Records.TryGetValue( itemId, out var held ) ? held : null;
}
return plan?.Layers?.FirstOrDefault( record => record.ItemId == itemId );
}
}