1 #include "layout_computer.hh"
2 #include "layout.hh"
3 #include "structure.hh"
4 #include "node_tree.hh"
5 #include "shape.hh"
6 #include "../utils/std_ext.hh"
7 #include "../utils/perf_helper.hh"
8 
9 #include "cursors/layout_cursor.hh"
10 #include "cursors/nodevisitor.hh"
11 
12 #include <QMutex>
13 #include <QDebug>
14 #include <thread>
15 #include <iostream>
16 
17 namespace cpprofiler
18 {
19 namespace tree
20 {
21 
LayoutComputer(const NodeTree & tree,Layout & layout,const VisualFlags & nf)22 LayoutComputer::LayoutComputer(const NodeTree &tree, Layout &layout, const VisualFlags &nf)
23     : m_tree(tree), m_layout(layout), m_vis_flags(nf)
24 {
25 }
26 
isDirty(NodeID nid)27 bool LayoutComputer::isDirty(NodeID nid)
28 {
29     return m_layout.isDirty(nid);
30 }
31 
setDirty(NodeID nid)32 void LayoutComputer::setDirty(NodeID nid)
33 {
34 
35     utils::MutexLocker lock(&m_layout.getMutex());
36 
37     m_layout.setDirty(nid, true);
38 }
39 
dirtyUpUnconditional(NodeID n)40 void LayoutComputer::dirtyUpUnconditional(NodeID n)
41 {
42     while (n != NodeID::NoNode)
43     {
44         m_layout.setDirty(n, true);
45         n = m_tree.getParent(n);
46     }
47 }
48 
dirtyUp(NodeID nid)49 void LayoutComputer::dirtyUp(NodeID nid)
50 {
51     while (nid != NodeID::NoNode && !m_layout.isDirty(nid))
52     {
53         m_layout.setDirty(nid, true);
54         nid = m_tree.getParent(nid);
55     }
56 }
57 
dirtyUpLater(NodeID nid)58 void LayoutComputer::dirtyUpLater(NodeID nid)
59 {
60     // if (m_layout.ready(nid))
61     // {
62     // print("dirty up {} later", nid);
63     du_node_set_.insert(nid);
64     // }
65 }
66 
compute()67 bool LayoutComputer::compute()
68 {
69 
70     /// do nothing if there is no nodes
71 
72     if (m_tree.nodeCount() == 0)
73         return false;
74 
75     /// TODO: come back here (ensure mutexes work correctly)
76     utils::MutexLocker tree_lock(&m_tree.treeMutex());
77     utils::MutexLocker layout_lock(&m_layout.getMutex());
78 
79     /// Ensures that sufficient memory is allocated for every node's shape
80     m_layout.growDataStructures(m_tree.nodeCount());
81 
82     // print("to dirty up size: {}", du_node_set_.size());
83 
84     for (auto n : du_node_set_)
85     {
86         dirtyUp(n);
87     }
88 
89     du_node_set_.clear();
90 
91     LayoutCursor lc(m_tree.getRoot(), m_tree, m_vis_flags, m_layout, debug_mode_);
92     PostorderNodeVisitor<LayoutCursor>(lc).run();
93 
94     static int counter = 0;
95     // std::cerr << "computed layout " << ++counter   << " times\n";
96 
97     return true;
98 }
99 
100 } // namespace tree
101 } // namespace cpprofiler