pulled event code from other project
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 16 Feb 2021 21:54:31 +0000 (15:54 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 16 Feb 2021 21:54:31 +0000 (15:54 -0600)
dist/index.js
src/build.onyx
src/events.onyx [new file with mode: 0644]
src/prez.onyx

index a79a025d54262014301c191ad9d198662b72c2d4..60eb8b4e68813502e612a75880107a64def73dcc 100644 (file)
@@ -5,6 +5,66 @@ let canvasCtx;
 
 const MAGIC_CANVAS_NUMBER = 0x5052455A;
 
+function push_event_to_buffer(esp, event_size, event_kind, data) {
+    let WASM_U32 = new Uint32Array(wasm_instance.exports.memory.buffer);
+
+    if (WASM_U32[esp] >= WASM_U32[esp + 1]) {
+        console.log("Buffer full!");
+        return;
+    }
+
+    WASM_U32[esp] += 1;
+
+    let event_idx = esp + (WASM_U32[esp] - 1) * (event_size / 4) + 2;
+    WASM_U32[event_idx] = event_kind;
+    WASM_U32[event_idx + 1] = Date.now();
+
+    for (let i = 0; i < data.length; i++) {
+        WASM_U32[event_idx + 2 + i] = data[i];
+    }
+}
+
+
+let event_import_obj = {
+    setup(esp, event_size) {
+        // Indicies into a Uint32Array are not based on bytes,
+        // but on the index.
+        esp /= 4;
+
+        document.addEventListener("keydown", (ev) => {
+            if (ev.isComposing || ev.keyCode === 229) return;
+            push_event_to_buffer(esp, event_size, 0x04, [ ev.keyCode ]);
+        });
+
+        document.addEventListener("keyup", (ev) => {
+            if (ev.isComposing || ev.keyCode === 229) return;
+            push_event_to_buffer(esp, event_size, 0x05, [ ev.keyCode ]);
+        });
+
+        document.addEventListener("mousedown", (ev) => {
+            push_event_to_buffer(esp, event_size, 0x01, [ ev.clientX, ev.clientY, ev.button ]);
+        });
+
+        document.addEventListener("mouseup", (ev) => {
+            push_event_to_buffer(esp, event_size, 0x02, [ ev.clientX, ev.clientY, ev.button ]);
+        });
+
+        document.addEventListener("mousemove", (ev) => {
+            push_event_to_buffer(esp, event_size, 0x03, [ ev.clientX, ev.clientY, -1 ]);
+        });
+
+        document.addEventListener("wheel", (ev) => {
+            push_event_to_buffer(esp, event_size, 0x07, [ ev.clientX, ev.clientY, ev.deltaY >= 0 ? 0x04 : 0x03 ]);
+        });
+
+        window.addEventListener("resize", (ev) => {
+            push_event_to_buffer(esp, event_size, 0x06, [ window.innerWidth, window.innerHeight ]);
+        });
+
+        push_event_to_buffer(esp, event_size, 0x06, [ window.innerWidth, window.innerHeight ]);
+    }
+}
+
 let canvas_import_obj = {
 
     init(canvas_name, length) {
@@ -42,7 +102,6 @@ let canvas_import_obj = {
         const text = new TextDecoder().decode(data);
 
         let metrics = canvasCtx.measureText(text);
-        console.log("TEST:", metrics);
 
         let data_view = new DataView(wasm_instance.exports.memory.buffer, measure_ptr, 5 * 4);
         data_view.setFloat32(0,  metrics.width, true);
@@ -79,7 +138,8 @@ let import_obj = {
         exit(status) { console.warn("Attempted to call host.exit()."); }
     },
 
-    canvas: canvas_import_obj
+    canvas: canvas_import_obj,
+    event:  event_import_obj,
 }
 
 function main() {
index 541cdddaddaae5da93f4852a054793b7fb8ebcc8..92729c61c42aa329608618e524c175d89a11bf10 100644 (file)
@@ -7,3 +7,4 @@ use package build_opts as build_opts
 #load "core/std"
 
 #load "src/prez"
+#load "src/events"
diff --git a/src/events.onyx b/src/events.onyx
new file mode 100644 (file)
index 0000000..5dd6631
--- /dev/null
@@ -0,0 +1,104 @@
+// This is a simple buffered system to receive events from the webbrowser
+// in a buffer that you can poll and consume all of the events. It is not
+// direclty used by the immediate mode graphics, but it makes standing up
+// a simple application much easier.
+
+package event
+
+#private_file Num_Buffered_Events :: 16
+
+// NOTE: These need to match exactly what is in the corresponding javascript
+DomEventKind :: enum {
+    None       :: 0x00;
+
+    MouseDown  :: 0x01;
+    MouseUp    :: 0x02;
+    MouseMove  :: 0x03;
+    MouseWheel :: 0x07;
+
+    KeyDown    :: 0x04;
+    KeyUp      :: 0x05;
+
+    Resize     :: 0x06;
+}
+
+DomEvent :: struct {
+    kind : DomEventKind;
+    timestamp : u32;
+}
+
+KeyboardEvent :: struct {
+    use event : DomEvent;
+
+    keycode : u32;
+}
+
+MouseButton :: enum {
+    Left :: 0x00;
+    Middle :: 0x01;
+    Right :: 0x02;
+
+    WheelUp :: 0x03;
+    WheelDown :: 0x04;
+}
+
+MouseEvent :: struct {
+    use event : DomEvent;
+
+    pos_x  : u32;
+    pos_y  : u32;
+    button : MouseButton;
+}
+
+ResizeEvent :: struct {
+    use event : DomEvent;
+
+    width  : u32;
+    height : u32;
+}
+
+Event :: struct #union {
+    use dom : DomEvent;
+
+    keyboard : KeyboardEvent;
+    mouse    : MouseEvent;
+    resize   : ResizeEvent;
+}
+
+clear_event :: (ev: ^Event) {
+    ev.kind = DomEventKind.None;
+    ev.timestamp = 0;
+}
+
+init :: () {
+    event_storage.event_count = 0;
+    event_storage.max_events = Num_Buffered_Events;
+
+    for ^ev: event_storage.event_buffer do clear_event(ev);
+
+    event_setup(^event_storage, sizeof Event);
+}
+
+poll :: (ev: ^Event) -> bool {
+    if event_storage.event_count == 0 do return false;
+
+    *ev = event_storage.event_buffer[0];
+    for i: 0 .. Num_Buffered_Events - 2 {
+        event_storage.event_buffer[i] = event_storage.event_buffer[i + 1];
+    }
+
+    event_storage.event_count -= 1;
+
+    return true;
+}
+
+/* Private members */
+
+#private_file EventStorage :: struct {
+    event_count  : u32;
+    max_events   : u32;
+    event_buffer : [Num_Buffered_Events] Event;
+}
+
+#private_file event_storage : EventStorage;
+#private_file event_setup :: (event_storage: ^EventStorage, event_size: u32) -> void #foreign "event" "setup" ---
index 16b4c4cdd7f06f61df98de1c993019c7e4e8745c..0ccc2636d18eda2dad7e929b487970716be2fe81 100644 (file)
@@ -1,7 +1,8 @@
 use package core
+use package event as event
 
 Canvas :: struct {
-    Handle :: #type u32;
+    Handle :: #type u32
 
     init  :: (id: str) -> Handle #foreign "canvas" "init" ---
     clear :: (handle: Handle, r: f32, g: f32, b: f32, a := 1.0f) -> Handle #foreign "canvas" "clear" ---
@@ -12,8 +13,9 @@ Canvas :: struct {
     set_font :: (handle: Handle, font_name: str) -> u32 #foreign "canvas" "setFont" ---
 
     TextMetrics :: struct {
-        width : f32;
-        box   : struct {
+        width: f32;
+
+        box: struct {
             left, right : f32;
             top, bottom : f32;
         };
@@ -49,15 +51,28 @@ draw_centered_text :: (text: str, y_baseline: f32) {
 
     font_metrics: TextMetrics;
     measure_text(canvas, text, ^font_metrics);
-    println(font_metrics.width);
 
     x := (width - font_metrics.width) / 2;
 
     fill_text(canvas, text, x, y_baseline);
 }
 
+poll_events :: () {
+    use event.DomEventKind;
+
+    ev: event.Event;
+    while event.poll(^ev) do switch ev.kind {
+        case Resize {
+            printf("New window size: %i, %i", ev.resize.width, ev.resize.height);
+        }
+    }
+}
+
 main :: (args: [] cstr) {
     setup_canvas();
+    event.init();
 
     draw_centered_text("Hello, World! This is a long title!", 100);
+
+    poll_events();
 }