| 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 math |
| 9 | import time |
| 10 | |
| 11 | const win_width = 600 |
| 12 | const win_height = 700 |
| 13 | const bg_color = gg.white |
| 14 | |
| 15 | struct App { |
| 16 | mut: |
| 17 | gg &gg.Context = unsafe { nil } |
| 18 | ch chan i64 |
| 19 | counter i64 |
| 20 | } |
| 21 | |
| 22 | fn 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 | |
| 37 | fn 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. |
| 43 | fn 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 | |
| 56 | fn 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 | |