Skip to content

Commit cd477aa

Browse files
committed
v1.1.2
1 parent 7514980 commit cd477aa

File tree

4 files changed

+70
-33
lines changed

4 files changed

+70
-33
lines changed

README.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# visualizer (v1.1.1b)
1+
# visualizer (v1.1.2)
22

33
This project aims to make a quick visual representation for a C++ project (though Python support is planned).
44

@@ -51,11 +51,10 @@ Why not use `<insert your favorite C++ parser>`?
5151
so only by using a compiler can we get a 100% correct output.
5252
Easiest example is `operator <<` which in most parsers is registered as a `binary expression`, when in reality it is a `function call`.
5353

54-
# What's new in v1.1.1?
55-
* Curved lines fix
56-
* Only showing correctly parsed functions / classes
57-
* Support for 'brute-force' mode and 'verbose mode'
58-
* Struct support
54+
# What's new in v1.1.2?
55+
* Functions defined in .h files in class are now detected
56+
* Fixed bug, when functions where doubled in structures
57+
* Lines always curve (idk, looks better)
5958

6059
# Known bugs // missing features:
6160
* Function calls inside Loop and If conditions are not registered
@@ -65,11 +64,10 @@ Easiest example is `operator <<` which in most parsers is registered as a `binar
6564
* No way to see how many times a function is called from a single line
6665
* No support for outside-of-function code
6766
* No way to resize/move in editor
68-
* No struct support
6967
* 5000 tonnes of useless debug output with no way to shut it off
7068
* It's hard to tell code structure if there are many If statements
71-
* Class constructors are not registered as function calls
72-
* If a function is defined in .h, it's not detected
69+
* Class / struct constructors are not registered as function calls
7370
* **If an included library is not found, some code may be absent!!! (this can be partually avoided by commenting the problematic include)**
7471
* No way to add libraries that shouldn't be rendered
75-
* No switch case support
72+
* No switch case support
73+
* Operator calls are not detected, even if they are user-defined

examples/segment_tree/image.webp

-3.87 KB
Loading

visualizer/tree_objects.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,20 +189,35 @@ def parse_cpp(self, cursor: clang.cindex.Cursor, bruteforce: bool, verbose: bool
189189
class Class(Node):
190190
def __init__(self, parent_node):
191191
super().__init__(parent_node)
192-
self.body_nodes = []
192+
self.body_nodes = {}
193193
self.name = ""
194194

195-
def parse_cpp(self, cursor: clang.cindex.Cursor, bruteforce: bool, verbose: bool):
195+
def parse_cpp(self, cursor: clang.cindex.Cursor, code_tree: CodeTree, bruteforce: bool, verbose: bool):
196196
self.name = cursor.spelling
197197

198-
# FIXME: parse class data (methods are parsed externally)
198+
for i in cursor.get_children():
199+
if i.kind.name == 'FIELD_DECL':
200+
pass
201+
# TODO: parse field declarations
202+
elif i.kind.name == 'CONSTRUCTOR':
203+
pass
204+
# TODO: parse struct constructor
205+
elif i.kind.name == 'CXX_METHOD':
206+
code_tree.methods[i.get_usr()] = Function(self)
207+
self.body_nodes[i.get_usr()] = code_tree.methods[i.get_usr()]
208+
code_tree.methods[i.get_usr()].parse_cpp(i, bruteforce, verbose)
209+
elif i.kind.name == 'CXX_ACCESS_SPEC_DECL':
210+
pass
211+
# nothing should be here, access specifiers are taken from methods themselves
212+
else:
213+
output_error(bruteforce, "Unknown class field: ", i.kind.name, " location: ", i.location)
199214
# TODO: add print method
200215

201216

202217
class Struct(Node):
203218
def __init__(self, parent_node):
204219
super().__init__(parent_node)
205-
self.body_nodes = []
220+
self.body_nodes = {}
206221
self.name = ""
207222

208223
def parse_cpp(self, cursor: clang.cindex.Cursor, code_tree: CodeTree, bruteforce: bool, verbose: bool):
@@ -219,7 +234,7 @@ def parse_cpp(self, cursor: clang.cindex.Cursor, code_tree: CodeTree, bruteforce
219234
# TODO: parse struct constructor
220235
elif i.kind.name == 'CXX_METHOD':
221236
code_tree.methods[i.get_usr()] = Function(self)
222-
self.body_nodes.append(code_tree.methods[i.get_usr()])
237+
self.body_nodes[i.get_usr()] = code_tree.methods[i.get_usr()]
223238
code_tree.methods[i.get_usr()].parse_cpp(i, bruteforce, verbose)
224239
elif i.kind.name == 'CXX_BASE_SPECIFIER':
225240
pass

visualizer/visualizer.py

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -122,19 +122,25 @@ def parse_cpp_file(self, file_path: str) -> None:
122122
elif cursor.kind.name == 'CLASS_DECL':
123123
if self.code_tree.classes.get(cursor.get_usr()) is None:
124124
self.code_tree.classes[cursor.get_usr()] = Class(None)
125-
self.code_tree.classes[cursor.get_usr()].parse_cpp(cursor, self.bruteforce, self.verbose)
125+
self.code_tree.classes[cursor.get_usr()].parse_cpp(cursor, self.code_tree, self.bruteforce,
126+
self.verbose)
126127
elif cursor.kind.name == 'STRUCT_DECL':
127128
if self.code_tree.structures.get(cursor.get_usr()) is None:
128129
self.code_tree.structures[cursor.get_usr()] = Struct(None)
129-
self.code_tree.structures[cursor.get_usr()].parse_cpp(cursor, self.code_tree, self.bruteforce, self.verbose)
130+
self.code_tree.structures[cursor.get_usr()].parse_cpp(cursor, self.code_tree, self.bruteforce,
131+
self.verbose)
130132
else:
131133
output_error(self.bruteforce, "Error: ", cursor.kind.name, " not supported!!")
132134

133135
def detect_all_objects(self, node):
134136
self.code_tree.nodes.append(node)
135137
if type(node) != CodeLine:
136138
for i in node.body_nodes:
137-
self.detect_all_objects(i)
139+
if type(i) == str:
140+
# this is a dictionary
141+
self.detect_all_objects(node.body_nodes[i])
142+
else:
143+
self.detect_all_objects(i)
138144
if type(node) == If:
139145
for i in node.else_nodes:
140146
self.detect_all_objects(i)
@@ -219,7 +225,12 @@ def set_graphics_info(self, node):
219225
self.graphics_info[node] = NodeGraphicsInfo(node)
220226
if type(node) != CodeLine:
221227
for i in node.body_nodes:
222-
self.set_graphics_info(i)
228+
if type(i) == str:
229+
# this is a dictionary
230+
self.set_graphics_info(node.body_nodes[i])
231+
else:
232+
self.set_graphics_info(i)
233+
223234
# FIXME: probably this if type(node) == If thing should have a more elegant solution
224235
if type(node) == If:
225236
for i in node.else_nodes:
@@ -314,19 +325,22 @@ def compute_node_size(self, node, scaler: Scaler) -> None:
314325
self.graphics_info[node].size_y = 0 + scaler.BUFFER_SIZE_CLASS_VERTICAL * (len(node.body_nodes) + 1)
315326
# calculate new size:
316327
for i in node.body_nodes:
317-
self.compute_node_size(i, scaler)
318-
self.graphics_info[node].size_y += self.graphics_info[i].size_y
328+
self.compute_node_size(node.body_nodes[i], scaler)
329+
self.graphics_info[node].size_y += self.graphics_info[node.body_nodes[i]].size_y
319330
self.graphics_info[node].size_x = max(self.graphics_info[node].size_x,
320-
self.graphics_info[i].size_x + scaler.BUFFER_SIZE_HORIZONTAL * 2)
331+
self.graphics_info[node.body_nodes[i]].size_x +
332+
scaler.BUFFER_SIZE_HORIZONTAL * 2)
333+
321334
elif type(node) == Struct:
322335
self.graphics_info[node].size_x = 0
323336
self.graphics_info[node].size_y = 0 + scaler.BUFFER_SIZE_CLASS_VERTICAL * (len(node.body_nodes) + 1)
324337
# calculate new size:
325338
for i in node.body_nodes:
326-
self.compute_node_size(i, scaler)
327-
self.graphics_info[node].size_y += self.graphics_info[i].size_y
339+
self.compute_node_size(node.body_nodes[i], scaler)
340+
self.graphics_info[node].size_y += self.graphics_info[node.body_nodes[i]].size_y
328341
self.graphics_info[node].size_x = max(self.graphics_info[node].size_x,
329-
self.graphics_info[i].size_x + scaler.BUFFER_SIZE_HORIZONTAL * 2)
342+
self.graphics_info[node.body_nodes[i]].size_x +
343+
scaler.BUFFER_SIZE_HORIZONTAL * 2)
330344
else:
331345
raise RuntimeError("unknown type:", type(node))
332346

@@ -374,15 +388,15 @@ def compute_node_position(self, node, scaler: Scaler, offset_x: int, offset_y: i
374388
offset_x += scaler.BUFFER_SIZE_HORIZONTAL
375389
for i in node.body_nodes:
376390
offset_y -= scaler.BUFFER_SIZE_CLASS_VERTICAL
377-
offset_y -= self.graphics_info[i].size_y
378-
self.compute_node_position(i, scaler, offset_x, offset_y)
391+
offset_y -= self.graphics_info[node.body_nodes[i]].size_y
392+
self.compute_node_position(node.body_nodes[i], scaler, offset_x, offset_y)
379393
elif type(node) == Struct:
380394
offset_y += self.graphics_info[node].size_y
381395
offset_x += scaler.BUFFER_SIZE_HORIZONTAL
382396
for i in node.body_nodes:
383397
offset_y -= scaler.BUFFER_SIZE_CLASS_VERTICAL
384-
offset_y -= self.graphics_info[i].size_y
385-
self.compute_node_position(i, scaler, offset_x, offset_y)
398+
offset_y -= self.graphics_info[node.body_nodes[i]].size_y
399+
self.compute_node_position(node.body_nodes[i], scaler, offset_x, offset_y)
386400
else:
387401
raise RuntimeError("unknown type:", type(node))
388402

@@ -410,17 +424,21 @@ def quadBezier(t, p0, p1, p2):
410424
prev_point_x = self.graphics_info[node].start_pos_x
411425
prev_point_y = self.graphics_info[node].start_pos_y
412426

427+
curvature_sign = 1
428+
if self.graphics_info[node].end_pos_x - self.graphics_info[node].start_pos_x > 0:
429+
curvature_sign = -1
430+
413431
while t < 1.001:
414432
v = [self.graphics_info[node].end_pos_x - self.graphics_info[node].start_pos_x,
415433
self.graphics_info[node].end_pos_y - self.graphics_info[node].start_pos_y]
416434
perp_v = [v[1], -v[0]]
417435
x = quadBezier(t, self.graphics_info[node].start_pos_x,
418436
(self.graphics_info[node].start_pos_x + self.graphics_info[node].end_pos_x) // 2 +
419-
perp_v[0] * self.scaler.LINE_CURVATURE,
437+
perp_v[0] * self.scaler.LINE_CURVATURE * curvature_sign,
420438
self.graphics_info[node].end_pos_x)
421439
y = quadBezier(t, self.graphics_info[node].start_pos_y,
422440
(self.graphics_info[node].start_pos_y + self.graphics_info[node].end_pos_y) // 2 +
423-
perp_v[1] * self.scaler.LINE_CURVATURE,
441+
perp_v[1] * self.scaler.LINE_CURVATURE * curvature_sign,
424442
self.graphics_info[node].end_pos_y)
425443
arcade.draw_line(prev_point_x, prev_point_y,
426444
x, y,
@@ -459,8 +477,14 @@ def recursive_node_draw(self, node):
459477
if type(node) != CodeLine:
460478
offset_y = 0
461479
for i in node.body_nodes:
462-
self.recursive_node_draw(i)
463-
offset_y += self.graphics_info[i].size_y + self.scaler.BUFFER_SIZE_VERTICAL
480+
if type(i) == str:
481+
# this is a dictionary
482+
self.recursive_node_draw(node.body_nodes[i])
483+
offset_y += self.graphics_info[node.body_nodes[i]].size_y + self.scaler.BUFFER_SIZE_VERTICAL
484+
else:
485+
self.recursive_node_draw(i)
486+
offset_y += self.graphics_info[i].size_y + self.scaler.BUFFER_SIZE_VERTICAL
487+
464488
if type(node) == If and node.else_nodes:
465489
arcade.draw_line(self.graphics_info[node].pos_x,
466490
self.graphics_info[node].pos_y + self.graphics_info[node].size_y - offset_y,

0 commit comments

Comments
 (0)