From 6180767bf249da850c4df1756c64582d31c13fc1 Mon Sep 17 00:00:00 2001 From: Alberto Torres Date: Fri, 13 Sep 2024 02:42:11 +0200 Subject: [PATCH] Add `break_current_callbacks` to block other callbacks in the same frame. --- src/platform/glfm_wrap.nim | 18 ++++++++++++++++-- src/platform/glfw_wrap.nim | 24 +++++++++++++++++++++--- src/screen.nim | 9 +++++++++ src/types.nim | 1 + 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/platform/glfm_wrap.nim b/src/platform/glfm_wrap.nim index d8b68a4..98e3940 100644 --- a/src/platform/glfm_wrap.nim +++ b/src/platform/glfm_wrap.nim @@ -109,23 +109,31 @@ proc make_window*(width, height: int32, title: string): Window = return window.glfmSetKeyFunc proc(display: ptr GLFMDisplay; keyCode: GLFMKey; action: GLFMKeyAction; mods: cint): bool {.cdecl.} = + let screen = display.screen let key = cast[KeyCode](keyCode) let shiftKey = (mods and 1).bool let ctrlKey = (mods and 2).bool let altKey = (mods and 4).bool let metaKey = (mods and 8).bool - for cb in display.screen.key_callbacks: + for cb in screen.key_callbacks: cb(KeyEvent( pressed: action != GLFMKeyActionReleased, repeat: action == GLFMKeyActionRepeated, shiftKey: shiftKey, ctrlKey: ctrlKey, altKey: altKey, metaKey: metaKey, key: key, )) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break return true window.glfmSetCharFunc proc(display: ptr GLFMDisplay; utf8: cstring; modifiers: cint) {.cdecl.} = + let screen = display.screen let codepoint = cast[uint32](($utf8).runeAt(0)) - for cb in display.screen.char_callbacks: + for cb in screen.char_callbacks: cb(codepoint) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break window.glfmSetTouchFunc proc (display: ptr GLFMDisplay; touch: cint; phase: GLFMTouchPhase; x: cdouble; y: cdouble): bool {.cdecl.} = @@ -149,6 +157,9 @@ proc make_window*(width, height: int32, title: string): Window = ) for cb in screen.mouse_move_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break screen.last_x = x screen.last_y = y else: @@ -166,6 +177,9 @@ proc make_window*(width, height: int32, title: string): Window = ) for cb in window.screen.mouse_button_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break if pressed: screen.last_buttons = screen.last_buttons or (1'i8 shl btn) else: diff --git a/src/platform/glfw_wrap.nim b/src/platform/glfw_wrap.nim index a0f75e6..f62a99f 100644 --- a/src/platform/glfw_wrap.nim +++ b/src/platform/glfw_wrap.nim @@ -79,6 +79,7 @@ proc make_window*(width, height: int32, title: string): Window = to_be_closed.add window ) discard glfw.setKeyCallback(window, proc(window: Window, key, scancode, action, mods: int32) {.cdecl.} = + let screen = window.screen let e = KeyEvent( pressed: action.bool, repeat: action == 2, @@ -88,12 +89,19 @@ proc make_window*(width, height: int32, title: string): Window = metaKey: (mods and 8).bool, key: cast[KeyCode](key), ) - for cb in window.screen.key_callbacks: + for cb in screen.key_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break ) discard glfw.setCharCallback(window, proc(window: Window, codepoint: uint32) {.cdecl.} = - for cb in window.screen.char_callbacks: + let screen = window.screen + for cb in screen.char_callbacks: cb(codepoint) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break ) discard glfw.setCursorPosCallback(window, proc(window: Window, x, y: float) {.cdecl.} = # TODO: when a mouse button is pressed do we need to poll the position @@ -115,6 +123,9 @@ proc make_window*(width, height: int32, title: string): Window = ) for cb in screen.mouse_move_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break screen.last_x = x screen.last_y = y ) @@ -129,19 +140,26 @@ proc make_window*(width, height: int32, title: string): Window = metaKey: (mods and 8).bool, position: vec2(screen.last_x, screen.last_y), ) - for cb in window.screen.mouse_button_callbacks: + for cb in screen.mouse_button_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break if action.bool: screen.last_buttons = screen.last_buttons or (1'i8 shl button) else: screen.last_buttons = screen.last_buttons and not (1'i8 shl button) ) discard glfw.setScrollCallback(window, proc(window: Window, x, y: float) {.cdecl.} = + let screen = window.screen let e = MouseWheelEvent( movement: vec2(x,y), ) for cb in window.screen.mouse_wheel_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break ) windows.add window return window diff --git a/src/screen.nim b/src/screen.nim index a8838b5..f3a6159 100644 --- a/src/screen.nim +++ b/src/screen.nim @@ -137,6 +137,9 @@ proc emulateMouseWithTouch*(screen: Screen, touch: int32, ending: bool, x, y: fl ) for cb in screen.mouse_move_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break screen.last_x = x screen.last_y = y template send_btn(pressed1, btn, x, y: untyped) = @@ -147,6 +150,9 @@ proc emulateMouseWithTouch*(screen: Screen, touch: int32, ending: bool, x, y: fl ) for cb in screen.mouse_button_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break if pressed1: screen.last_buttons = screen.last_buttons or (1'i8 shl btn) else: @@ -159,6 +165,9 @@ proc emulateMouseWithTouch*(screen: Screen, touch: int32, ending: bool, x, y: fl ) for cb in screen.mouse_wheel_callbacks: cb(e) + if screen.break_current_callbacks: + screen.break_current_callbacks = false + break let prev_count = screen.touches.len var index = -1 diff --git a/src/types.nim b/src/types.nim index 3349a89..f5c251b 100644 --- a/src/types.nim +++ b/src/types.nim @@ -863,6 +863,7 @@ type prev_touches*: seq[(int32, Vec2)] resize_callbacks*: seq[proc(screen: Screen)] ## private platform_event_callbacks*: seq[proc(screen: Screen, e: PlatformEvent)] ## private + break_current_callbacks*: bool ## private PlatformEvent* = enum PlatformPause