From: Brendan Hansen Date: Tue, 16 Feb 2021 21:54:31 +0000 (-0600) Subject: pulled event code from other project X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=9f2453beeedcd332ebfb605b7011364cdc0b0e74;p=onyx-prez.git pulled event code from other project --- diff --git a/dist/index.js b/dist/index.js index a79a025..60eb8b4 100644 --- a/dist/index.js +++ b/dist/index.js @@ -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() { diff --git a/src/build.onyx b/src/build.onyx index 541cddd..92729c6 100644 --- a/src/build.onyx +++ b/src/build.onyx @@ -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 index 0000000..5dd6631 --- /dev/null +++ b/src/events.onyx @@ -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" --- diff --git a/src/prez.onyx b/src/prez.onyx index 16b4c4c..0ccc263 100644 --- a/src/prez.onyx +++ b/src/prez.onyx @@ -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(); }