///|
struct TouchDurationEntry {
id : Int
duration : Int
} derive(Debug)
///|
pub impl Show for TouchDurationEntry with output(self, logger) {
logger.write_object(to_repr(self))
}
///|
pub struct TouchInputState {
mut prev_touch_ids : Array[Int]
mut touch_ids : Array[Int]
mut just_pressed_touch_ids : Array[Int]
mut just_released_touch_ids : Array[Int]
mut durations : Array[TouchDurationEntry]
}
///|
fn normalize_touch_ids(snapshot : @core.InputSnapshot) -> Array[Int] {
let out : Array[Int] = []
for touch in snapshot.touches {
if !contains_key(out, touch.id) {
out.push(touch.id)
}
}
out
}
///|
fn duration_for_touch(entries : Array[TouchDurationEntry], id : Int) -> Int {
let mut out = 0
for entry in entries {
if entry.id == id {
out = entry.duration
}
}
out
}
///|
pub fn new_touch_input_state() -> TouchInputState {
{
prev_touch_ids: [],
touch_ids: [],
just_pressed_touch_ids: [],
just_released_touch_ids: [],
durations: [],
}
}
///|
pub fn update_touch_input_state(
state : TouchInputState,
snapshot : @core.InputSnapshot,
) -> Unit {
let prev_ids = state.touch_ids
let next_ids = normalize_touch_ids(snapshot)
let just_pressed : Array[Int] = []
for id in next_ids {
if !contains_key(prev_ids, id) {
just_pressed.push(id)
}
}
let just_released : Array[Int] = []
for id in prev_ids {
if !contains_key(next_ids, id) {
just_released.push(id)
}
}
let next_durations : Array[TouchDurationEntry] = []
for id in next_ids {
let duration = if contains_key(prev_ids, id) {
duration_for_touch(state.durations, id) + 1
} else {
1
}
next_durations.push({ id, duration })
}
state.prev_touch_ids = prev_ids
state.touch_ids = next_ids
state.just_pressed_touch_ids = just_pressed
state.just_released_touch_ids = just_released
state.durations = next_durations
}
///|
pub fn is_touch_pressed(state : TouchInputState, id : Int) -> Bool {
contains_key(state.touch_ids, id)
}
///|
pub fn is_touch_just_pressed(state : TouchInputState, id : Int) -> Bool {
contains_key(state.just_pressed_touch_ids, id)
}
///|
pub fn is_touch_just_released(state : TouchInputState, id : Int) -> Bool {
contains_key(state.just_released_touch_ids, id)
}
///|
pub fn touch_press_duration(state : TouchInputState, id : Int) -> Int {
duration_for_touch(state.durations, id)
}
///|
pub fn append_touch_ids(
state : TouchInputState,
dst : Array[Int],
) -> Array[Int] {
let out = dst
for id in state.touch_ids {
out.push(id)
}
out
}
///|
pub fn append_just_pressed_touch_ids(
state : TouchInputState,
dst : Array[Int],
) -> Array[Int] {
let out = dst
for id in state.just_pressed_touch_ids {
out.push(id)
}
out
}
///|
pub fn append_just_released_touch_ids(
state : TouchInputState,
dst : Array[Int],
) -> Array[Int] {
let out = dst
for id in state.just_released_touch_ids {
out.push(id)
}
out
}
///|
struct GamepadDurationEntry {
id : Int
duration : Int
} derive(Debug)
///|
pub impl Show for GamepadDurationEntry with output(self, logger) {
logger.write_object(to_repr(self))
}
///|
struct GamepadButtonKey {
gamepad_id : Int
button_id : Int
} derive(Debug)
///|
pub impl Show for GamepadButtonKey with output(self, logger) {
logger.write_object(to_repr(self))
}
///|
struct GamepadButtonDurationEntry {
gamepad_id : Int
button_id : Int
duration : Int
} derive(Debug)
///|
pub impl Show for GamepadButtonDurationEntry with output(self, logger) {
logger.write_object(to_repr(self))
}
///|
pub struct GamepadInputState {
mut prev_gamepad_ids : Array[Int]
mut gamepad_ids : Array[Int]
mut just_connected_gamepad_ids : Array[Int]
mut just_disconnected_gamepad_ids : Array[Int]
mut durations : Array[GamepadDurationEntry]
mut prev_pressed_buttons : Array[GamepadButtonKey]
mut pressed_buttons : Array[GamepadButtonKey]
mut just_pressed_buttons : Array[GamepadButtonKey]
mut just_released_buttons : Array[GamepadButtonKey]
mut button_durations : Array[GamepadButtonDurationEntry]
}
///|
fn normalize_gamepad_ids(snapshot : @core.InputSnapshot) -> Array[Int] {
let out : Array[Int] = []
for gamepad in snapshot.gamepads {
if !contains_key(out, gamepad.id) {
out.push(gamepad.id)
}
}
out
}
///|
fn contains_gamepad_button(
entries : Array[GamepadButtonKey],
gamepad_id : Int,
button_id : Int,
) -> Bool {
let mut found = false
for entry in entries {
if entry.gamepad_id == gamepad_id && entry.button_id == button_id {
found = true
}
}
found
}
///|
fn normalize_gamepad_buttons(
snapshot : @core.InputSnapshot,
) -> Array[GamepadButtonKey] {
let out : Array[GamepadButtonKey] = []
for gamepad in snapshot.gamepads {
for button_id in gamepad.pressed_buttons {
if !contains_gamepad_button(out, gamepad.id, button_id) {
out.push({ gamepad_id: gamepad.id, button_id })
}
}
}
out
}
///|
fn duration_for_gamepad(entries : Array[GamepadDurationEntry], id : Int) -> Int {
let mut out = 0
for entry in entries {
if entry.id == id {
out = entry.duration
}
}
out
}
///|
fn duration_for_gamepad_button(
entries : Array[GamepadButtonDurationEntry],
gamepad_id : Int,
button_id : Int,
) -> Int {
let mut out = 0
for entry in entries {
if entry.gamepad_id == gamepad_id && entry.button_id == button_id {
out = entry.duration
}
}
out
}
///|
pub fn new_gamepad_input_state() -> GamepadInputState {
{
prev_gamepad_ids: [],
gamepad_ids: [],
just_connected_gamepad_ids: [],
just_disconnected_gamepad_ids: [],
durations: [],
prev_pressed_buttons: [],
pressed_buttons: [],
just_pressed_buttons: [],
just_released_buttons: [],
button_durations: [],
}
}
///|
pub fn update_gamepad_input_state(
state : GamepadInputState,
snapshot : @core.InputSnapshot,
) -> Unit {
let prev_gamepad_ids = state.gamepad_ids
let next_gamepad_ids = normalize_gamepad_ids(snapshot)
let just_connected : Array[Int] = []
for id in next_gamepad_ids {
if !contains_key(prev_gamepad_ids, id) {
just_connected.push(id)
}
}
let just_disconnected : Array[Int] = []
for id in prev_gamepad_ids {
if !contains_key(next_gamepad_ids, id) {
just_disconnected.push(id)
}
}
let next_durations : Array[GamepadDurationEntry] = []
for id in next_gamepad_ids {
let duration = if contains_key(prev_gamepad_ids, id) {
duration_for_gamepad(state.durations, id) + 1
} else {
1
}
next_durations.push({ id, duration })
}
let prev_buttons = state.pressed_buttons
let next_buttons = normalize_gamepad_buttons(snapshot)
let just_pressed_buttons : Array[GamepadButtonKey] = []
for entry in next_buttons {
if !contains_gamepad_button(prev_buttons, entry.gamepad_id, entry.button_id) {
just_pressed_buttons.push({
gamepad_id: entry.gamepad_id,
button_id: entry.button_id,
})
}
}
let just_released_buttons : Array[GamepadButtonKey] = []
for entry in prev_buttons {
if !contains_gamepad_button(next_buttons, entry.gamepad_id, entry.button_id) {
just_released_buttons.push({
gamepad_id: entry.gamepad_id,
button_id: entry.button_id,
})
}
}
let next_button_durations : Array[GamepadButtonDurationEntry] = []
for entry in next_buttons {
let duration = if contains_gamepad_button(
prev_buttons,
entry.gamepad_id,
entry.button_id,
) {
duration_for_gamepad_button(
state.button_durations,
entry.gamepad_id,
entry.button_id,
) +
1
} else {
1
}
next_button_durations.push({
gamepad_id: entry.gamepad_id,
button_id: entry.button_id,
duration,
})
}
state.prev_gamepad_ids = prev_gamepad_ids
state.gamepad_ids = next_gamepad_ids
state.just_connected_gamepad_ids = just_connected
state.just_disconnected_gamepad_ids = just_disconnected
state.durations = next_durations
state.prev_pressed_buttons = prev_buttons
state.pressed_buttons = next_buttons
state.just_pressed_buttons = just_pressed_buttons
state.just_released_buttons = just_released_buttons
state.button_durations = next_button_durations
}
///|
pub fn is_gamepad_connected(state : GamepadInputState, id : Int) -> Bool {
contains_key(state.gamepad_ids, id)
}
///|
pub fn is_gamepad_just_connected(state : GamepadInputState, id : Int) -> Bool {
contains_key(state.just_connected_gamepad_ids, id)
}
///|
pub fn is_gamepad_just_disconnected(
state : GamepadInputState,
id : Int,
) -> Bool {
contains_key(state.just_disconnected_gamepad_ids, id)
}
///|
pub fn gamepad_connection_duration(state : GamepadInputState, id : Int) -> Int {
duration_for_gamepad(state.durations, id)
}
///|
pub fn is_gamepad_button_pressed(
state : GamepadInputState,
gamepad_id : Int,
button_id : Int,
) -> Bool {
contains_gamepad_button(state.pressed_buttons, gamepad_id, button_id)
}
///|
pub fn is_gamepad_button_just_pressed(
state : GamepadInputState,
gamepad_id : Int,
button_id : Int,
) -> Bool {
contains_gamepad_button(state.just_pressed_buttons, gamepad_id, button_id)
}
///|
pub fn is_gamepad_button_just_released(
state : GamepadInputState,
gamepad_id : Int,
button_id : Int,
) -> Bool {
contains_gamepad_button(state.just_released_buttons, gamepad_id, button_id)
}
///|
pub fn gamepad_pressed_button_count(state : GamepadInputState) -> Int {
state.pressed_buttons.length()
}
///|
pub fn gamepad_just_pressed_button_count(state : GamepadInputState) -> Int {
state.just_pressed_buttons.length()
}
///|
pub fn gamepad_just_released_button_count(state : GamepadInputState) -> Int {
state.just_released_buttons.length()
}
///|
pub fn gamepad_button_press_duration(
state : GamepadInputState,
gamepad_id : Int,
button_id : Int,
) -> Int {
duration_for_gamepad_button(state.button_durations, gamepad_id, button_id)
}
///|
pub fn append_connected_gamepad_ids(
state : GamepadInputState,
dst : Array[Int],
) -> Array[Int] {
let out = dst
for id in state.gamepad_ids {
out.push(id)
}
out
}
///|
pub fn append_just_connected_gamepad_ids(
state : GamepadInputState,
dst : Array[Int],
) -> Array[Int] {
let out = dst
for id in state.just_connected_gamepad_ids {
out.push(id)
}
out
}
///|
pub fn append_just_disconnected_gamepad_ids(
state : GamepadInputState,
dst : Array[Int],
) -> Array[Int] {
let out = dst
for id in state.just_disconnected_gamepad_ids {
out.push(id)
}
out
}