Skip to content

Commit 9287049

Browse files
committed
more memory optimize stuff, cache cosf/sinf values for rectangle drawing
1 parent 4ab61c4 commit 9287049

29 files changed

+239
-225
lines changed

_gui.v

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
@[has_globals]
66
module gui
77

8+
import math
9+
810
__global gui_theme = theme_dark_no_padding
911
__global gui_tooltip = TooltipState{}
12+
__global cosf_values = [32]f32{}
13+
__global sinf_values = [32]f32{}
1014

1115
pub const version = '0.1.0'
1216
pub const app_title = 'GUI'
@@ -16,3 +20,15 @@ mut:
1620
id u32
1721
bounds DrawClip
1822
}
23+
24+
fn init() {
25+
// cosf_values, sinf_values are used in render2.v for drawing rounded
26+
// corners on rectangles. Yes, there are several magic numbers here
27+
// and the drawing routines assume these arrays are initialized and
28+
// are the correct size.
29+
for idx in 0 .. 31 {
30+
rad := f32(math.radians(idx * 3))
31+
cosf_values[idx] = math.cosf(rad)
32+
sinf_values[idx] = math.sinf(rad)
33+
}
34+
}

animation.v

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ mut:
2727
pub fn (mut window Window) animation_add(mut animation Animation) {
2828
window.animations = window.animations.filter(it.id != animation.id)
2929
unsafe { window.animations.flags.set(.noslices) }
30-
defer { unsafe { window.animations.flags.clear(.noslices) } }
3130
animation.start = time.now()
3231
window.animations << animation
3332
}

examples/column_scroll.v

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ fn main() {
1616
size := 10_000 // 10K!
1717
mut items := []gui.View{cap: size + 1}
1818
unsafe { items.flags.set(.noslices) }
19-
defer { unsafe { items.flags.clear(.noslices) } }
2019
for i in 1 .. size + 1 {
2120
items << gui.text(text: '${i:05} text list item')
2221
}

examples/date_picker_options.v

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ fn example_date_picker(app DatePickerApp, mut window gui.Window) gui.View {
9999

100100
mut allowed_weekdays := []gui.DatePickerWeekdays{}
101101
unsafe { allowed_weekdays.flags.set(.noslices) }
102-
defer { unsafe { allowed_weekdays.flags.clear(.noslices) } }
103102
if app.allow_monday {
104103
allowed_weekdays << .monday
105104
}
@@ -649,7 +648,6 @@ fn set_theme(mut window gui.Window) {
649648
gui.theme_light_bordered
650649
}
651650
} else {
652-
println('x')
653651
if app.use_system_font {
654652
create_system_font_theme(gui.theme_dark_bordered_cfg, gui.theme_dark_bordered_cfg.text_style)
655653
} else {

examples/fonts.v

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,8 @@ fn font_panel(window &gui.Window) gui.View {
9494
app := window.state[FontsApp]()
9595
mut rows := []gui.View{}
9696
unsafe { rows.flags.set(.noslices) }
97-
defer { unsafe { rows.flags.clear(.noslices) } }
9897
mut cols := []gui.View{}
9998
unsafe { rows.flags.set(.noslices) }
100-
defer { unsafe { rows.flags.clear(.noslices) } }
10199
width := f32(gui.theme().n3.size) * 1.5
102100

103101
text_style := match app.selected_family {

examples/showcase.v

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,13 +1344,11 @@ fn icon_catalog(mut w gui.Window) gui.View {
13441344
chunks := chunk_map(gui.icons_map, 4)
13451345
mut all_icons := []gui.View{cap: chunks.len}
13461346
unsafe { all_icons.flags.set(.noslices) }
1347-
defer { unsafe { all_icons.flags.clear(.noslices) } }
13481347

13491348
// create rows of icons/text
13501349
for chunk in chunks {
13511350
mut icons := []gui.View{cap: chunk.len}
13521351
unsafe { icons.flags.set(.noslices) }
1353-
defer { unsafe { icons.flags.clear(.noslices) } }
13541352
for key, val in chunk {
13551353
icons << gui.column(
13561354
min_width: longest
@@ -1381,7 +1379,6 @@ fn icon_catalog(mut w gui.Window) gui.View {
13811379
fn chunk_map[K, V](input map[K]V, chunk_size int) []map[K]V {
13821380
mut chunks := []map[K]V{cap: input.keys().len / chunk_size + 1}
13831381
unsafe { chunks.flags.set(.noslices) }
1384-
defer { unsafe { chunks.flags.clear(.noslices) } }
13851382
mut current_chunk := map[K]V{}
13861383
mut count := 0
13871384

@@ -1789,7 +1786,6 @@ fn table_with_sortable_columns(mut table_data TableData, mut window gui.Window)
17891786
// Replace with first row with clickable column headers
17901787
mut tds := []gui.TableCellCfg{}
17911788
unsafe { tds.flags.set(.noslices) }
1792-
defer { unsafe { tds.flags.clear(.noslices) } }
17931789
for idx, cell in table_cfg.data[0].cells {
17941790
tds << gui.TableCellCfg{
17951791
...cell

layout.v

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ fn layout_arrange(mut layout Layout, mut window Window) []Layout {
4141
// They also complicate the fuck out of things.
4242
mut floating_layouts := []Layout{}
4343
unsafe { floating_layouts.flags.set(.noslices) }
44-
defer { unsafe { floating_layouts.flags.clear(.noslices) } }
4544
layout_remove_floating_layouts(mut layout, mut floating_layouts)
4645
fix_float_parents(mut floating_layouts)
4746

@@ -59,7 +58,6 @@ fn layout_arrange(mut layout Layout, mut window Window) []Layout {
5958
layout_pipeline(mut layout, mut window)
6059
mut layouts := [layout]
6160
unsafe { layouts.flags.set(.noslices) }
62-
defer { unsafe { layouts.flags.clear(.noslices) } }
6361

6462
// Compute the floating layouts. Because they are appended to
6563
// the layout array, they get rendered after the main layout.
@@ -110,7 +108,6 @@ fn layout_parents(mut layout Layout, parent &Layout) {
110108
// the layout logic.
111109
fn layout_remove_floating_layouts(mut layout Layout, mut layouts []Layout) {
112110
unsafe { layout.children.flags.set(.noslices) }
113-
defer { unsafe { layout.children.flags.clear(.noslices) } }
114111
for i, mut child in layout.children {
115112
if child.shape.float {
116113
layouts << child

layout2.v

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ fn (node &Layout) find_next_focusable(ids []u32, mut w Window) ?Shape {
7272
fn (node &Layout) get_focus_ids() []u32 {
7373
mut focus_ids := []u32{}
7474
unsafe { focus_ids.flags.set(.noslices) }
75-
defer { unsafe { focus_ids.flags.clear(.noslices) } }
7675
if node.shape.id_focus > 0 && !node.shape.focus_skip {
7776
focus_ids << node.shape.id_focus
7877
}

render2.v

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
@[has_globals]
12
module gui
23

34
import sokol.sgl
45
import gg
5-
import math
66

77
fn draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c gg.Color, ctx &gg.Context) {
88
if w <= 0 || h <= 0 || radius < 0 {
@@ -39,9 +39,8 @@ fn draw_rounded_rect_filled(x f32, y f32, w f32, h f32, radius f32, c gg.Color,
3939
mut dxs := [32]f32{}
4040
mut dys := [32]f32{}
4141
for i in 0 .. 31 {
42-
rad := f32(math.radians(i * 3))
43-
dxs[i] = r * math.cosf(rad)
44-
dys[i] = r * math.sinf(rad)
42+
dxs[i] = r * cosf_values[i]
43+
dys[i] = r * sinf_values[i]
4544
}
4645

4746
if r != 0 {
@@ -147,9 +146,8 @@ fn draw_rounded_rect_empty(x f32, y f32, w f32, h f32, radius f32, c gg.Color, c
147146
mut dxs := [32]f32{}
148147
mut dys := [32]f32{}
149148
for i in 0 .. 31 {
150-
rad := f32(math.radians(i * 3))
151-
dxs[i] = r * math.cosf(rad)
152-
dys[i] = r * math.sinf(rad)
149+
dxs[i] = r * cosf_values[i]
150+
dys[i] = r * sinf_values[i]
153151
}
154152

155153
if r != 0 {

shape.v

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,77 @@ import rand
44
import datatypes
55

66
// Shape is the only data structure in GUI used to draw to the screen.
7+
// Members are arranged for packing to reduce memory footprint.
78
pub struct Shape {
89
pub:
910
id string // user assigned
10-
id_focus u32 // >0 indicates shape is focusable. Value determines tabbing order
1111
name string // internal shape name, useful for debugging
1212
type ShapeType
1313
uid u64 = rand.u64() // internal use only
14+
id_focus u32 // >0 indicates shape is focusable. Value determines tabbing order
1415
axis Axis
1516
cfg voidptr
1617
pub mut:
17-
clip bool
18+
// --- text spans (likely largest field, place early) ---
19+
text_spans datatypes.LinkedList[TextSpan] // rich text format spans
20+
// --- strings grouped together ---
21+
text string
22+
image_name string // filename of image
23+
text_lines []string
24+
// --- callback functions grouped together ---
25+
on_char fn (voidptr, mut Event, mut Window) = unsafe { nil }
26+
on_keydown fn (voidptr, mut Event, mut Window) = unsafe { nil }
27+
on_click fn (voidptr, mut Event, mut Window) = unsafe { nil }
28+
on_mouse_move fn (voidptr, mut Event, mut Window) = unsafe { nil }
29+
on_mouse_up fn (voidptr, mut Event, mut Window) = unsafe { nil }
30+
on_char_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
31+
on_keydown_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
32+
on_mouse_down_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
33+
on_mouse_move_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
34+
on_mouse_up_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
35+
on_mouse_scroll_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
36+
amend_layout fn (mut Layout, mut Window) = unsafe { nil }
37+
on_hover fn (mut Layout, mut Event, mut Window) = unsafe { nil }
38+
// --- larger structs ---
1839
shape_clip DrawClip // used for hit-testing
1940
color Color
20-
disabled bool
21-
fill bool
22-
focus_skip bool
23-
// --- sizes, positions ---
24-
x f32
25-
y f32
26-
width f32
27-
min_width f32
28-
max_width f32
29-
height f32
30-
min_height f32
31-
max_height f32
32-
h_align HorizontalAlign
33-
v_align VerticalAlign
3441
padding Padding
35-
radius f32
42+
text_style TextStyle
3643
sizing Sizing
37-
spacing f32
38-
// -- text ---
39-
text string
40-
text_lines []string
41-
text_style TextStyle
42-
text_mode TextMode
43-
text_is_password bool
44-
text_is_placeholder bool
45-
text_sel_beg u32
46-
text_sel_end u32
47-
text_tab_size u32 = 4
48-
text_spans datatypes.LinkedList[TextSpan] // rich text format spans
49-
// --- image ---
50-
image_name string // filename of image
51-
// --- float ---
52-
float bool
53-
float_anchor FloatAttach
54-
float_tie_off FloatAttach
44+
// --- f32 fields grouped together (4-byte alignment) ---
45+
x f32
46+
y f32
47+
width f32
48+
min_width f32
49+
max_width f32
50+
height f32
51+
min_height f32
52+
max_height f32
53+
radius f32
54+
spacing f32
5555
float_offset_x f32
5656
float_offset_y f32
57-
// -- scrolling ---
58-
id_scroll u32 // >0 indicates shape is scrollable
59-
over_draw bool // allows scrollbars to draw in padding area
60-
scroll_mode ScrollMode
61-
// --- user callbacks ---
62-
on_char fn (voidptr, mut Event, mut Window) = unsafe { nil }
63-
on_keydown fn (voidptr, mut Event, mut Window) = unsafe { nil }
64-
on_click fn (voidptr, mut Event, mut Window) = unsafe { nil }
65-
on_mouse_move fn (voidptr, mut Event, mut Window) = unsafe { nil }
66-
on_mouse_up fn (voidptr, mut Event, mut Window) = unsafe { nil }
67-
// --- for internal use and not intended for end users ---
68-
// --- however, composite views can set these in the ---
69-
// --- layout amend callback. See input view for example ---
70-
on_char_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
71-
on_keydown_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
72-
on_mouse_down_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
73-
on_mouse_move_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
74-
on_mouse_up_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
75-
on_mouse_scroll_shape fn (&Shape, mut Event, mut Window) = unsafe { nil }
76-
// amend_layout called after all other layout operations complete
77-
amend_layout fn (mut Layout, mut Window) = unsafe { nil }
78-
on_hover fn (mut Layout, mut Event, mut Window) = unsafe { nil }
57+
// --- u32 fields grouped together (4-byte alignment) ---
58+
id_scroll u32 // >0 indicates shape is scrollable
59+
text_sel_beg u32
60+
text_sel_end u32
61+
text_tab_size u32 = 4
62+
// --- enums (typically 4-byte alignment) ---
63+
h_align HorizontalAlign
64+
v_align VerticalAlign
65+
text_mode TextMode
66+
scroll_mode ScrollMode
67+
float_anchor FloatAttach
68+
float_tie_off FloatAttach
69+
// --- boolean fields grouped at the end (1-byte each, can be packed) ---
70+
clip bool
71+
disabled bool
72+
fill bool
73+
focus_skip bool
74+
text_is_password bool
75+
text_is_placeholder bool
76+
float bool
77+
over_draw bool // allows scrollbars to draw in padding area
7978
}
8079

8180
// ShapeType defines the kind of Shape.

0 commit comments

Comments
 (0)