1 | // Copyright(C) 2019 Lars Pontoppidan. All rights reserved. |
2 | // Use of this source code is governed by an MIT license file distributed with this software package. |
3 | module main |
4 | |
5 | // Example of how to send a value through a channel from a worker thread to the main/rendering thread. |
6 | // This can be useful to do long running computations while keeping your framerate high (60 fps in this example). |
7 | import gg |
8 | import gx |
9 | import math |
10 | import time |
11 | |
12 | const ( |
13 | win_width = 600 |
14 | win_height = 700 |
15 | bg_color = gx.white |
16 | count_color = gx.black |
17 | ) |
18 | |
19 | struct App { |
20 | mut: |
21 | gg &gg.Context = unsafe { nil } |
22 | ch chan i64 |
23 | counter i64 |
24 | } |
25 | |
26 | fn main() { |
27 | mut app := &App{ |
28 | gg: 0 |
29 | } |
30 | app.gg = gg.new_context( |
31 | width: win_width |
32 | height: win_height |
33 | create_window: true |
34 | window_title: 'Counter' |
35 | user_data: app |
36 | bg_color: bg_color |
37 | frame_fn: frame |
38 | init_fn: init |
39 | ) |
40 | app.gg.run() |
41 | } |
42 | |
43 | fn init(mut app App) { |
44 | // Spawn a new worker thread. |
45 | spawn worker(mut app) |
46 | } |
47 | |
48 | // worker simulates a workload. This should be run in a separate thread. |
49 | fn worker(mut app App) { |
50 | stopwatch := time.new_stopwatch() |
51 | mut elapsed := stopwatch.elapsed() |
52 | // Do heavy operations here - like invoking a path finding algorithm, load an image or similar. |
53 | for { |
54 | now := stopwatch.elapsed() |
55 | // When done - send the result through a channel to the main/rendering thread. |
56 | app.ch <- (now - elapsed) |
57 | elapsed = now |
58 | time.sleep(1 * time.second) |
59 | } |
60 | } |
61 | |
62 | fn frame(mut app App) { |
63 | app.gg.begin() |
64 | size := gg.window_size() |
65 | mut scale_factor := math.round(f32(size.width) / win_width) |
66 | if scale_factor <= 0 { |
67 | scale_factor = 1 |
68 | } |
69 | text_cfg := gx.TextCfg{ |
70 | size: 64 * int(scale_factor) |
71 | } |
72 | |
73 | // Try a pop from the channel |
74 | mut count := i64(0) |
75 | if app.ch.try_pop(mut count) == .success { |
76 | // A value was assigned - increase the counter |
77 | app.counter += i64(f64(count) / time.second) |
78 | } |
79 | |
80 | label := '${app.counter}' |
81 | label_width := (f64(label.len * text_cfg.size) / 4.0) |
82 | label_height := (f64(1 * text_cfg.size) / 2.0) |
83 | mut x := f32(size.width) * 0.5 - label_width |
84 | mut y := f32(size.height) * 0.5 - label_height |
85 | |
86 | app.gg.draw_text(int(x), int(y), label, text_cfg) |
87 | |
88 | app.gg.end() |
89 | } |