#include "input.h"
#include "input_keyboard.h"
#include "../platforms/platform.h"
#include "../libraries/array.h"
#include "../libraries/ferr_thread.h"
namespace sk {
struct keyboard_event_t {
key_ key;
int16_t down;
};
struct keyboard_t {
uint8_t keys[key_MAX];
array_t<keyboard_event_t> events;
array_t<char32_t> characters;
int32_t queue_counter;
};
struct input_keyboard_state_t {
keyboard_t key_data;
array_t<keyboard_event_t> key_pending;
array_t<char32_t> chars_pending;
ft_mutex_t key_pending_mtx;
bool key_suspended;
float last_physical_keypress;
};
static input_keyboard_state_t local = {};
void input_keyboard_initialize() {
local = {};
local.last_physical_keypress = -1000;
local.key_pending_mtx = ft_mutex_create();
}
void input_keyboard_shutdown() {
ft_mutex_destroy(&local.key_pending_mtx);
local.key_pending .free();
local.chars_pending .free();
local.key_data.events .free();
local.key_data.characters.free();
local = {};
}
void input_keyboard_suspend(bool suspend) {
local.key_suspended = suspend;
}
void input_keyboard_update() {
input_text_reset();
array_t<keyboard_event_t> &evts = local.key_data.events;
for (int32_t i = 0; i < evts.count; i++) {
if (evts[i].down)
local.key_data.keys[evts[i].key] &= ~button_state_just_active;
else
local.key_data.keys[evts[i].key] &= ~button_state_just_inactive;
}
local.key_data.events .clear();
local.key_data.characters.clear();
ft_mutex_lock(local.key_pending_mtx);
local.key_data.events .add_range(local.key_pending .data, local.key_pending .count);
local.key_data.characters.add_range(local.chars_pending.data, local.chars_pending.count);
local.key_pending .clear();
local.chars_pending.clear();
ft_mutex_unlock(local.key_pending_mtx);
evts = local.key_data.events;
for (int32_t i = 0; i < evts.count; i++) {
keyboard_event_t &evt = evts.get(i);
if (evt.down) {
local.key_data.keys[evt.key] |= button_state_just_active | button_state_active;
} else {
local.key_data.keys[evt.key] &= ~button_state_active;
local.key_data.keys[evt.key] |= button_state_just_inactive;
}
}
}
void input_key_inject_press(key_ key) {
if (local.key_suspended) return;
ft_mutex_lock(local.key_pending_mtx);
keyboard_event_t evt;
evt.key = key;
evt.down = 1;
local.key_pending.add(evt);
ft_mutex_unlock(local.key_pending_mtx);
}
void input_key_inject_release(key_ key) {
if (local.key_suspended && (input_keyboard_get(key) & button_state_inactive))
return;
ft_mutex_lock(local.key_pending_mtx);
keyboard_event_t evt;
evt.key = key;
evt.down = 0;
local.key_pending.add(evt);
ft_mutex_unlock(local.key_pending_mtx);
}
button_state_ input_keyboard_get(key_ key) {
return (button_state_)local.key_data.keys[key];
}
void input_text_inject_char(char32_t character) {
if (local.key_suspended) return;
ft_mutex_lock(local.key_pending_mtx);
local.chars_pending.add(character);
ft_mutex_unlock(local.key_pending_mtx);
}
char32_t input_text_consume() {
if (local.key_data.queue_counter >= local.key_data.characters.count) return 0;
char32_t result = local.key_data.characters[local.key_data.queue_counter];
local.key_data.queue_counter++;
return result;
}
void input_text_reset() {
local.key_data.queue_counter = 0;
}
float input_get_last_physical_keypress_time() {
return local.last_physical_keypress;
}
void input_set_last_physical_keypress_time(float time) {
local.last_physical_keypress = time;
}
}