MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
WindowEventSource.cpp
Go to the documentation of this file.
2
4
5namespace MayaFlux::Vruta {
6
8{
9 if (auto* kd = std::get_if<Core::WindowEvent::KeyData>(&event.data)) {
11 m_key_states[kd->key] = true;
12 } else if (event.type == Core::WindowEventType::KEY_RELEASED) {
13 m_key_states[kd->key] = false;
14 }
15 }
16
17 if (auto* bd = std::get_if<Core::WindowEvent::MouseButtonData>(&event.data)) {
19 m_button_states[bd->button] = true;
21 m_button_states[bd->button] = false;
22 }
23 }
24
25 if (auto* pd = std::get_if<Core::WindowEvent::MousePosData>(&event.data)) {
26 m_mouse_x = pd->x;
27 m_mouse_y = pd->y;
28 }
29
30 const size_t resumed_before = m_resumed;
32 dispatch(&event);
34 if (m_resumed == resumed_before) {
35 m_pending_events.push_back(event);
36 auto& held = m_pending_counts[static_cast<uint8_t>(event.type)];
37 if (++held > k_max_pending_events) {
38 auto oldest = std::ranges::find(m_pending_events, event.type, &Core::WindowEvent::type);
39 m_pending_events.erase(oldest);
40 --held;
41 }
42 }
43
44 if (m_signal_depth != 0 || m_deferred_actions.empty())
45 return;
46
47 std::vector<std::function<void()>> deferred_actions;
48 deferred_actions.swap(m_deferred_actions);
49 for (auto& action : deferred_actions)
50 action();
51}
52
53void WindowEventSource::defer(std::function<void()> action)
54{
55 if (!action)
56 return;
57
58 if (m_signal_depth == 0) {
59 action();
60 return;
61 }
62
63 m_deferred_actions.push_back(std::move(action));
64}
65
70
75
76std::optional<Core::WindowEvent> WindowEventSource::pop_event(const WindowEventFilter& filter)
77{
78 if (m_pending_events.empty())
79 return std::nullopt;
80
81 if (!filter.event_type && !filter.key_code && !filter.button) {
82 auto ev = m_pending_events.front();
83 m_pending_events.pop_front();
84 --m_pending_counts[static_cast<uint8_t>(ev.type)];
85 return ev;
86 }
87
88 std::deque<Core::WindowEvent> tmp;
89 std::optional<Core::WindowEvent> result;
90
91 while (!m_pending_events.empty()) {
92 auto ev = m_pending_events.front();
93 m_pending_events.pop_front();
94
95 bool matches = true;
96
97 if (filter.event_type && ev.type != *filter.event_type)
98 matches = false;
99
100 if (matches && filter.key_code) {
101 if (auto* kd = std::get_if<Core::WindowEvent::KeyData>(&ev.data)) {
102 matches = kd->key == static_cast<int16_t>(*filter.key_code);
103 } else {
104 matches = false;
105 }
106 }
107
108 if (matches && filter.button) {
109 if (auto* bd = std::get_if<Core::WindowEvent::MouseButtonData>(&ev.data)) {
110 matches = bd->button == static_cast<int>(*filter.button);
111 } else {
112 matches = false;
113 }
114 }
115
116 if (matches && !result) {
117 result = ev;
118 } else {
119 tmp.push_back(ev);
120 }
121 }
122
123 m_pending_events = std::move(tmp);
124 if (result)
125 --m_pending_counts[static_cast<uint8_t>(result->type)];
126 return result;
127}
128
130{
131 auto it = m_key_states.find(static_cast<int16_t>(key));
132 return it != m_key_states.end() && it->second;
133}
134
136{
137 auto it = m_button_states.find(button);
138 return it != m_button_states.end() && it->second;
139}
140
141std::pair<double, double> WindowEventSource::get_mouse_position() const
142{
143 return { m_mouse_x, m_mouse_y };
144}
145
146} // namespace MayaFlux::Vruta
vk::PhysicalDeviceType type
Definition VKDevice.cpp:126
Awaiter for suspending on window input events with optional filtering.
void dispatch(const void *event)
Iterates the waiter list, passing the type-erased signal to each.
bool is_key_pressed(IO::Keys key) const
Returns true if the given key is currently held.
bool is_mouse_pressed(int button) const
Returns true if the given mouse button is currently held.
Kriya::WindowEventAwaiter await_event(Core::WindowEventType type)
Creates an awaiter that resumes on the next event matching a type.
void defer(std::function< void()> action)
Run an action after the active outermost window-event dispatch.
std::unordered_map< int16_t, bool > m_key_states
void signal(Core::WindowEvent event)
Enqueue a window event and resume matching waiters.
std::vector< std::function< void()> > m_deferred_actions
std::deque< Core::WindowEvent > m_pending_events
std::pair< double, double > get_mouse_position() const
Returns the last known cursor position in screen coordinates.
std::optional< Core::WindowEvent > pop_event(const WindowEventFilter &filter)
Removes and returns the first pending event matching the filter.
Kriya::WindowEventAwaiter next_event()
Creates an awaiter that resumes on the next event of any type.
std::unordered_map< int, bool > m_button_states
std::array< size_t, 256 > m_pending_counts
static constexpr size_t k_max_pending_events
Most events of one type held for a later awaiter before the oldest of that type is dropped.
WindowEventType
Types of window and input events.
Event data for window and input events.
std::optional< Core::WindowEventType > event_type
std::optional< IO::MouseButtons > button
Filter criteria for window input events.