blob: 391beedf4503ad0894d7bceccea338710f3e1e0d [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:collection';
import 'tile_model.dart';
import 'tiler_model.dart';
Iterable<TileModel> flatten(Iterable<TileModel> tiles) {
return tiles
.map((tile) => tile.isContent ? [tile] : flatten(tile.tiles))
.expand((t) => t);
}
/// A co-routine to iterate over the TilerModel tree.
Iterable<TileModel> tilerWalker(TilerModel a) sync* {
final nodes = ListQueue<TileModel>()..add(a.root);
while (nodes.isNotEmpty) {
nodes.addAll(nodes.first.tiles);
yield nodes.removeFirst();
}
}
/// Get the content nodes of a layout tree.
List<TileModel> getTileContent(TilerModel a) => tilerWalker(a)
.where((t) => t.type == TileType.content)
.fold(<TileModel>[], (l, t) => l..add(t));
enum Traversal { depthFirst, depthLast }
/// Traverse the tree rooted at [tile] in [order] and call [callback] at each
/// node, unless [contentOnly] was set to [true].
void traverse<T>({
TileModel<T> tile,
Traversal order = Traversal.depthFirst,
bool contentOnly = false,
void callback(TileModel<T> tile, TileModel<T> parent),
}) {
void _traverse(TileModel<T> t, TileModel<T> p) {
if (t.isContent || !contentOnly) {
callback(t, p);
}
final it = order == Traversal.depthFirst ? t.tiles : t.tiles.reversed;
for (final c in it) {
_traverse(c, t);
}
}
_traverse(tile, tile.parent);
}