v2 / examples / gg / worker_thread.v
83 lines · 72 sloc · 2.08 KB · e2e5cf8db56f3562c7baa735061690be936bdf3e
Raw
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.
3module 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).
7import gg
8import math
9import time
10
11const win_width = 600
12const win_height = 700
13const bg_color = gg.white
14
15struct App {
16mut:
17 gg &gg.Context = unsafe { nil }
18 ch chan i64
19 counter i64
20}
21
22fn main() {
23 mut app := &App{}
24 app.gg = gg.new_context(
25 width: win_width
26 height: win_height
27 create_window: true
28 window_title: 'Counter'
29 user_data: app
30 bg_color: bg_color
31 frame_fn: frame
32 init_fn: init
33 )
34 app.gg.run()
35}
36
37fn init(mut app App) {
38 // Spawn a new worker thread.
39 spawn worker(mut app)
40}
41
42// worker simulates a workload. This should be run in a separate thread.
43fn worker(mut app App) {
44 stopwatch := time.new_stopwatch()
45 mut elapsed := stopwatch.elapsed()
46 // Do heavy operations here - like invoking a path finding algorithm, load an image or similar.
47 for {
48 now := stopwatch.elapsed()
49 // When done - send the result through a channel to the main/rendering thread.
50 app.ch <- (now - elapsed)
51 elapsed = now
52 time.sleep(1 * time.second)
53 }
54}
55
56fn frame(mut app App) {
57 app.gg.begin()
58 size := gg.window_size()
59 mut scale_factor := math.round(f32(size.width) / win_width)
60 if scale_factor <= 0 {
61 scale_factor = 1
62 }
63 text_cfg := gg.TextCfg{
64 size: 64 * int(scale_factor)
65 }
66
67 // Try a pop from the channel
68 mut count := i64(0)
69 if app.ch.try_pop(mut count) == .success {
70 // A value was assigned - increase the counter
71 app.counter += i64(f64(count) / time.second)
72 }
73
74 label := '${app.counter}'
75 label_width := (f64(label.len * text_cfg.size) / 4.0)
76 label_height := (f64(1 * text_cfg.size) / 2.0)
77 mut x := f32(size.width) * 0.5 - label_width
78 mut y := f32(size.height) * 0.5 - label_height
79
80 app.gg.draw_text(int(x), int(y), label, text_cfg)
81
82 app.gg.end()
83}
84