Layout algorithm decoupling, Sizing Constraints & Perf Improvements (#246)
1use core::fmt::{Debug, Display, Write};
2use slotmap::Key;
3use std::sync::Mutex;
4
5use crate::node::Node;
6use crate::tree::LayoutTree;
7
8/// Prints a debug representation of the computed layout for a tree of nodes, starting with the passed root node.
9pub fn print_tree(tree: &impl LayoutTree, root: Node) {
10 println!();
11 print_node(tree, root, 0);
12}
13
14fn print_node(tree: &impl LayoutTree, node: Node, level: usize) {
15 let layout = tree.layout(node);
16 println!(
17 "{space:leftpad$}{key:?} (x:{x}, y: {y}, width: {width}, height: {height})",
18 space = " ",
19 leftpad = level * 4,
20 key = node.data(),
21 x = layout.location.x,
22 y = layout.location.y,
23 width = layout.size.width,
24 height = layout.size.height,
25 );
26
27 // Recurse into children
28 for child in tree.children(node) {
29 print_node(tree, *child, level + 1)
30 }
31}
32
33#[doc(hidden)]
34pub struct DebugLogger {
35 stack: Mutex<Vec<String>>,
36}
37
38static EMPTY_STRING: String = String::new();
39impl DebugLogger {
40 pub const fn new() -> Self {
41 Self { stack: Mutex::new(Vec::new()) }
42 }
43
44 pub fn push_node(&self, new_key: impl Key) {
45 let mut stack = self.stack.lock().unwrap();
46 let mut key_string = String::new();
47 write!(&mut key_string, "{:?}", new_key.data()).unwrap();
48 stack.push(key_string);
49 }
50
51 pub fn pop_node(&self) {
52 let mut stack = self.stack.lock().unwrap();
53 stack.pop();
54 }
55
56 pub fn log(&self, message: impl Display) {
57 let stack = self.stack.lock().unwrap();
58 let key = stack.last().unwrap_or(&EMPTY_STRING);
59 let level = stack.len() * 4;
60 let space = " ";
61 println!("{space:level$}{key}: {message}");
62 }
63
64 pub fn labelled_log(&self, label: &str, message: impl Display) {
65 let stack = self.stack.lock().unwrap();
66 let key = stack.last().unwrap_or(&EMPTY_STRING);
67 let level = stack.len() * 4;
68 let space = " ";
69 println!("{space:level$}{key}: {label} {message}");
70 }
71
72 pub fn debug_log(&self, message: impl Debug) {
73 let stack = self.stack.lock().unwrap();
74 let key = stack.last().unwrap_or(&EMPTY_STRING);
75 let level = stack.len() * 4;
76 let space = " ";
77 println!("{space:level$}{key}: {message:?}");
78 }
79
80 pub fn labelled_debug_log(&self, label: &str, message: impl Debug) {
81 let stack = self.stack.lock().unwrap();
82 let key = stack.last().unwrap_or(&EMPTY_STRING);
83 let level = stack.len() * 4;
84 let space = " ";
85 println!("{space:level$}{key}: {label} {message:?}");
86 }
87}
88
89#[cfg(feature = "debug")]
90pub(crate) static NODE_LOGGER: DebugLogger = DebugLogger::new();