Base input pass updated for sokol possibly done (untested)
Still need to figure out input event consumption, I don't want to do it with the event ring. I would like to setup input binding layers and then have the push/pop input contextes with a set of bindings. If the bindings are detected it should "consume" that binding from further use for the buffered time period. This will be really important with how heavily model this app will be.I
This commit is contained in:
@ -1,63 +0,0 @@
|
||||
package sectr
|
||||
|
||||
InputEventType :: enum u32 {
|
||||
Key_Pressed,
|
||||
Key_Released,
|
||||
Mouse_Pressed,
|
||||
Mouse_Released,
|
||||
Mouse_Scroll,
|
||||
Mouse_Move,
|
||||
Mouse_Enter,
|
||||
Mouse_Leave,
|
||||
Unicode,
|
||||
}
|
||||
|
||||
InputEvent :: struct
|
||||
{
|
||||
frame_id : u64,
|
||||
type : InputEventType,
|
||||
key : KeyCode,
|
||||
modifiers : ModifierCodeFlags,
|
||||
mouse : struct {
|
||||
btn : MouseBtn,
|
||||
pos : Vec2,
|
||||
delta : Vec2,
|
||||
scroll : Vec2,
|
||||
},
|
||||
codepoint : rune,
|
||||
|
||||
// num_touches : u32,
|
||||
// touches : Touchpoint,
|
||||
|
||||
_sokol_frame_id : u64,
|
||||
}
|
||||
|
||||
InputKeyEvent :: struct {
|
||||
frame_id : u64,
|
||||
type : InputEventType,
|
||||
key : KeyCode,
|
||||
modifiers : ModifierCodeFlags,
|
||||
}
|
||||
|
||||
InputMouseEvent :: struct {
|
||||
frame_id : u64,
|
||||
type : InputEventType,
|
||||
key : KeyCode,
|
||||
modifiers : ModifierCodeFlags,
|
||||
}
|
||||
|
||||
// Note(Ed): There is a staged_input_events : Array(InputEvent), in the state.odin's State struct
|
||||
|
||||
append_staged_input_events :: #force_inline proc() {
|
||||
// TODO(Ed) : Add guards for multi-threading
|
||||
|
||||
state := get_state()
|
||||
array_append( & state.staged_input_events, event )
|
||||
}
|
||||
|
||||
pull_staged_input_events :: proc( input : ^InputState, staged_events : ^Array(InputEvent) )
|
||||
{
|
||||
// TODO(Ed) : Add guards for multi-threading
|
||||
|
||||
|
||||
}
|
259
code/sectr/input/events.odin
Normal file
259
code/sectr/input/events.odin
Normal file
@ -0,0 +1,259 @@
|
||||
package sectr
|
||||
|
||||
InputEventType :: enum u32 {
|
||||
Key_Pressed,
|
||||
Key_Released,
|
||||
Mouse_Pressed,
|
||||
Mouse_Released,
|
||||
Mouse_Scroll,
|
||||
Mouse_Move,
|
||||
Mouse_Enter,
|
||||
Mouse_Leave,
|
||||
Unicode,
|
||||
}
|
||||
|
||||
InputEvent :: struct
|
||||
{
|
||||
frame_id : u64,
|
||||
type : InputEventType,
|
||||
key : KeyCode,
|
||||
modifiers : ModifierCodeFlags,
|
||||
mouse : struct {
|
||||
btn : MouseBtn,
|
||||
pos : Vec2,
|
||||
delta : Vec2,
|
||||
scroll : Vec2,
|
||||
},
|
||||
codepoint : rune,
|
||||
|
||||
// num_touches : u32,
|
||||
// touches : Touchpoint,
|
||||
|
||||
_sokol_frame_id : u64,
|
||||
}
|
||||
|
||||
// TODO(Ed): May just use input event exclusively in the future and have pointers for key and mouse event filters
|
||||
// I'm on the fence about this as I don't want to force
|
||||
|
||||
InputKeyEvent :: struct {
|
||||
frame_id : u64,
|
||||
type : InputEventType,
|
||||
key : KeyCode,
|
||||
modifiers : ModifierCodeFlags,
|
||||
}
|
||||
|
||||
InputMouseEvent :: struct {
|
||||
frame_id : u64,
|
||||
type : InputEventType,
|
||||
btn : MouseBtn,
|
||||
pos : Vec2,
|
||||
delta : Vec2,
|
||||
scroll : Vec2,
|
||||
modifiers : ModifierCodeFlags,
|
||||
}
|
||||
|
||||
InputEvents :: struct {
|
||||
events : Queue(InputEvent),
|
||||
key_events : Queue(InputKeyEvent),
|
||||
mouse_events : Queue(InputMouseEvent),
|
||||
|
||||
codes_pressed : Array(rune),
|
||||
}
|
||||
|
||||
// Note(Ed): There is a staged_input_events : Array(InputEvent), in the state.odin's State struct
|
||||
|
||||
append_staged_input_events :: #force_inline proc( event : InputEvent ) {
|
||||
// TODO(Ed) : Add guards for multi-threading
|
||||
|
||||
state := get_state()
|
||||
append( & state.staged_input_events, event )
|
||||
}
|
||||
|
||||
pull_staged_input_events :: proc( input : ^InputState, input_events : ^InputEvents, staged_events : Array(InputEvent) )
|
||||
{
|
||||
// TODO(Ed) : Add guards for multi-threading
|
||||
|
||||
staged_events_slice := array_to_slice(staged_events)
|
||||
push( & input_events.events, staged_events_slice )
|
||||
|
||||
using input_events
|
||||
|
||||
for event in staged_events_slice
|
||||
{
|
||||
switch event.type {
|
||||
case .Key_Pressed:
|
||||
push( & key_events, InputKeyEvent {
|
||||
frame_id = event.frame_id,
|
||||
type = event.type,
|
||||
key = event.key,
|
||||
modifiers = event.modifiers
|
||||
})
|
||||
|
||||
case .Key_Released:
|
||||
push( & key_events, InputKeyEvent {
|
||||
frame_id = event.frame_id,
|
||||
type = event.type,
|
||||
key = event.key,
|
||||
modifiers = event.modifiers
|
||||
})
|
||||
|
||||
case .Unicode:
|
||||
append( & codes_pressed, event.codepoint )
|
||||
|
||||
case .Mouse_Pressed:
|
||||
push( & mouse_events, InputMouseEvent {
|
||||
frame_id = event.frame_id,
|
||||
type = event.type,
|
||||
btn = event.mouse.btn,
|
||||
pos = event.mouse.pos,
|
||||
delta = event.mouse.delta,
|
||||
scroll = event.mouse.scroll,
|
||||
modifiers = event.modifiers,
|
||||
})
|
||||
|
||||
case .Mouse_Released:
|
||||
push( & mouse_events, InputMouseEvent {
|
||||
frame_id = event.frame_id,
|
||||
type = event.type,
|
||||
btn = event.mouse.btn,
|
||||
pos = event.mouse.pos,
|
||||
delta = event.mouse.delta,
|
||||
scroll = event.mouse.scroll,
|
||||
modifiers = event.modifiers,
|
||||
})
|
||||
|
||||
case .Mouse_Scroll:
|
||||
push( & mouse_events, InputMouseEvent {
|
||||
frame_id = event.frame_id,
|
||||
type = event.type,
|
||||
btn = event.mouse.btn,
|
||||
pos = event.mouse.pos,
|
||||
delta = event.mouse.delta,
|
||||
scroll = event.mouse.scroll,
|
||||
modifiers = event.modifiers,
|
||||
})
|
||||
case .Mouse_Move:
|
||||
push( & mouse_events, InputMouseEvent {
|
||||
frame_id = event.frame_id,
|
||||
type = event.type,
|
||||
btn = event.mouse.btn,
|
||||
pos = event.mouse.pos,
|
||||
delta = event.mouse.delta,
|
||||
scroll = event.mouse.scroll,
|
||||
modifiers = event.modifiers,
|
||||
})
|
||||
|
||||
case .Mouse_Enter:
|
||||
push( & mouse_events, InputMouseEvent {
|
||||
frame_id = event.frame_id,
|
||||
type = event.type,
|
||||
btn = event.mouse.btn,
|
||||
pos = event.mouse.pos,
|
||||
delta = event.mouse.delta,
|
||||
scroll = event.mouse.scroll,
|
||||
modifiers = event.modifiers,
|
||||
})
|
||||
|
||||
case .Mouse_Leave:
|
||||
push( & mouse_events, InputMouseEvent {
|
||||
frame_id = event.frame_id,
|
||||
type = event.type,
|
||||
btn = event.mouse.btn,
|
||||
pos = event.mouse.pos,
|
||||
delta = event.mouse.delta,
|
||||
scroll = event.mouse.scroll,
|
||||
modifiers = event.modifiers,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
clear( staged_events )
|
||||
}
|
||||
|
||||
poll_input_events :: proc( input, prev_input : ^InputState, input_events : InputEvents )
|
||||
{
|
||||
input.keyboard = {}
|
||||
input.mouse = {}
|
||||
|
||||
input_events := input_events
|
||||
using input_events
|
||||
|
||||
@static prev_frame : u64 = u64_max
|
||||
|
||||
last_frame := peek_front( & events).frame_id
|
||||
|
||||
// No new events, don't update
|
||||
if prev_frame != 0 && last_frame == prev_frame do return
|
||||
|
||||
Iterate_Key_Events:
|
||||
{
|
||||
iter_obj := iterator( key_events ); iter := & iter_obj
|
||||
for event := next( iter ); event != nil; event = next( iter )
|
||||
{
|
||||
if last_frame == event.frame_id do return
|
||||
|
||||
key := & input.keyboard.keys[event.key]
|
||||
prev_key := prev_input.keyboard.keys[event.key]
|
||||
|
||||
first_transition := key.half_transitions == 0
|
||||
|
||||
#partial switch event.type {
|
||||
case .Key_Pressed:
|
||||
key.half_transitions += 1
|
||||
key.ended_down = true
|
||||
|
||||
case .Key_Released:
|
||||
key.half_transitions += 1
|
||||
key.ended_down = false
|
||||
}
|
||||
|
||||
frame_transition := first_transition && prev_key.ended_down != key.ended_down ? i32(1) : i32(0)
|
||||
key.half_transitions += frame_transition
|
||||
}
|
||||
}
|
||||
|
||||
Iterate_Mouse_Events:
|
||||
{
|
||||
iter_obj := iterator( mouse_events ); iter := & iter_obj
|
||||
for event := next( iter ); event != nil; event = next( iter )
|
||||
{
|
||||
if last_frame == event.frame_id do return
|
||||
|
||||
process_digital_btn :: proc( btn : ^DigitalBtn, prev_btn : DigitalBtn, ended_down : b32 )
|
||||
{
|
||||
first_transition := btn.half_transitions == 0
|
||||
|
||||
btn.half_transitions += 1
|
||||
btn.ended_down = ended_down
|
||||
|
||||
frame_transition := first_transition && prev_btn.ended_down != btn.ended_down ? i32(1) : i32(0)
|
||||
btn.half_transitions += frame_transition
|
||||
}
|
||||
|
||||
#partial switch event.type {
|
||||
case .Mouse_Pressed:
|
||||
btn := & input.mouse.btns[event.btn]
|
||||
prev_btn := prev_input.mouse.btns[event.btn]
|
||||
process_digital_btn( btn, prev_btn, true )
|
||||
|
||||
case .Mouse_Released:
|
||||
btn := & input.mouse.btns[event.btn]
|
||||
prev_btn := prev_input.mouse.btns[event.btn]
|
||||
process_digital_btn( btn, prev_btn, false )
|
||||
|
||||
case .Mouse_Scroll:
|
||||
input.mouse.scroll += event.scroll.x
|
||||
|
||||
case .Mouse_Move:
|
||||
case .Mouse_Enter:
|
||||
case .Mouse_Leave:
|
||||
// Handled elsewhere
|
||||
}
|
||||
|
||||
input.mouse.pos = event.pos
|
||||
input.mouse.delta = event.delta
|
||||
}
|
||||
}
|
||||
|
||||
prev_frame = last_frame
|
||||
}
|
@ -10,7 +10,7 @@ AnalogStick :: struct {
|
||||
|
||||
DigitalBtn :: struct {
|
||||
half_transitions : i32,
|
||||
ended_down : b32
|
||||
ended_down : b32,
|
||||
}
|
||||
|
||||
btn_pressed :: proc( btn : DigitalBtn ) -> b32 {
|
||||
@ -167,11 +167,11 @@ MouseState :: struct {
|
||||
btns : [16] DigitalBtn,
|
||||
using individual : struct {
|
||||
left, middle, right : DigitalBtn,
|
||||
side, forward, back, extra : DigitalBtn
|
||||
side, forward, back, extra : DigitalBtn,
|
||||
}
|
||||
},
|
||||
raw_pos, pos, delta : Vec2,
|
||||
vertical_wheel, horizontal_wheel : AnalogAxis
|
||||
raw_pos, pos, delta : Vec2,
|
||||
scroll : [2]AnalogAxis,
|
||||
}
|
||||
|
||||
mouse_world_delta :: #force_inline proc "contextless" () -> Vec2 {
|
||||
@ -183,10 +183,4 @@ mouse_world_delta :: #force_inline proc "contextless" () -> Vec2 {
|
||||
InputState :: struct {
|
||||
keyboard : KeyboardState,
|
||||
mouse : MouseState,
|
||||
|
||||
events : Array(InputEvent),
|
||||
key_events : Array(InputKeyEvent),
|
||||
mouse_events : Array(InputMouseEvent),
|
||||
|
||||
codes_pressed : Array(rune),
|
||||
}
|
||||
|
@ -7,43 +7,18 @@ import sokol_app "thirdparty:sokol/app"
|
||||
|
||||
to_modifiers_code_from_sokol :: proc( sokol_modifiers : u32 ) -> ( modifiers : ModifierCodeFlags )
|
||||
{
|
||||
if sokol_modifiers & sokol_app.MODIFIER_SHIFT != 0 {
|
||||
modifiers |= { .Shift }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_CTRL != 0 {
|
||||
modifiers |= { .Control }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_ALT != 0 {
|
||||
modifiers |= { .Alt }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_LMB != 0 {
|
||||
modifiers |= { .Left_Mouse }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_RMB != 0 {
|
||||
modifiers |= { .Right_Mouse }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_MMB != 0 {
|
||||
modifiers |= { .Middle_Mouse }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_LSHIFT != 0 {
|
||||
modifiers |= { .Left_Shift }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_RSHIFT != 0 {
|
||||
modifiers |= { .Right_Shift }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_LCTRL != 0 {
|
||||
modifiers |= { .Left_Control }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_RCTRL != 0 {
|
||||
modifiers |= { .Right_Control }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_LALT != 0 {
|
||||
modifiers |= { .Left_Alt }
|
||||
}
|
||||
if sokol_modifiers & sokol_app.MODIFIER_RALT != 0 {
|
||||
modifiers |= { .Right_Alt }
|
||||
}
|
||||
|
||||
if sokol_modifiers & sokol_app.MODIFIER_SHIFT != 0 do modifiers |= { .Shift }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_CTRL != 0 do modifiers |= { .Control }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_ALT != 0 do modifiers |= { .Alt }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_LMB != 0 do modifiers |= { .Left_Mouse }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_RMB != 0 do modifiers |= { .Right_Mouse }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_MMB != 0 do modifiers |= { .Middle_Mouse }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_LSHIFT != 0 do modifiers |= { .Left_Shift }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_RSHIFT != 0 do modifiers |= { .Right_Shift }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_LCTRL != 0 do modifiers |= { .Left_Control }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_RCTRL != 0 do modifiers |= { .Right_Control }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_LALT != 0 do modifiers |= { .Left_Alt }
|
||||
if sokol_modifiers & sokol_app.MODIFIER_RALT != 0 do modifiers |= { .Right_Alt }
|
||||
return
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user