Skip to content

Commit eaea02c

Browse files
committed
v1.1.3a
1 parent 5cd8ad0 commit eaea02c

File tree

4 files changed

+59
-31
lines changed

4 files changed

+59
-31
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# visualizer (v1.1.3)
1+
# visualizer (v1.1.3a)
22

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

@@ -67,6 +67,12 @@ Easiest example is `operator <<` which in most parsers is registered as a `binar
6767
* OMG, FINALLY RESIZE!!! (literally took 10 min to implement, no idea why didn't do it earlier)
6868
* OMG, FINALLY MOVE AROUND!!! (literally took another 10 min to implement, no idea why didn't do it earlier)
6969

70+
Alpha patch:
71+
72+
* Reduced number of line segments when drawing a curve, improved performance x2, almost not noticeable.
73+
* Various code improvements
74+
* Added FPS meter to verbose mode
75+
7076
# Known bugs // missing features:
7177
* Function calls inside Loop and If conditions are not registered
7278
* No way to see actual code from visualizer
@@ -81,4 +87,4 @@ Easiest example is `operator <<` which in most parsers is registered as a `binar
8187
* No way to add libraries that shouldn't be rendered
8288
* No switch case support
8389
* Operator calls are not detected, even if they are user-defined
84-
* On large projects moving/resizing is quite CPU-intensive and takes significant time
90+
* On large projects moving/resizing is quite CPU-intensive and takes significant time (projects of around 1500 lines of code are rendered at around 7-8 FPS)

visualizer/tree_objects.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ def parse_cpp(self, cursor: clang.cindex.Cursor, code_tree: CodeTree, bruteforce
202202
elif i.kind.name == 'CONSTRUCTOR':
203203
pass
204204
# TODO: parse struct constructor
205+
elif i.kind.name == 'DESTRUCTOR':
206+
pass
207+
# TODO: parse struct destructor
205208
elif i.kind.name == 'CXX_METHOD':
206209
code_tree.methods[i.get_usr()] = Function(self)
207210
self.body_nodes[i.get_usr()] = code_tree.methods[i.get_usr()]

visualizer/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def output_error(brute_force: bool, *args):
4343

4444
def output_verbose(verbose: bool, *args):
4545
if verbose:
46-
info_print(args)
46+
info_print(*args)
4747

4848

4949
class Scaler:

visualizer/visualizer.py

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import enum
88
import os.path
99
import sys
10+
import time
1011

1112
import clang.cindex
1213

@@ -215,10 +216,14 @@ def __init__(self, scale: float):
215216

216217
self.should_redraw = False
217218
self.a = False
219+
# FIXME: make this 'a' a proper thing (it's used for showing blocks)
220+
221+
self.bruteforce = False
222+
self.verbose = False
218223

219224
self.global_offset_x = 100
220225
self.global_offset_y = 0
221-
# FIXME: make this 'a' a proper thing (it's used for showing blocks)
226+
222227
# TODO: add side-by-side code comparison
223228

224229
def set_graphics_info(self, node):
@@ -240,7 +245,10 @@ def set_graphics_info(self, node):
240245
self.set_graphics_info(i)
241246

242247
def parse(self, target: str, mode: ParseModes, bruteforce: bool, verbose: bool) -> None:
243-
self.parser.parse(target, mode, bruteforce, verbose)
248+
self.bruteforce = bruteforce
249+
self.verbose = verbose
250+
251+
self.parser.parse(target, mode, self.bruteforce, self.verbose)
244252
# FIXME: make one loop instead of two to reduce code duplicates
245253
for i in self.parser.code_tree.roots:
246254
self.set_graphics_info(i)
@@ -255,7 +263,8 @@ def on_resize(self, width: float, height: float):
255263
tmp_offset_x = 0
256264

257265
for i in self.parser.code_tree.roots:
258-
self.compute_node_position(i, self.scaler, self.global_offset_x + tmp_offset_x, self.global_offset_y + (self.height - self.graphics_info[i].size_y) // 2)
266+
self.compute_node_position(i, self.scaler, self.global_offset_x + tmp_offset_x,
267+
self.global_offset_y + (self.height - self.graphics_info[i].size_y) // 2)
259268
tmp_offset_x += self.scaler.OBJECTS_BUFFER
260269
tmp_offset_x += self.graphics_info[i].size_x
261270

@@ -405,6 +414,7 @@ def compute_node_position(self, node, scaler: Scaler, offset_x: int, offset_y: i
405414

406415
def on_draw(self):
407416
if self.should_redraw:
417+
start_time = time.time()
408418
arcade.start_render()
409419

410420
for i in self.parser.code_tree.roots:
@@ -415,13 +425,17 @@ def on_draw(self):
415425
arcade.finish_render()
416426
self.should_redraw = False
417427

428+
end_time = time.time()
429+
output_verbose(self.verbose, "Code redraw took:", end_time - start_time,
430+
"seconds (" + str(1 / (end_time - start_time)), "FPS)")
431+
418432
def function_call_draw(self, node):
419-
if node.target != None:
420-
def quadBezier(t, p0, p1, p2):
433+
if node.target is not None:
434+
def quad_bezier(t, p0, p1, p2):
421435
return (1 - t) ** 2 * p0 + 2 * (1 - t) * t * p1 + t ** 2 * p2
422436

423437
t = 0
424-
num_segments = 100
438+
num_segments = 20
425439
block = 1 / num_segments
426440

427441
prev_point_x = self.graphics_info[node].start_pos_x
@@ -431,18 +445,20 @@ def quadBezier(t, p0, p1, p2):
431445
if self.graphics_info[node].end_pos_x - self.graphics_info[node].start_pos_x > 0:
432446
curvature_sign = -1
433447

448+
v = [self.graphics_info[node].end_pos_x - self.graphics_info[node].start_pos_x,
449+
self.graphics_info[node].end_pos_y - self.graphics_info[node].start_pos_y]
450+
perp_v_scaled = [v[1] * self.scaler.LINE_CURVATURE * curvature_sign,
451+
-v[0] * self.scaler.LINE_CURVATURE * curvature_sign]
452+
434453
while t < 1.001:
435-
v = [self.graphics_info[node].end_pos_x - self.graphics_info[node].start_pos_x,
436-
self.graphics_info[node].end_pos_y - self.graphics_info[node].start_pos_y]
437-
perp_v = [v[1], -v[0]]
438-
x = quadBezier(t, self.graphics_info[node].start_pos_x,
439-
(self.graphics_info[node].start_pos_x + self.graphics_info[node].end_pos_x) // 2 +
440-
perp_v[0] * self.scaler.LINE_CURVATURE * curvature_sign,
441-
self.graphics_info[node].end_pos_x)
442-
y = quadBezier(t, self.graphics_info[node].start_pos_y,
443-
(self.graphics_info[node].start_pos_y + self.graphics_info[node].end_pos_y) // 2 +
444-
perp_v[1] * self.scaler.LINE_CURVATURE * curvature_sign,
445-
self.graphics_info[node].end_pos_y)
454+
x = quad_bezier(t, self.graphics_info[node].start_pos_x,
455+
(self.graphics_info[node].start_pos_x + self.graphics_info[node].end_pos_x) // 2 +
456+
perp_v_scaled[0],
457+
self.graphics_info[node].end_pos_x)
458+
y = quad_bezier(t, self.graphics_info[node].start_pos_y,
459+
(self.graphics_info[node].start_pos_y + self.graphics_info[node].end_pos_y) // 2 +
460+
perp_v_scaled[1],
461+
self.graphics_info[node].end_pos_y)
446462
arcade.draw_line(prev_point_x, prev_point_y,
447463
x, y,
448464
(0, 0, 0), self.scaler.LINE_WIDTH)
@@ -469,14 +485,21 @@ def recursive_node_draw(self, node):
469485
color = (50, 50, 50)
470486
elif type(node) == Struct:
471487
color = (75, 75, 75)
472-
# FIXME: use draw_xywh_rectangle_filled
473-
arcade.draw_rectangle_filled(self.graphics_info[node].pos_x + self.graphics_info[node].size_x / 2,
474-
self.graphics_info[node].pos_y + self.graphics_info[node].size_y / 2,
475-
self.graphics_info[node].size_x, self.graphics_info[node].size_y, color)
488+
arcade.draw_xywh_rectangle_filled(
489+
self.graphics_info[node].pos_x,
490+
self.graphics_info[node].pos_y,
491+
self.graphics_info[node].size_x,
492+
self.graphics_info[node].size_y,
493+
color
494+
)
476495
if type(node) != CodeBlock:
477-
arcade.draw_rectangle_outline(self.graphics_info[node].pos_x + self.graphics_info[node].size_x / 2,
478-
self.graphics_info[node].pos_y + self.graphics_info[node].size_y / 2,
479-
self.graphics_info[node].size_x, self.graphics_info[node].size_y, (0, 0, 0))
496+
arcade.draw_xywh_rectangle_outline(
497+
self.graphics_info[node].pos_x,
498+
self.graphics_info[node].pos_y,
499+
self.graphics_info[node].size_x,
500+
self.graphics_info[node].size_y,
501+
(0, 0, 0)
502+
)
480503
if type(node) != CodeLine:
481504
offset_y = 0
482505
for i in node.body_nodes:
@@ -524,7 +547,3 @@ def on_key_press(self, symbol, modifier):
524547
# FIXME: probably this should be made more elegant
525548
if should_recalculate:
526549
self.on_resize(self.width, self.height)
527-
528-
529-
530-

0 commit comments

Comments
 (0)