mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-16 14:08:59 +07:00
separate input devices
This commit is contained in:
@@ -13,6 +13,8 @@
|
|||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
class debug;
|
class debug;
|
||||||
|
class mouse;
|
||||||
|
class keyboard;
|
||||||
class input;
|
class input;
|
||||||
class vfs;
|
class vfs;
|
||||||
class window;
|
class window;
|
||||||
|
|||||||
@@ -11,45 +11,78 @@
|
|||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
class bad_input_operation final : public exception {
|
class mouse final : private noncopyable {
|
||||||
public:
|
public:
|
||||||
const char* what() const noexcept final {
|
mouse();
|
||||||
return "bad input operation";
|
~mouse() noexcept;
|
||||||
}
|
|
||||||
|
bool is_any_button_pressed() const noexcept;
|
||||||
|
bool is_any_button_just_pressed() const noexcept;
|
||||||
|
bool is_any_button_just_released() const noexcept;
|
||||||
|
|
||||||
|
bool is_button_pressed(mouse_button btn) const noexcept;
|
||||||
|
bool is_button_just_pressed(mouse_button btn) const noexcept;
|
||||||
|
bool is_button_just_released(mouse_button btn) const noexcept;
|
||||||
|
|
||||||
|
void extract_pressed_buttons(std::vector<mouse_button>& dst) const;
|
||||||
|
void extract_just_pressed_buttons(std::vector<mouse_button>& dst) const;
|
||||||
|
void extract_just_released_buttons(std::vector<mouse_button>& dst) const;
|
||||||
|
private:
|
||||||
|
class state;
|
||||||
|
friend class input;
|
||||||
|
std::unique_ptr<state> state_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class keyboard final : private noncopyable {
|
||||||
|
public:
|
||||||
|
keyboard();
|
||||||
|
~keyboard() noexcept;
|
||||||
|
|
||||||
|
bool is_any_key_pressed() const noexcept;
|
||||||
|
bool is_any_key_just_pressed() const noexcept;
|
||||||
|
bool is_any_key_just_released() const noexcept;
|
||||||
|
|
||||||
|
bool is_key_pressed(keyboard_key key) const noexcept;
|
||||||
|
bool is_key_just_pressed(keyboard_key key) const noexcept;
|
||||||
|
bool is_key_just_released(keyboard_key key) const noexcept;
|
||||||
|
|
||||||
|
void extract_pressed_keys(std::vector<keyboard_key>& dst) const;
|
||||||
|
void extract_just_pressed_keys(std::vector<keyboard_key>& dst) const;
|
||||||
|
void extract_just_released_keys(std::vector<keyboard_key>& dst) const;
|
||||||
|
private:
|
||||||
|
class state;
|
||||||
|
friend class input;
|
||||||
|
std::unique_ptr<state> state_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class input final : public module<input> {
|
class input final : public module<input> {
|
||||||
|
public:
|
||||||
|
struct input_char_event {
|
||||||
|
char32_t uchar = 0;
|
||||||
|
};
|
||||||
|
struct mouse_button_event {
|
||||||
|
mouse_button button = mouse_button::unknown;
|
||||||
|
mouse_button_action action = mouse_button_action::unknown;
|
||||||
|
};
|
||||||
|
struct keyboard_key_event {
|
||||||
|
keyboard_key key = keyboard_key::unknown;
|
||||||
|
keyboard_key_action action = keyboard_key_action::unknown;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
input();
|
input();
|
||||||
~input() noexcept;
|
~input() noexcept;
|
||||||
|
|
||||||
bool is_any_mouse_button_pressed() const noexcept;
|
str32 input_text() const;
|
||||||
bool is_any_mouse_button_just_pressed() const noexcept;
|
void extract_input_text(str32& dst) const;
|
||||||
bool is_any_mouse_button_just_released() const noexcept;
|
|
||||||
|
|
||||||
bool is_any_keyboard_key_pressed() const noexcept;
|
const mouse& mouse() const noexcept;
|
||||||
bool is_any_keyboard_key_just_pressed() const noexcept;
|
const keyboard& keyboard() const noexcept;
|
||||||
bool is_any_keyboard_key_just_released() const noexcept;
|
|
||||||
|
|
||||||
bool is_mouse_button_pressed(mouse_button btn) const noexcept;
|
void post_event(input_char_event evt) noexcept;
|
||||||
bool is_mouse_button_just_pressed(mouse_button btn) const noexcept;
|
void post_event(mouse_button_event evt) noexcept;
|
||||||
bool is_mouse_button_just_released(mouse_button btn) const noexcept;
|
void post_event(keyboard_key_event evt) noexcept;
|
||||||
|
|
||||||
bool is_keyboard_key_pressed(keyboard_key key) const noexcept;
|
|
||||||
bool is_keyboard_key_just_pressed(keyboard_key key) const noexcept;
|
|
||||||
bool is_keyboard_key_just_released(keyboard_key key) const noexcept;
|
|
||||||
|
|
||||||
void extract_pressed_mouse_buttons(std::vector<mouse_button>& dst) const;
|
|
||||||
void extract_just_pressed_mouse_buttons(std::vector<mouse_button>& dst) const;
|
|
||||||
void extract_just_released_mouse_buttons(std::vector<mouse_button>& dst) const;
|
|
||||||
|
|
||||||
void extract_pressed_keyboard_keys(std::vector<keyboard_key>& dst) const;
|
|
||||||
void extract_just_pressed_keyboard_keys(std::vector<keyboard_key>& dst) const;
|
|
||||||
void extract_just_released_keyboard_keys(std::vector<keyboard_key>& dst) const;
|
|
||||||
|
|
||||||
void frame_tick() noexcept;
|
void frame_tick() noexcept;
|
||||||
void post_event(keyboard_key key, keyboard_key_action act) noexcept;
|
|
||||||
void post_event(mouse_button btn, mouse_button_action act) noexcept;
|
|
||||||
private:
|
private:
|
||||||
class state;
|
class state;
|
||||||
std::unique_ptr<state> state_;
|
std::unique_ptr<state> state_;
|
||||||
@@ -58,6 +91,7 @@ namespace e2d
|
|||||||
class window_input_source : public window::event_listener {
|
class window_input_source : public window::event_listener {
|
||||||
public:
|
public:
|
||||||
window_input_source(input& input) noexcept;
|
window_input_source(input& input) noexcept;
|
||||||
|
void on_input_char(char32_t uchar) noexcept final;
|
||||||
void on_mouse_button(mouse_button btn, mouse_button_action act) noexcept final;
|
void on_mouse_button(mouse_button btn, mouse_button_action act) noexcept final;
|
||||||
void on_keyboard_key(keyboard_key key, u32 scancode, keyboard_key_action act) noexcept final;
|
void on_keyboard_key(keyboard_key key, u32 scancode, keyboard_key_action act) noexcept final;
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ int main() {
|
|||||||
.trace("SAMPLE: window virtual size: %0", w.virtual_size())
|
.trace("SAMPLE: window virtual size: %0", w.virtual_size())
|
||||||
.trace("SAMPLE: window framebuffer size: %0", w.framebuffer_size());
|
.trace("SAMPLE: window framebuffer size: %0", w.framebuffer_size());
|
||||||
|
|
||||||
while ( !w.should_close() && !i.is_keyboard_key_just_released(keyboard_key::escape) ) {
|
const keyboard& k = i.keyboard();
|
||||||
|
while ( !w.should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
|
||||||
i.frame_tick();
|
i.frame_tick();
|
||||||
w.swap_buffers();
|
w.swap_buffers();
|
||||||
window::frame_tick();
|
window::frame_tick();
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ int main() {
|
|||||||
.trace("SAMPLE: window virtual size: %0", w.virtual_size())
|
.trace("SAMPLE: window virtual size: %0", w.virtual_size())
|
||||||
.trace("SAMPLE: window framebuffer size: %0", w.framebuffer_size());
|
.trace("SAMPLE: window framebuffer size: %0", w.framebuffer_size());
|
||||||
|
|
||||||
while ( !w.should_close() && !i.is_keyboard_key_just_released(keyboard_key::escape) ) {
|
const keyboard& k = i.keyboard();
|
||||||
|
while ( !w.should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
|
||||||
i.frame_tick();
|
i.frame_tick();
|
||||||
w.swap_buffers();
|
w.swap_buffers();
|
||||||
window::frame_tick();
|
window::frame_tick();
|
||||||
|
|||||||
@@ -8,6 +8,23 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
using namespace e2d;
|
||||||
|
|
||||||
|
enum class button_state : u8 {
|
||||||
|
pressed,
|
||||||
|
released,
|
||||||
|
just_pressed,
|
||||||
|
just_released
|
||||||
|
};
|
||||||
|
|
||||||
|
void update_button_state(enum button_state& state) noexcept {
|
||||||
|
if ( state == button_state::just_pressed ) {
|
||||||
|
state = button_state::pressed;
|
||||||
|
} else if ( state == button_state::just_released ) {
|
||||||
|
state = button_state::released;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template < typename E >
|
template < typename E >
|
||||||
constexpr std::underlying_type_t<E> enum_to_number(E e) noexcept {
|
constexpr std::underlying_type_t<E> enum_to_number(E e) noexcept {
|
||||||
return static_cast<std::underlying_type_t<E>>(e);
|
return static_cast<std::underlying_type_t<E>>(e);
|
||||||
@@ -16,53 +33,308 @@ namespace
|
|||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// class mouse::state
|
||||||
|
//
|
||||||
|
|
||||||
|
class mouse::state final : private e2d::noncopyable {
|
||||||
|
public:
|
||||||
|
mutable std::mutex mutex;
|
||||||
|
std::array<button_state, enum_to_number(mouse_button::unknown) + 1> button_states;
|
||||||
|
char _pad[2];
|
||||||
|
public:
|
||||||
|
state() noexcept {
|
||||||
|
std::fill(
|
||||||
|
button_states.begin(),
|
||||||
|
button_states.end(),
|
||||||
|
button_state::released);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t button_index(mouse_button btn) const noexcept {
|
||||||
|
const auto index = enum_to_number(btn);
|
||||||
|
E2D_ASSERT(index < button_states.size());
|
||||||
|
return math::numeric_cast<std::size_t>(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void frame_tick() noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(mutex);
|
||||||
|
std::for_each(
|
||||||
|
button_states.begin(),
|
||||||
|
button_states.end(),
|
||||||
|
&update_button_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void post_event(input::mouse_button_event evt) noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(mutex);
|
||||||
|
const std::size_t index = button_index(evt.button);
|
||||||
|
const enum button_state ms = button_states[index];
|
||||||
|
switch ( evt.action ) {
|
||||||
|
case mouse_button_action::press:
|
||||||
|
if ( ms == button_state::released || ms == button_state::just_released ) {
|
||||||
|
button_states[index] = button_state::just_pressed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mouse_button_action::release:
|
||||||
|
if ( ms == button_state::just_pressed || ms == button_state::pressed ) {
|
||||||
|
button_states[index] = button_state::just_released;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mouse_button_action::unknown:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
E2D_ASSERT_MSG(false, "unexpected mouse action");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// class keyboard::state
|
||||||
|
//
|
||||||
|
|
||||||
|
class keyboard::state final : private e2d::noncopyable {
|
||||||
|
public:
|
||||||
|
mutable std::mutex mutex;
|
||||||
|
std::array<button_state, enum_to_number(keyboard_key::unknown) + 1> key_states;
|
||||||
|
public:
|
||||||
|
state() noexcept {
|
||||||
|
std::fill(
|
||||||
|
key_states.begin(),
|
||||||
|
key_states.end(),
|
||||||
|
button_state::released);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t key_index(keyboard_key key) const noexcept {
|
||||||
|
const auto index = enum_to_number(key);
|
||||||
|
E2D_ASSERT(index < key_states.size());
|
||||||
|
return math::numeric_cast<std::size_t>(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void frame_tick() noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(mutex);
|
||||||
|
std::for_each(
|
||||||
|
key_states.begin(),
|
||||||
|
key_states.end(),
|
||||||
|
&update_button_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void post_event(input::keyboard_key_event evt) noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(mutex);
|
||||||
|
const std::size_t index = key_index(evt.key);
|
||||||
|
const enum button_state ks = key_states[index];
|
||||||
|
switch ( evt.action ) {
|
||||||
|
case keyboard_key_action::press:
|
||||||
|
case keyboard_key_action::repeat:
|
||||||
|
if ( ks == button_state::released || ks == button_state::just_released ) {
|
||||||
|
key_states[index] = button_state::just_pressed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case keyboard_key_action::release:
|
||||||
|
if ( ks == button_state::pressed || ks == button_state::just_pressed ) {
|
||||||
|
key_states[index] = button_state::just_released;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case keyboard_key_action::unknown:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
E2D_ASSERT_MSG(false, "unexpected key action");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// class mouse
|
||||||
|
//
|
||||||
|
|
||||||
|
mouse::mouse()
|
||||||
|
: state_(new state()) {}
|
||||||
|
mouse::~mouse() noexcept = default;
|
||||||
|
|
||||||
|
bool mouse::is_any_button_pressed() const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
return std::any_of(
|
||||||
|
state_->button_states.cbegin(),
|
||||||
|
state_->button_states.cend(),
|
||||||
|
[](button_state s) noexcept {
|
||||||
|
return s == button_state::just_pressed
|
||||||
|
|| s == button_state::pressed;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mouse::is_any_button_just_pressed() const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
return std::any_of(
|
||||||
|
state_->button_states.cbegin(),
|
||||||
|
state_->button_states.cend(),
|
||||||
|
[](button_state s) noexcept {
|
||||||
|
return s == button_state::just_pressed;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mouse::is_any_button_just_released() const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
return std::any_of(
|
||||||
|
state_->button_states.cbegin(),
|
||||||
|
state_->button_states.cend(),
|
||||||
|
[](button_state s) noexcept {
|
||||||
|
return s == button_state::just_released;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mouse::is_button_pressed(mouse_button btn) const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
const std::size_t index = state_->button_index(btn);
|
||||||
|
const enum button_state ms = state_->button_states[index];
|
||||||
|
return ms == button_state::just_pressed
|
||||||
|
|| ms == button_state::pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mouse::is_button_just_pressed(mouse_button btn) const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
const std::size_t index = state_->button_index(btn);
|
||||||
|
const enum button_state ms = state_->button_states[index];
|
||||||
|
return ms == button_state::just_pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mouse::is_button_just_released(mouse_button btn) const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
const std::size_t index = state_->button_index(btn);
|
||||||
|
const enum button_state ms = state_->button_states[index];
|
||||||
|
return ms == button_state::just_released;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse::extract_pressed_buttons(std::vector<mouse_button>& dst) const {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
for ( std::size_t i = 0; i < state_->button_states.size(); ++i ) {
|
||||||
|
button_state ks = state_->button_states[i];
|
||||||
|
if ( ks == button_state::just_pressed || ks == button_state::pressed ) {
|
||||||
|
dst.push_back(static_cast<mouse_button>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse::extract_just_pressed_buttons(std::vector<mouse_button>& dst) const {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
for ( std::size_t i = 0; i < state_->button_states.size(); ++i ) {
|
||||||
|
button_state ks = state_->button_states[i];
|
||||||
|
if ( ks == button_state::just_pressed ) {
|
||||||
|
dst.push_back(static_cast<mouse_button>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse::extract_just_released_buttons(std::vector<mouse_button>& dst) const {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
for ( std::size_t i = 0; i < state_->button_states.size(); ++i ) {
|
||||||
|
button_state ks = state_->button_states[i];
|
||||||
|
if ( ks == button_state::just_released ) {
|
||||||
|
dst.push_back(static_cast<mouse_button>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// class keyboard
|
||||||
|
//
|
||||||
|
|
||||||
|
keyboard::keyboard()
|
||||||
|
: state_(new state()) {}
|
||||||
|
keyboard::~keyboard() noexcept = default;
|
||||||
|
|
||||||
|
bool keyboard::is_any_key_pressed() const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
return std::any_of(
|
||||||
|
state_->key_states.cbegin(),
|
||||||
|
state_->key_states.cend(),
|
||||||
|
[](button_state s) noexcept {
|
||||||
|
return s == button_state::just_pressed
|
||||||
|
|| s == button_state::pressed;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyboard::is_any_key_just_pressed() const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
return std::any_of(
|
||||||
|
state_->key_states.cbegin(),
|
||||||
|
state_->key_states.cend(),
|
||||||
|
[](button_state s) noexcept {
|
||||||
|
return s == button_state::just_pressed;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyboard::is_any_key_just_released() const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
return std::any_of(
|
||||||
|
state_->key_states.cbegin(),
|
||||||
|
state_->key_states.cend(),
|
||||||
|
[](button_state s) noexcept {
|
||||||
|
return s == button_state::just_released;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyboard::is_key_pressed(keyboard_key key) const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
const std::size_t index = state_->key_index(key);
|
||||||
|
const enum button_state ks = state_->key_states[index];
|
||||||
|
return ks == button_state::just_pressed
|
||||||
|
|| ks == button_state::pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyboard::is_key_just_pressed(keyboard_key key) const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
const std::size_t index = state_->key_index(key);
|
||||||
|
const enum button_state ks = state_->key_states[index];
|
||||||
|
return ks == button_state::just_pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool keyboard::is_key_just_released(keyboard_key key) const noexcept {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
const std::size_t index = state_->key_index(key);
|
||||||
|
const enum button_state ks = state_->key_states[index];
|
||||||
|
return ks == button_state::just_released;
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard::extract_pressed_keys(std::vector<keyboard_key>& dst) const {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
for ( std::size_t i = 0; i < state_->key_states.size(); ++i ) {
|
||||||
|
button_state ks = state_->key_states[i];
|
||||||
|
if ( ks == button_state::just_pressed || ks == button_state::pressed ) {
|
||||||
|
dst.push_back(static_cast<keyboard_key>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard::extract_just_pressed_keys(std::vector<keyboard_key>& dst) const {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
for ( std::size_t i = 0; i < state_->key_states.size(); ++i ) {
|
||||||
|
button_state ks = state_->key_states[i];
|
||||||
|
if ( ks == button_state::just_pressed ) {
|
||||||
|
dst.push_back(static_cast<keyboard_key>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard::extract_just_released_keys(std::vector<keyboard_key>& dst) const {
|
||||||
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
|
for ( std::size_t i = 0; i < state_->key_states.size(); ++i ) {
|
||||||
|
button_state ks = state_->key_states[i];
|
||||||
|
if ( ks == button_state::just_released ) {
|
||||||
|
dst.push_back(static_cast<keyboard_key>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// class input::state
|
// class input::state
|
||||||
//
|
//
|
||||||
|
|
||||||
class input::state final : private e2d::noncopyable {
|
class input::state final : private e2d::noncopyable {
|
||||||
public:
|
public:
|
||||||
enum class button_state : u8 {
|
std::mutex mutex;
|
||||||
pressed,
|
str32 input_text;
|
||||||
released,
|
class mouse mouse;
|
||||||
just_pressed,
|
class keyboard keyboard;
|
||||||
just_released
|
|
||||||
};
|
|
||||||
mutable std::mutex mutex;
|
|
||||||
std::array<button_state, enum_to_number(keyboard_key::unknown) + 1> key_button_states;
|
|
||||||
std::array<button_state, enum_to_number(mouse_button::unknown) + 1> mouse_button_states;
|
|
||||||
char _pad[2];
|
|
||||||
public:
|
|
||||||
state() noexcept {
|
|
||||||
std::fill(
|
|
||||||
key_button_states.begin(),
|
|
||||||
key_button_states.end(),
|
|
||||||
button_state::released);
|
|
||||||
std::fill(
|
|
||||||
mouse_button_states.begin(),
|
|
||||||
mouse_button_states.end(),
|
|
||||||
button_state::released);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t mouse_button_index(mouse_button btn) const noexcept {
|
|
||||||
const auto index = enum_to_number(btn);
|
|
||||||
E2D_ASSERT(index < mouse_button_states.size());
|
|
||||||
return math::numeric_cast<std::size_t>(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t keyboard_key_index(keyboard_key key) const noexcept {
|
|
||||||
const auto index = enum_to_number(key);
|
|
||||||
E2D_ASSERT(index < key_button_states.size());
|
|
||||||
return math::numeric_cast<std::size_t>(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_button_state(enum button_state& state) noexcept {
|
|
||||||
if ( state == button_state::just_pressed ) {
|
|
||||||
state = button_state::pressed;
|
|
||||||
} else if ( state == button_state::just_released ) {
|
|
||||||
state = button_state::released;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -73,229 +345,44 @@ namespace e2d
|
|||||||
: state_(new state()) {}
|
: state_(new state()) {}
|
||||||
input::~input() noexcept = default;
|
input::~input() noexcept = default;
|
||||||
|
|
||||||
bool input::is_any_mouse_button_pressed() const noexcept {
|
str32 input::input_text() const {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
return std::any_of(
|
return state_->input_text;
|
||||||
state_->mouse_button_states.cbegin(),
|
|
||||||
state_->mouse_button_states.cend(),
|
|
||||||
[](state::button_state s) noexcept {
|
|
||||||
return s == state::button_state::just_pressed
|
|
||||||
|| s == state::button_state::pressed;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool input::is_any_mouse_button_just_pressed() const noexcept {
|
void input::extract_input_text(str32& dst) const {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
return std::any_of(
|
dst = state_->input_text;
|
||||||
state_->mouse_button_states.cbegin(),
|
|
||||||
state_->mouse_button_states.cend(),
|
|
||||||
[](state::button_state s) noexcept {
|
|
||||||
return s == state::button_state::just_pressed;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool input::is_any_mouse_button_just_released() const noexcept {
|
const mouse& input::mouse() const noexcept {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
return state_->mouse;
|
||||||
return std::any_of(
|
|
||||||
state_->mouse_button_states.cbegin(),
|
|
||||||
state_->mouse_button_states.cend(),
|
|
||||||
[](state::button_state s) noexcept {
|
|
||||||
return s == state::button_state::just_released;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool input::is_any_keyboard_key_pressed() const noexcept {
|
const keyboard& input::keyboard() const noexcept {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
return state_->keyboard;
|
||||||
return std::any_of(
|
|
||||||
state_->key_button_states.cbegin(),
|
|
||||||
state_->key_button_states.cend(),
|
|
||||||
[](state::button_state s) noexcept {
|
|
||||||
return s == state::button_state::just_pressed
|
|
||||||
|| s == state::button_state::pressed;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool input::is_any_keyboard_key_just_pressed() const noexcept {
|
void input::post_event(input_char_event evt) noexcept {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
return std::any_of(
|
state_->input_text += evt.uchar;
|
||||||
state_->key_button_states.cbegin(),
|
|
||||||
state_->key_button_states.cend(),
|
|
||||||
[](state::button_state s) noexcept {
|
|
||||||
return s == state::button_state::just_pressed;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool input::is_any_keyboard_key_just_released() const noexcept {
|
void input::post_event(mouse_button_event evt) noexcept {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
state_->mouse.state_->post_event(evt);
|
||||||
return std::any_of(
|
|
||||||
state_->key_button_states.cbegin(),
|
|
||||||
state_->key_button_states.cend(),
|
|
||||||
[](state::button_state s) noexcept {
|
|
||||||
return s == state::button_state::just_released;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool input::is_mouse_button_pressed(mouse_button btn) const noexcept {
|
void input::post_event(keyboard_key_event evt) noexcept {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
state_->keyboard.state_->post_event(evt);
|
||||||
const std::size_t index = state_->mouse_button_index(btn);
|
|
||||||
const enum state::button_state ms = state_->mouse_button_states[index];
|
|
||||||
return ms == state::button_state::just_pressed
|
|
||||||
|| ms == state::button_state::pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool input::is_mouse_button_just_pressed(mouse_button btn) const noexcept {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
const std::size_t index = state_->mouse_button_index(btn);
|
|
||||||
const enum state::button_state ms = state_->mouse_button_states[index];
|
|
||||||
return ms == state::button_state::just_pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool input::is_mouse_button_just_released(mouse_button btn) const noexcept {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
const std::size_t index = state_->mouse_button_index(btn);
|
|
||||||
const enum state::button_state ms = state_->mouse_button_states[index];
|
|
||||||
return ms == state::button_state::just_released;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool input::is_keyboard_key_pressed(keyboard_key key) const noexcept {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
const std::size_t index = state_->keyboard_key_index(key);
|
|
||||||
const enum state::button_state ks = state_->key_button_states[index];
|
|
||||||
return ks == state::button_state::just_pressed
|
|
||||||
|| ks == state::button_state::pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool input::is_keyboard_key_just_pressed(keyboard_key key) const noexcept {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
const std::size_t index = state_->keyboard_key_index(key);
|
|
||||||
const enum state::button_state ks = state_->key_button_states[index];
|
|
||||||
return ks == state::button_state::just_pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool input::is_keyboard_key_just_released(keyboard_key key) const noexcept {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
const std::size_t index = state_->keyboard_key_index(key);
|
|
||||||
const enum state::button_state ks = state_->key_button_states[index];
|
|
||||||
return ks == state::button_state::just_released;
|
|
||||||
}
|
|
||||||
|
|
||||||
void input::extract_pressed_mouse_buttons(std::vector<mouse_button>& dst) const {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
for ( std::size_t i = 0; i < state_->mouse_button_states.size(); ++i ) {
|
|
||||||
state::button_state ks = state_->mouse_button_states[i];
|
|
||||||
if ( ks == state::button_state::just_pressed || ks == state::button_state::pressed ) {
|
|
||||||
dst.push_back(static_cast<mouse_button>(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void input::extract_just_pressed_mouse_buttons(std::vector<mouse_button>& dst) const {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
for ( std::size_t i = 0; i < state_->mouse_button_states.size(); ++i ) {
|
|
||||||
state::button_state ks = state_->mouse_button_states[i];
|
|
||||||
if ( ks == state::button_state::just_pressed ) {
|
|
||||||
dst.push_back(static_cast<mouse_button>(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void input::extract_just_released_mouse_buttons(std::vector<mouse_button>& dst) const {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
for ( std::size_t i = 0; i < state_->mouse_button_states.size(); ++i ) {
|
|
||||||
state::button_state ks = state_->mouse_button_states[i];
|
|
||||||
if ( ks == state::button_state::just_released ) {
|
|
||||||
dst.push_back(static_cast<mouse_button>(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void input::extract_pressed_keyboard_keys(std::vector<keyboard_key>& dst) const {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
for ( std::size_t i = 0; i < state_->key_button_states.size(); ++i ) {
|
|
||||||
state::button_state ks = state_->key_button_states[i];
|
|
||||||
if ( ks == state::button_state::just_pressed || ks == state::button_state::pressed ) {
|
|
||||||
dst.push_back(static_cast<keyboard_key>(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void input::extract_just_pressed_keyboard_keys(std::vector<keyboard_key>& dst) const {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
for ( std::size_t i = 0; i < state_->key_button_states.size(); ++i ) {
|
|
||||||
state::button_state ks = state_->key_button_states[i];
|
|
||||||
if ( ks == state::button_state::just_pressed ) {
|
|
||||||
dst.push_back(static_cast<keyboard_key>(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void input::extract_just_released_keyboard_keys(std::vector<keyboard_key>& dst) const {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
for ( std::size_t i = 0; i < state_->key_button_states.size(); ++i ) {
|
|
||||||
state::button_state ks = state_->key_button_states[i];
|
|
||||||
if ( ks == state::button_state::just_released ) {
|
|
||||||
dst.push_back(static_cast<keyboard_key>(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void input::frame_tick() noexcept {
|
void input::frame_tick() noexcept {
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
{
|
||||||
std::for_each(
|
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||||
state_->key_button_states.begin(),
|
state_->input_text.clear();
|
||||||
state_->key_button_states.end(),
|
|
||||||
&state::update_button_state);
|
|
||||||
std::for_each(
|
|
||||||
state_->mouse_button_states.begin(),
|
|
||||||
state_->mouse_button_states.end(),
|
|
||||||
&state::update_button_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void input::post_event(keyboard_key key, keyboard_key_action action) noexcept {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
const std::size_t index = state_->keyboard_key_index(key);
|
|
||||||
const enum state::button_state ks = state_->key_button_states[index];
|
|
||||||
switch ( action ) {
|
|
||||||
case keyboard_key_action::press:
|
|
||||||
case keyboard_key_action::repeat:
|
|
||||||
if ( ks == state::button_state::released || ks == state::button_state::just_released ) {
|
|
||||||
state_->key_button_states[index] = state::button_state::just_pressed;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case keyboard_key_action::release:
|
|
||||||
if ( ks == state::button_state::pressed || ks == state::button_state::just_pressed ) {
|
|
||||||
state_->key_button_states[index] = state::button_state::just_released;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case keyboard_key_action::unknown:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
E2D_ASSERT_MSG(false, "unexpected key action");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void input::post_event(mouse_button mouse, mouse_button_action action) noexcept {
|
|
||||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
|
||||||
const std::size_t index = state_->mouse_button_index(mouse);
|
|
||||||
const enum state::button_state ms = state_->mouse_button_states[index];
|
|
||||||
switch ( action ) {
|
|
||||||
case mouse_button_action::press:
|
|
||||||
if ( ms == state::button_state::released || ms == state::button_state::just_released ) {
|
|
||||||
state_->mouse_button_states[index] = state::button_state::just_pressed;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mouse_button_action::release:
|
|
||||||
if ( ms == state::button_state::just_pressed || ms == state::button_state::pressed ) {
|
|
||||||
state_->mouse_button_states[index] = state::button_state::just_released;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mouse_button_action::unknown:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
E2D_ASSERT_MSG(false, "unexpected mouse action");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
state_->mouse.state_->frame_tick();
|
||||||
|
state_->keyboard.state_->frame_tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -305,12 +392,16 @@ namespace e2d
|
|||||||
window_input_source::window_input_source(input& input) noexcept
|
window_input_source::window_input_source(input& input) noexcept
|
||||||
: input_(input) {}
|
: input_(input) {}
|
||||||
|
|
||||||
|
void window_input_source::on_input_char(char32_t uchar) noexcept {
|
||||||
|
input_.post_event({uchar});
|
||||||
|
}
|
||||||
|
|
||||||
void window_input_source::on_keyboard_key(keyboard_key key, u32 scancode, keyboard_key_action act) noexcept {
|
void window_input_source::on_keyboard_key(keyboard_key key, u32 scancode, keyboard_key_action act) noexcept {
|
||||||
E2D_UNUSED(scancode);
|
E2D_UNUSED(scancode);
|
||||||
input_.post_event(key, act);
|
input_.post_event({key, act});
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_input_source::on_mouse_button(mouse_button btn, mouse_button_action act) noexcept {
|
void window_input_source::on_mouse_button(mouse_button btn, mouse_button_action act) noexcept {
|
||||||
input_.post_event(btn, act);
|
input_.post_event({btn, act});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user