// Copyright 2025 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
pub struct ButtonData {
last_event_ts : Int64
counter : Int64
value : Double
is_pressed : Bool
is_repeating : Bool
}
///|
fn ButtonData::new(
value : Double,
pressed : Bool,
repeating : Bool,
counter : Int64,
time : Int64,
) -> ButtonData {
{
last_event_ts: time,
counter,
value,
is_pressed: pressed,
is_repeating: repeating,
}
}
///|
pub fn ButtonData::is_pressed(self : ButtonData) -> Bool {
self.is_pressed
}
///|
pub fn ButtonData::value(self : ButtonData) -> Double {
self.value
}
///|
pub fn ButtonData::is_repeating(self : ButtonData) -> Bool {
self.is_repeating
}
///|
pub fn ButtonData::counter(self : ButtonData) -> Int64 {
self.counter
}
///|
pub fn ButtonData::timestamp(self : ButtonData) -> Int64 {
self.last_event_ts
}
///|
pub struct AxisData {
last_event_ts : Int64
last_event_c : Int64
value : Double
}
///|
fn AxisData::new(value : Double, counter : Int64, time : Int64) -> AxisData {
{ last_event_ts: time, last_event_c: counter, value }
}
///|
pub fn AxisData::value(self : AxisData) -> Double {
self.value
}
///|
pub fn AxisData::counter(self : AxisData) -> Int64 {
self.last_event_c
}
///|
pub fn AxisData::timestamp(self : AxisData) -> Int64 {
self.last_event_ts
}
///|
pub struct GamepadState {
buttons : Array[(Code, ButtonData)]
axes : Array[(Code, AxisData)]
}
///|
pub fn GamepadState::new() -> GamepadState {
{ buttons: [], axes: [] }
}
///|
pub fn GamepadState::buttons_entries(
self : GamepadState,
) -> Array[(Code, ButtonData)] {
self.buttons.copy()
}
///|
pub fn GamepadState::axes_entries(
self : GamepadState,
) -> Array[(Code, AxisData)] {
self.axes.copy()
}
///|
fn find_idx_button(buttons : Array[(Code, ButtonData)], code : Code) -> Int? {
for i in 0.. Int? {
for i in 0.. Bool {
match find_idx_button(self.buttons, btn) {
None => false
Some(i) => {
let (_, data) = self.buttons[i]
data.is_pressed()
}
}
}
///|
pub fn GamepadState::value(self : GamepadState, el : Code) -> Double {
match find_idx_axis(self.axes, el) {
Some(i) => {
let (_, data) = self.axes[i]
data.value()
}
None =>
match find_idx_button(self.buttons, el) {
Some(i) => {
let (_, data) = self.buttons[i]
data.value()
}
None => 0.0
}
}
}
///|
pub fn GamepadState::button_data(
self : GamepadState,
btn : Code,
) -> ButtonData? {
match find_idx_button(self.buttons, btn) {
None => None
Some(i) => {
let (_, data) = self.buttons[i]
Some(data)
}
}
}
///|
pub fn GamepadState::axis_data(self : GamepadState, axis : Code) -> AxisData? {
match find_idx_axis(self.axes, axis) {
None => None
Some(i) => {
let (_, data) = self.axes[i]
Some(data)
}
}
}
///|
fn GamepadState::set_btn_pressed(
self : GamepadState,
btn : Code,
pressed : Bool,
counter : Int64,
timestamp : Int64,
) -> Unit {
let idx = find_idx_button(self.buttons, btn)
let data = match idx {
None =>
ButtonData::new(
if pressed {
1.0
} else {
0.0
},
pressed,
false,
counter,
timestamp,
)
Some(i) => {
let (_, old) = self.buttons[i]
ButtonData::new(old.value(), pressed, false, counter, timestamp)
}
}
match idx {
None => self.buttons.push((btn, data))
Some(i) => self.buttons[i] = (btn, data)
}
}
///|
fn GamepadState::set_btn_repeating(
self : GamepadState,
btn : Code,
counter : Int64,
timestamp : Int64,
) -> Unit {
let idx = find_idx_button(self.buttons, btn)
let data = match idx {
None => ButtonData::new(1.0, true, true, counter, timestamp)
Some(i) => {
let (_, old) = self.buttons[i]
ButtonData::new(old.value(), old.is_pressed(), true, counter, timestamp)
}
}
match idx {
None => self.buttons.push((btn, data))
Some(i) => self.buttons[i] = (btn, data)
}
}
///|
fn GamepadState::set_btn_value(
self : GamepadState,
btn : Code,
value : Double,
counter : Int64,
timestamp : Int64,
) -> Unit {
let idx = find_idx_button(self.buttons, btn)
let data = match idx {
None => ButtonData::new(value, false, false, counter, timestamp)
Some(i) => {
let (_, old) = self.buttons[i]
ButtonData::new(
value,
old.is_pressed(),
old.is_repeating(),
counter,
timestamp,
)
}
}
match idx {
None => self.buttons.push((btn, data))
Some(i) => self.buttons[i] = (btn, data)
}
}
///|
fn GamepadState::update_axis(
self : GamepadState,
axis : Code,
data : AxisData,
) -> Unit {
match find_idx_axis(self.axes, axis) {
None => self.axes.push((axis, data))
Some(i) => self.axes[i] = (axis, data)
}
}
///|
fn GamepadState::set_axis_value(
self : GamepadState,
axis : Code,
value : Double,
counter : Int64,
timestamp : Int64,
) -> Unit {
self.update_axis(axis, AxisData::new(value, counter, timestamp))
}