buildQuilt method
Builds a quilt from a range of tiles, optimizing placement for minimal variance.
Generates StaggeredGrid from selected tiles, handling holes if allowed and falling back to single-post quilts. Logs performance in debug mode. Central algorithm in buildQuilts, integrating with createGrid for rendering.
Implementation
QuiltResult buildQuilt(int start, {int? maxPosts}) {
PrecisionStopwatch? p = kDebugMode ? PrecisionStopwatch.start() : null;
List<StaggeredGridTile> tiles = [];
List<int> heights = List.filled(style.carpetWidth, 0);
int index = start;
int fbMaxH = style.maxQuiltHeight;
int maxIndex = start + (maxPosts ?? tileFaucet.buffer.length - start);
while (index < tileFaucet.buffer.length && index < maxIndex) {
T post = tileFaucet.buffer[index];
List<QSize> poss = getQSizeList(post, style.maxSizeOptions * 2);
List<TileOption> options = [];
for (QSize size in poss) {
List<int>? newHeights = placeTile(heights, size.w, size.h, fbMaxH);
if (newHeights == null) continue;
double avgHeight =
newHeights.reduce((a, b) => a + b) / style.carpetWidth;
double variance = newHeights.fold<double>(
0, (sum, h) => sum + (h - avgHeight).abs()) /
style.carpetWidth;
options.add(TileOption(
size: size,
newHeights: newHeights,
variance: variance,
d: size.d,
));
}
bool placed = false;
if (options.isNotEmpty) {
options.sort((a, b) =>
(a.d + a.variance * 0.1).compareTo(b.d + b.variance * 0.1));
TileOption chosen = options[0];
if (options.length > 1 && options[1].variance < chosen.variance) {
chosen = options[1];
}
StaggeredGridTile tile = createTile(post, chosen.size.w, chosen.size.h);
tiles.add(tile);
heights = chosen.newHeights;
placed = true;
} else if (!style.allowHoles) {
List<int>? newHeights = placeTile(heights, 1, 1, fbMaxH);
if (newHeights != null) {
StaggeredGridTile tile = createTile(post, 1, 1);
tiles.add(tile);
heights = newHeights;
placed = true;
}
}
if (!placed) {
break;
}
index++;
}
int used = index - start;
if (used == 0 && start < tileFaucet.buffer.length) {
return buildSinglePostQuilt(tileFaucet.buffer[start]);
}
if (kDebugMode) {
info(
"[CARPET] Built quilt of <$used> posts in ${p!.getMilliseconds()}ms (${quiltBuffer.length} quilts)");
}
return QuiltResult(
widget: createGrid(tiles),
used: used,
);
}