aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/examples/gg/worker_thread.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/examples/gg/worker_thread.v')
-rw-r--r--v_windows/v/examples/gg/worker_thread.v90
1 files changed, 90 insertions, 0 deletions
diff --git a/v_windows/v/examples/gg/worker_thread.v b/v_windows/v/examples/gg/worker_thread.v
new file mode 100644
index 0000000..a2c9852
--- /dev/null
+++ b/v_windows/v/examples/gg/worker_thread.v
@@ -0,0 +1,90 @@
+// Copyright(C) 2019 Lars Pontoppidan. All rights reserved.
+// Use of this source code is governed by an MIT license file distributed with this software package.
+module main
+
+// Example of how to send a value through a channel from a worker thread to the main/rendering thread.
+// This can be useful to do long running computations while keeping your framerate high (60 fps in this example).
+import gg
+import gx
+import math
+import time
+
+const (
+ win_width = 600
+ win_height = 700
+ bg_color = gx.white
+ count_color = gx.black
+)
+
+struct App {
+mut:
+ gg &gg.Context
+ ch chan i64
+ counter i64
+}
+
+fn main() {
+ mut app := &App{
+ gg: 0
+ }
+ app.gg = gg.new_context(
+ width: win_width
+ height: win_height
+ create_window: true
+ window_title: 'Counter'
+ user_data: app
+ bg_color: bg_color
+ frame_fn: frame
+ init_fn: init
+ font_path: gg.system_font_path()
+ )
+ app.gg.run()
+}
+
+fn init(mut app App) {
+ // Spawn a new worker thread.
+ go worker(mut app)
+}
+
+// worker simulates a workload. This should be run in a separate thread.
+fn worker(mut app App) {
+ stopwatch := time.new_stopwatch()
+ mut elapsed := stopwatch.elapsed()
+ // Do heavy operations here - like invoking a path finding algorithm, load an image or similar.
+ for {
+ now := stopwatch.elapsed()
+ // When done - send the result through a channel to the main/rendering thread.
+ app.ch <- (now - elapsed)
+ elapsed = now
+ time.sleep(1 * time.second)
+ }
+}
+
+fn frame(mut app App) {
+ app.gg.begin()
+ size := gg.window_size()
+ mut scale_factor := math.round(f32(size.width) / win_width)
+ if scale_factor <= 0 {
+ scale_factor = 1
+ }
+ text_cfg := gx.TextCfg{
+ size: 64 * int(scale_factor)
+ }
+
+ // Try a pop from the channel
+ mut count := i64(0)
+ if app.ch.try_pop(mut count) == .success {
+ // A value was assigned - increase the counter
+ app.counter += i64(f64(count) / time.second)
+ }
+
+ label := '$app.counter'
+ label_width := (f64(label.len * text_cfg.size) / 4.0)
+ label_height := (f64(1 * text_cfg.size) / 2.0)
+ mut x := f32(size.width) * 0.5 - label_width
+ mut y := f32(size.height) * 0.5 - label_height
+
+ app.gg.draw_text(int(x), int(y), label, text_cfg)
+
+ app.gg.end()
+}