decideSurface function

SurfaceDecision decideSurface(
  1. SurfaceArrival arrival,
  2. Iterable<SurfaceOccupant> occupants, {
  3. String? slot,
})

Decides an organic arrival against every occupant.

With several blockers, the one reported is the first in column order (blocking kinds before a collapsed floater before inline), which is the occupant the matrix cell names.

Implementation

SurfaceDecision decideSurface(
  SurfaceArrival arrival,
  Iterable<SurfaceOccupant> occupants, {
  String? slot,
}) {
  final row = _matrix[arrival]!;
  SurfaceOccupant? blocker;
  _Column? blockerColumn;
  SurfaceOccupant? replace;
  for (final occupant in occupants) {
    final column = _columnOf(occupant, slot);
    final cell = row[column] ?? _Cell.show;
    final busy = switch (cell) {
      _Cell.show => false,
      _Cell.busy => true,
      // A real campaign never displaces a test, displayed or not.
      _Cell.sameSlot => occupant.displayed || occupant.isLiveTest,
    };
    if (busy) {
      if (blockerColumn == null || column.index < blockerColumn.index) {
        blocker = occupant;
        blockerColumn = column;
      }
    } else if (cell == _Cell.sameSlot) {
      replace = occupant;
    }
  }
  if (blocker != null) return SurfaceBusy(blocker);
  if (replace != null) return SurfaceReplace(replace);
  return const SurfaceShow();
}