TreeDebugView.cpp
Go to the documentation of this file.
1 #include "TreeDebugView.hpp"
2 #include "../Basics/utils.hpp"
3 #include "../Instancing/Instance.hpp"
4 
5 namespace iv
6 {
7 
9  TextDebugView( context ),
10  root( nullptr, "", BoxStyle::Default ),
11  current( &this->root )
12 {
13 }
14 
15 void TreeDebugView::Push( const char * node_name, BoxStyle box_style )
16 {
17  this->endline();
18  Node * node = new Node( this->current, node_name, box_style );
19  this->current->children.push_back( node );
20  this->current = node;
21 }
22 
24 {
25  if( !this->current->parent )
26  {
27  this->context()->warning( SRC_INFO, "Can not pop. This is root." );
28  return;
29  }
30 
31  this->endline();
32  this->current = this->current->parent;
33 }
34 
35 void TreeDebugView::Write( Style style, TextDebugView * target )
36 {
37  //
38  this->endline();
39 
40  // print all
41  this->draw_node_children( style, target, &this->root );
42 }
43 
45 {
46  //
47  this->endline();
48 
49  // clear
50  this->current = &this->root;
51  this->root.children.clear();
52 }
53 
55 {
56  if( this->current == &this->root )
57  {
58  this->context()->warning( SRC_INFO, "There is not an active node. Can not print line." );
59  return;
60  }
61 
62  this->endline();
63 
64  this->current->separators.insert( this->current->lines.size() - 1 );
65 }
66 
67 void TreeDebugView::print_line( const char * prefix, const char * line, const char * postfix )
68 {
69  if( this->current == &this->root )
70  {
71  this->context()->warning( SRC_INFO, "There is not an active node. Can not print line." );
72  return;
73  }
74 
75  this->current->lines.push_back( std::string( prefix ) + std::string( line ) + std::string( postfix ) );
76 }
77 
78 void TreeDebugView::draw_node_children( Style style, TextDebugView * target, Node * node )
79 {
80  std::vector< const char * > c;
81  if( style == Style::BoldFramesWeakLinks )
82  {
83  c =
84  {
85  "│", // link_line
86  "├", // link_nonlast
87  "└", // link_last
88 
89  "━", // hor
90  "╸", // hor_lhalf
91  "╺", // hor_rhalf
92  "┯", // hor_linkout
93 
94  "┃", // vert
95  "┨", // vert_linkin
96 
97  "┏", // corner_tl
98  "┗", // corner_bl
99  "┓", // corner_tr
100  "┛", // corner_br
101 
102  "╍", // hor (dotted)
103  "╏", // vert (dotted)
104  "┏", // corner_tl (dotted)
105  "┗", // corner_bl (dotted)
106  "┓", // corner_tr (dotted)
107  "┛", // corner_br (dotted)
108  };
109  }
110  else
111  {
112  if( style != Style::WeakFramesWeakLinks )
113  this->context()->warning( SRC_INFO, "Unimplemented style." );
114 
115  c =
116  {
117  "│", // link_line
118  "├", // link_nonlast
119  "└", // link_last
120 
121  "─", // hor
122  "╴", // hor_lhalf
123  "╶", // hor_rhalf
124  "┬", // hor_linkout
125 
126  "│", // vert
127  "┤", // vert_linkin
128 
129  "┌", // corner_tl
130  "└", // corner_bl
131  "┐", // corner_tr
132  "┘", // corner_br
133 
134  "╌", // hor (dotted)
135  "╎", // vert (dotted)
136  "╭", // corner_tl (dotted)
137  "╰", // corner_bl (dotted)
138  "╮", // corner_tr (dotted)
139  "╯", // corner_br (dotted)
140  };
141  }
142 
143 
144  const int link_line = 0;
145  const int link_nonlast = 1;
146  const int link_last = 2;
147  int hor = 3;
148  const int hor_lhalf = 4;
149  const int hor_rhalf = 5;
150  const int hor_linkout = 6;
151  int vert = 7;
152  const int vert_linkin = 8;
153  int corner_tl = 9;
154  int corner_bl = 10;
155  int corner_tr = 11;
156  int corner_br = 12;
157 
158 
159  for( size_t ci = 0; ci < node->children.size(); ci++ )
160  {
161  //
162  Node * ch = node->children[ ci ];
163  bool last = ci == node->children.size() - 1;
164 
165  //
166  if( ch->box_style == BoxStyle::Dotted )
167  {
168  hor = 13;;
169  vert = 14;
170 
171  corner_tl = 15;
172  corner_bl = 16;
173  corner_tr = 17;
174  corner_br = 18;
175  }
176  else
177  {
178  hor = 3;
179  vert = 7;
180 
181  corner_tl = 9;
182  corner_bl = 10;
183  corner_tr = 11;
184  corner_br = 12;
185  }
186 
187  //-------- print self -----------
188  // compute line width
189  size_t inner_width = 0;
190  for( std::string const & l : ch->lines )
191  inner_width = std::max( inner_width, utf8_size( l ) );
192  inner_width = std::max( inner_width, utf8_size( ch->name ) + 6 );
193 
194  // header
195  if( node != &this->root )
196  target->out() <<" "<<c[ link_line ];
197  if( ch->name.size() )
198  target->out() <<c[ corner_tl ]<<c[ hor ]<<c[ hor ]<<c[ hor_lhalf ]<< ch->name <<c[ hor_rhalf ]<<c[ hor ]<<c[ hor ];
199  else
200  target->out() <<c[ corner_tl ]<<c[ hor ]<<c[ hor ]<<c[ hor ]<<c[ hor ]<<c[ hor ]<<c[ hor ];
201  for( size_t i = utf8_size( ch->name ) + 6; i < inner_width ; i++ )
202  target->out() << c[ hor ];
203  target->out() << c[ corner_tr ] << std::endl;
204 
205  // first line
206  if( node != &this->root )
207  {
208  if( last )
209  target->out() <<" "<<c[ link_last ]<<c[ vert_linkin ];
210  else
211  target->out() <<" "<<c[ link_nonlast ]<<c[ vert_linkin ];
212  }
213  else
214  {
215  target->out() << c[ vert ];
216  }
217 
218  if( ch->lines.size() )
219  {
220  target->out() << ch->lines[ 0 ];
221  for( size_t i = utf8_size( ch->lines[ 0 ] ); i < inner_width; i++ )
222  target->out() << " ";
223  target->out() << c[ vert ] << std::endl;
224  }
225  else
226  {
227  for( size_t i = 0; i < inner_width; i++ )
228  target->out() << " ";
229  target->out() << c[ vert ] << std::endl;
230  }
231 
232  // one character prefix for next lines
233  if( node != &this->root )
234  {
235  if( last )
236  target->prefix_push( " " );
237  else
238  target->prefix_push( ( std::string( " " ) + c[ link_line ] ).c_str() );
239  }
240 
241  // separator for first line
242  if( ch->separators.count( 0 ) )
243  {
244  target->out() << c[ vert ];
245  for( size_t j = 0; j < inner_width; j++ )
246  target->out() << c[ hor ];
247  target->out() << c[ vert ] << std::endl;
248  }
249 
250 
251  {
252  // print rest of lines
253  for( size_t i = 1; i < ch->lines.size(); i++ )
254  {
255  target->out() << c[ vert ] << ch->lines[ i ];
256  for( size_t j = utf8_size( ch->lines[ i ] ); j < inner_width; j++ )
257  target->out() << " ";
258  target->out() << c[ vert ] << std::endl;
259 
260  // separator
261  if( ch->separators.count( i ) && i < ch->lines.size() - 1 )
262  {
263  target->out() << c[ vert ];
264  for( size_t j = 0; j < inner_width; j++ )
265  target->out() << c[ hor ];
266  target->out() << c[ vert ] << std::endl;
267  }
268  }
269 
270  // footer
271  if( ch->children.size() )
272  target->out() <<c[ corner_bl ]<<c[ hor_linkout ];
273  else
274  target->out() <<c[ corner_bl ]<<c[ hor ];
275  for( size_t i = 1; i < inner_width; i++ )
276  target->out() << c[ hor ];
277  target->out() << c[ corner_br ] << std::endl;
278 
279  // print children
280  this->draw_node_children( style, target, ch );
281  }
282 
283  //
284  if( node != &this->root )
285  target->prefix_pop();
286  }
287 }
288 
289 }