1use std::{any::TypeId, borrow::Borrow as _};
4
5use crate::{
6 rolling_grid::RollingGrid,
7 vec2::{Bounds, Line, Point2d},
8 Chunk, Dependencies as _, Layer,
9};
10
11pub trait Debug {
15 fn debug(&self) -> Vec<DebugContent> {
17 vec![]
18 }
19}
20
21pub enum DebugContent {
23 Line(Line),
25 Circle {
27 center: Point2d,
29 radius: f32,
31 },
32 Text {
34 pos: Point2d,
36 label: String,
38 },
39}
40
41impl From<Line> for DebugContent {
42 fn from(line: Line) -> Self {
43 Self::Line(line)
44 }
45}
46
47pub trait DynLayer {
50 fn iter_all_loaded(&self) -> Box<dyn Iterator<Item = (Bounds, Box<dyn Debug + 'static>)> + '_>;
53
54 fn deps(&self) -> Vec<&dyn DynLayer>;
56
57 fn ident(&self) -> (usize, TypeId);
59
60 fn name(&self) -> String;
62}
63
64impl<C: Chunk + Debug> DynLayer for Layer<C> {
65 fn iter_all_loaded(&self) -> Box<dyn Iterator<Item = (Bounds, Box<dyn Debug + 'static>)> + '_> {
66 Box::new(
67 self.layer
68 .borrow()
69 .0
70 .iter_all_loaded()
71 .map(|(index, chunk)| {
72 (
73 C::bounds(index),
74 Box::new(chunk) as Box<dyn Debug + 'static>,
75 )
76 }),
77 )
78 }
79
80 fn deps(&self) -> Vec<&dyn DynLayer> {
81 self.debug()
82 }
83
84 fn ident(&self) -> (usize, TypeId) {
85 let ptr: *const RollingGrid<C> = &self.layer.borrow().0;
86 (ptr as usize, TypeId::of::<Self>())
87 }
88
89 fn name(&self) -> String {
90 let mut name = std::any::type_name::<C>().to_owned();
91 let mut start = 0;
92 loop {
93 while let Some((pos, _)) = name[start..]
94 .char_indices()
95 .take_while(|&(_, c)| matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | ':'))
96 .find(|&(_, c)| c == ':')
97 {
98 name.replace_range(start..(start + pos + 2), "");
99 }
100 if let Some((next, c)) = name[start..]
101 .char_indices()
102 .find(|&(_, c)| !matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '_'))
103 {
104 start += next + c.len_utf8();
105 } else {
106 break;
107 }
108 }
109 name
110 }
111}