freya_winit/
devtools.rs

1use std::sync::{
2    Arc,
3    Mutex,
4};
5
6use freya_core::{
7    dom::FreyaDOM,
8    node::{
9        get_node_state,
10        NodeState,
11    },
12};
13use freya_native_core::{
14    prelude::{
15        NodeId,
16        NodeImmutable,
17    },
18    tags::TagName,
19};
20use tokio::sync::watch;
21use torin::prelude::LayoutNode;
22
23pub type DevtoolsReceiver = watch::Receiver<Vec<NodeInfo>>;
24pub type HoveredNode = Option<Arc<Mutex<Option<NodeId>>>>;
25
26#[derive(Clone)]
27pub struct Devtools {
28    sender: watch::Sender<Vec<NodeInfo>>,
29}
30
31impl Devtools {
32    pub fn new() -> (Self, DevtoolsReceiver) {
33        let (sender, receiver) = watch::channel(Vec::new());
34
35        (Self { sender }, receiver)
36    }
37
38    pub fn update(&self, fdom: &FreyaDOM) {
39        let rdom = fdom.rdom();
40        let layout = fdom.layout();
41
42        let mut new_nodes = Vec::new();
43
44        let mut root_found = false;
45        let mut devtools_found = false;
46
47        rdom.traverse_depth_first(|node| {
48            let height = node.height();
49            if height == 3 {
50                if !root_found {
51                    root_found = true;
52                } else {
53                    devtools_found = true;
54                }
55            }
56
57            if !devtools_found && root_found {
58                let layout_node = layout.get(node.id()).cloned();
59                if let Some(layout_node) = layout_node {
60                    let node_type = node.node_type();
61                    new_nodes.push(NodeInfo {
62                        id: node.id(),
63                        parent_id: node.parent_id(),
64                        children_len: node
65                            .children()
66                            .iter()
67                            .filter(|node| layout.get(node.id()).is_some())
68                            .count(),
69                        tag: *node_type.tag().unwrap(),
70                        height: node.height(),
71                        state: get_node_state(&node),
72                        layout_node,
73                    });
74                }
75            }
76        });
77
78        self.sender
79            .send(new_nodes)
80            .expect("Failed to sync the Devtools.");
81    }
82}
83
84#[derive(Clone, PartialEq)]
85pub struct NodeInfo {
86    pub id: NodeId,
87    pub parent_id: Option<NodeId>,
88    pub children_len: usize,
89    pub tag: TagName,
90    pub height: u16,
91    pub state: NodeState,
92    pub layout_node: LayoutNode,
93}