tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 583HTML 275Markdown 8TOML 41586 Definiciones

⎇ morphorm src/util/debug.rs Rust · 133 líneas · 4.2 KB Historia Quién tocó qué crudo

Setup empty morphorm compute module 838c413a7 · Nico Burns ·

1#![allow(dead_code)]
2
3use crate::tree::NodeId;
4use crate::{style, LayoutTree};
5use core::fmt::{Debug, Display, Write};
6use std::sync::Mutex;
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: NodeId) {
10    println!("TREE");
11    print_node(tree, root, false, String::new());
12}
13
14fn print_node(tree: &impl LayoutTree, node: NodeId, has_sibling: bool, lines_string: String) {
15    let layout = &tree.layout(node);
16    let style = &tree.style(node);
17    let num_children = tree.child_count(node);
18
19    let display = match (num_children, style.display) {
20        (_, style::Display::None) => "NONE",
21        (0, _) => "LEAF",
22        #[cfg(feature = "block_layout")]
23        (_, style::Display::Block) => "BLOCK",
24        #[cfg(feature = "flexbox")]
25        (_, style::Display::Flex) => "FLEX",
26        #[cfg(feature = "grid")]
27        (_, style::Display::Grid) => "GRID",
28        #[cfg(feature = "morphorm")]
29        (_, style::Display::Morphorm) => "MORPHORM",
30    };
31
32    let fork_string = if has_sibling { "├── " } else { "└── " };
33    println!(
34        "{lines}{fork} {display} [x: {x:<4} y: {y:<4} width: {width:<4} height: {height:<4}] ({key:?})",
35        lines = lines_string,
36        fork = fork_string,
37        display = display,
38        x = layout.location.x,
39        y = layout.location.y,
40        width = layout.size.width,
41        height = layout.size.height,
42        key = node,
43    );
44    let bar = if has_sibling { "│   " } else { "    " };
45    let new_string = lines_string + bar;
46
47    // Recurse into children
48    for (index, child) in tree.children(node).enumerate() {
49        let has_sibling = index < num_children - 1;
50        print_node(tree, child, has_sibling, new_string.clone());
51    }
52}
53
54#[doc(hidden)]
55pub struct DebugLogger {
56    stack: Mutex<Vec<String>>,
57}
58
59static EMPTY_STRING: String = String::new();
60impl DebugLogger {
61    pub const fn new() -> Self {
62        Self { stack: Mutex::new(Vec::new()) }
63    }
64
65    pub fn push_node(&self, new_key: NodeId) {
66        let mut stack = self.stack.lock().unwrap();
67        let mut key_string = String::new();
68        write!(&mut key_string, "{:?}", new_key).unwrap();
69        stack.push(key_string);
70    }
71
72    pub fn pop_node(&self) {
73        let mut stack = self.stack.lock().unwrap();
74        stack.pop();
75    }
76
77    pub fn log(&self, message: impl Display) {
78        let stack = self.stack.lock().unwrap();
79        let key = stack.last().unwrap_or(&EMPTY_STRING);
80        let level = stack.len() * 4;
81        let space = " ";
82        println!("{space:level$}{key}: {message}");
83    }
84
85    pub fn labelled_log(&self, label: &str, message: impl Display) {
86        let stack = self.stack.lock().unwrap();
87        let key = stack.last().unwrap_or(&EMPTY_STRING);
88        let level = stack.len() * 4;
89        let space = " ";
90        println!("{space:level$}{key}: {label} {message}");
91    }
92
93    pub fn debug_log(&self, message: impl Debug) {
94        let stack = self.stack.lock().unwrap();
95        let key = stack.last().unwrap_or(&EMPTY_STRING);
96        let level = stack.len() * 4;
97        let space = " ";
98        println!("{space:level$}{key}: {message:?}");
99    }
100
101    pub fn labelled_debug_log(&self, label: &str, message: impl Debug) {
102        let stack = self.stack.lock().unwrap();
103        let key = stack.last().unwrap_or(&EMPTY_STRING);
104        let level = stack.len() * 4;
105        let space = " ";
106        println!("{space:level$}{key}: {label} {message:?}");
107    }
108}
109
110#[cfg(any(feature = "debug", feature = "profile"))]
111pub(crate) static NODE_LOGGER: DebugLogger = DebugLogger::new();
112
113#[cfg(feature = "profile")]
114#[allow(unused_macros)]
115macro_rules! time {
116    ($label:expr, $($code:tt)*) => {
117        let start = ::std::time::Instant::now();
118        $($code)*
119        let duration = ::std::time::Instant::now().duration_since(start);
120        crate::util::debug::NODE_LOGGER.log(format_args!("Performed {} in {}ms", $label, duration.as_millis()));
121    };
122}
123
124#[cfg(not(feature = "profile"))]
125#[allow(unused_macros)]
126macro_rules! time {
127    ($label:expr, $($code:tt)*) => {
128        $($code)*
129    };
130}
131
132#[allow(unused_imports)]
133pub(crate) use time;