Basic version of events

This commit is contained in:
Riyyi
2026-09-08 22:54:33 +02:00
parent 80bad9aad5
commit 90602ff1ff
2 changed files with 245 additions and 7 deletions
+115
View File
@@ -0,0 +1,115 @@
package event
import "core:fmt"
// -----------------------------------------
// event category, bitfield (?)
Event :: union {
Window_Close_Event,
Window_Resize_Event,
Joystick_Connect_Event,
Joystick_Disconnect_Event,
Key_Press_Event,
Key_Release_Event,
Key_Repeat_Event,
Mouse_Button_Press_Event,
Mouse_Button_Release_Event,
Mouse_Position_Event,
Mouse_Scroll_Event,
}
Window_Close_Event :: struct {
handled: bool,
}
Window_Resize_Event :: struct {
handled: bool,
width: i32,
height: i32,
}
Joystick_Connect_Event :: struct {
handled: bool,
id: i32,
}
Joystick_Disconnect_Event :: struct {
handled: bool,
id: i32,
}
Key_Press_Event :: struct {
handled: bool,
key: i32,
mods: i32,
}
Key_Release_Event :: struct {
handled: bool,
key: i32,
mods: i32,
}
Key_Repeat_Event :: struct {
handled: bool,
key: i32,
mods: i32,
}
Mouse_Button_Press_Event :: struct {
handled: bool,
button: i32,
mods: i32,
}
Mouse_Button_Release_Event :: struct {
handled: bool,
button: i32,
mods: i32,
}
Mouse_Position_Event :: struct {
handled: bool,
x_pos: f32,
y_pos: f32,
}
Mouse_Scroll_Event :: struct {
handled: bool,
x_offset: f32,
y_offset: f32,
}
// -----------------------------------------
// Dispatcher(Event) -> forwards to the right function
on_event :: proc(event: Event) {
fmt.println("toby!")
#partial switch e in event {
case Window_Close_Event:
fmt.println("Close")
case Window_Resize_Event:
fmt.println("Resize:", e.width, e.height)
case Key_Press_Event:
fmt.println("Key press", e.key, e.mods)
case Key_Release_Event:
fmt.println("Key release", e.key, e.mods)
case Key_Repeat_Event:
fmt.println("Key repeat", e.key, e.mods)
case Mouse_Button_Press_Event:
fmt.println("Mouse press", e.button, e.mods)
case Mouse_Button_Release_Event:
fmt.println("Mouse release", e.button, e.mods)
case Mouse_Position_Event:
fmt.printfln("Mouse pos: {}x{}", e.x_pos, e.y_pos)
case Joystick_Connect_Event:
fmt.println("Joy con:", e.id)
case Joystick_Disconnect_Event:
fmt.println("Joy dis:", e.id)
}
}
+129 -6
View File
@@ -1,5 +1,6 @@
package sindri
import "core:fmt"
import "core:strings"
import "vendor:glfw"
@@ -7,21 +8,28 @@ import "wgpu:wgpu"
import "wgpu:wgpu/glfwglue"
import "sindri:core"
import "sindri:event"
// -----------------------------------------
// Types
OS :: struct {
window: glfw.WindowHandle,
}
// -----------------------------------------
// Constructor / destructor
os_init :: proc(settings: core.Settings) {
if !glfw.Init() {
panic("[glfw] init failure")
}
glfw.WindowHint(glfw.CLIENT_API, glfw.NO_API)
// Set window properties
glfw.WindowHint(glfw.CLIENT_API, glfw.NO_API) // do not create OpenGL context
glfw.WindowHint(glfw.RESIZABLE, glfw.FALSE)
// Create GLFW window
state.os.window = glfw.CreateWindow(
i32(settings.width),
i32(settings.height),
@@ -30,9 +38,30 @@ os_init :: proc(settings: core.Settings) {
nil,
)
glfw.SetErrorCallback(error_callback)
glfw.SetWindowCloseCallback(state.os.window, window_close_callback)
// NOTE: SetFramebufferSize over SetWindowSize, to handle different DPIs
glfw.SetFramebufferSizeCallback(state.os.window, size_callback)
glfw.SetKeyCallback(state.os.window, key_callback)
glfw.SetMouseButtonCallback(state.os.window, mouse_button_callback)
glfw.SetCursorPosCallback(state.os.window, cursor_pos_callback)
glfw.SetScrollCallback(state.os.window, scroll_callback)
glfw.SetJoystickCallback(joystick_callback)
// TODO: Figure out proper vsync, found 3 spots so far
// - glfw.SwapInterval(0) this is only for OpenGL it seems?
// - glfw.SetWindowMonitor(refresh)
// - wgpu presentMode = .Fifo
}
os_destroy :: proc() {
glfw.DestroyWindow(state.os.window)
glfw.Terminate()
}
// -----------------------------------------
// Public functions
os_set_monitor :: proc(settings: core.Settings) {
monitor := glfw.GetPrimaryMonitor()
x_pos: i32
@@ -86,6 +115,10 @@ os_set_monitor :: proc(settings: core.Settings) {
)
}
os_set_callback_proc :: proc(window: rawptr) {
glfw.SetWindowUserPointer(state.os.window, window)
}
os_should_close :: proc() -> bool {
return bool(glfw.WindowShouldClose(state.os.window))
}
@@ -98,11 +131,6 @@ os_poll_events :: proc() {
glfw.PollEvents()
}
os_destroy :: proc() {
glfw.DestroyWindow(state.os.window)
glfw.Terminate()
}
os_get_framebuffer_size :: proc() -> (width, height: u32) {
iw, ih := glfw.GetFramebufferSize(state.os.window)
return u32(iw), u32(ih)
@@ -112,7 +140,102 @@ os_get_surface :: proc(instance: wgpu.Instance) -> wgpu.Surface {
return glfwglue.GetSurface(instance, state.os.window)
}
// -----------------------------------------
// Private functions
// Error callback
@(private = "file")
error_callback :: proc "c" (error: i32, description: cstring) {
context = state.ctx
fmt.eprintfln("error: GLFW {}: {}", error, description)
} // GLFWerrorfun
// Window close callback
@(private = "file")
window_close_callback :: proc "c" (window: glfw.WindowHandle) {
context = state.ctx
event.on_event(event.Window_Close_Event{})
} // GLFWwindowclosefun
// Window resize callback
@(private = "file")
size_callback :: proc "c" (window: glfw.WindowHandle, width, height: i32) {
resize()
} // GLFWframebuffersizefun
// Keyboard callback
@(private = "file")
key_callback :: proc "c" (
window: glfw.WindowHandle,
key, scancode, action, mods: i32,
) {
context = state.ctx
if action == glfw.PRESS {
event.on_event(event.Key_Press_Event{key = key, mods = mods})
}
if action == glfw.RELEASE {
event.on_event(event.Key_Release_Event{key = key, mods = mods})
}
if action == glfw.REPEAT {
event.on_event(event.Key_Repeat_Event{key = key, mods = mods})
}
} // GLFWkeyfun
// Mouse button callback
@(private = "file")
mouse_button_callback :: proc "c" (
window: glfw.WindowHandle,
button, action, mods: i32,
) {
context = state.ctx
if action == glfw.PRESS {
event.on_event(event.Mouse_Button_Press_Event{button = button})
}
if action == glfw.RELEASE {
event.on_event(event.Mouse_Button_Release_Event{button = button})
}
} // GLFWmousebuttonfun
// Mouse position callback
@(private = "file")
cursor_pos_callback :: proc "c" (
window: glfw.WindowHandle,
x_pos, y_pos: f64,
) {
context = state.ctx
event.on_event(
event.Mouse_Position_Event{x_pos = f32(x_pos), y_pos = f32(y_pos)},
)
} // GLFWcursorposfun
// Mouse scroll callback
@(private = "file")
scroll_callback :: proc "c" (
window: glfw.WindowHandle,
x_offset, y_offset: f64,
) {
context = state.ctx
event.on_event(
event.Mouse_Scroll_Event {
x_offset = f32(x_offset),
y_offset = f32(y_offset),
},
)
} // GLFWscrollfun
// Joystick connected / disconnected callback
@(private = "file")
joystick_callback :: proc "c" (id, connected: i32) {
context = state.ctx
if connected == glfw.CONNECTED {
event.on_event(event.Joystick_Connect_Event{id = id})
} else {
event.on_event(event.Joystick_Disconnect_Event{id = id})
}
} // GLFWjoystickfun
// References:
// - https://www.glfw.org/docs/latest/group__init.html
// - https://www.glfw.org/docs/latest/group__window.html
// - https://www.glfw.org/docs/latest/group__input.html