From cca613e785864a35cf7000f0d133cf3441b5c956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 1 May 2023 14:23:47 +0200 Subject: [PATCH] Initial work on queueing up UI events for processing. Key events excepted for now. --- Common/UI/UIScreen.cpp | 96 ++++++++++++++++++++++++++++++------------ Common/UI/UIScreen.h | 22 +++++++++- 2 files changed, 89 insertions(+), 29 deletions(-) diff --git a/Common/UI/UIScreen.cpp b/Common/UI/UIScreen.cpp index 6b7a7b3c86..c7a5f616fe 100644 --- a/Common/UI/UIScreen.cpp +++ b/Common/UI/UIScreen.cpp @@ -60,6 +60,41 @@ void UIScreen::DoRecreateViews() { } } +void UIScreen::touch(const TouchInput &touch) { + if (root_) { + if (ClickDebug && (touch.flags & TOUCH_DOWN)) { + INFO_LOG(SYSTEM, "Touch down!"); + std::vector views; + root_->Query(touch.x, touch.y, views); + for (auto view : views) { + INFO_LOG(SYSTEM, "%s", view->DescribeLog().c_str()); + } + } + } + + std::lock_guard guard(eventQueueLock_); + QueuedEvent ev{}; + ev.type = QueuedEventType::TOUCH; + ev.touch = touch; + eventQueue_.push_back(ev); +} + +void UIScreen::axis(const AxisInput &axis) { + std::lock_guard guard(eventQueueLock_); + QueuedEvent ev{}; + ev.type = QueuedEventType::AXIS; + ev.axis = axis; + eventQueue_.push_back(ev); +} + +bool UIScreen::key(const KeyInput &key) { + if (root_ && !ignoreInput_) { + // TODO: Make key events async too. The return value is troublesome, though. + return UI::KeyEvent(key, root_); + } + return false; +} + void UIScreen::update() { bool vertical = UseVerticalLayout(); if (vertical != lastVertical_) { @@ -71,6 +106,39 @@ void UIScreen::update() { if (root_) { UpdateViewHierarchy(root_); + while (true) { + QueuedEvent ev{}; + { + std::lock_guard guard(eventQueueLock_); + if (!eventQueue_.empty()) { + ev = eventQueue_.front(); + eventQueue_.pop_front(); + } else { + break; + } + } + if (ignoreInput_) { + continue; + } + switch (ev.type) { + case QueuedEventType::KEY: + break; + case QueuedEventType::TOUCH: + if (ClickDebug && (ev.touch.flags & TOUCH_DOWN)) { + INFO_LOG(SYSTEM, "Touch down!"); + std::vector views; + root_->Query(ev.touch.x, ev.touch.y, views); + for (auto view : views) { + INFO_LOG(SYSTEM, "%s", view->DescribeLog().c_str()); + } + } + UI::TouchEvent(ev.touch, root_); + break; + case QueuedEventType::AXIS: + UI::AxisEvent(ev.axis, root_); + break; + } + } } } @@ -148,34 +216,6 @@ TouchInput UIScreen::transformTouch(const TouchInput &touch) { return updated; } -void UIScreen::touch(const TouchInput &touch) { - if (root_ && !ignoreInput_) { - if (ClickDebug && (touch.flags & TOUCH_DOWN)) { - INFO_LOG(SYSTEM, "Touch down!"); - std::vector views; - root_->Query(touch.x, touch.y, views); - for (auto view : views) { - INFO_LOG(SYSTEM, "%s", view->DescribeLog().c_str()); - } - } - - UI::TouchEvent(touch, root_); - } -} - -bool UIScreen::key(const KeyInput &key) { - if (root_ && !ignoreInput_) { - return UI::KeyEvent(key, root_); - } - return false; -} - -void UIScreen::axis(const AxisInput &axis) { - if (root_ && !ignoreInput_) { - UI::AxisEvent(axis, root_); - } -} - void UIScreen::TriggerFinish(DialogResult result) { // From here on, this dialog cannot receive input. ignoreInput_ = true; diff --git a/Common/UI/UIScreen.h b/Common/UI/UIScreen.h index 1d5443a5fa..33c69034f9 100644 --- a/Common/UI/UIScreen.h +++ b/Common/UI/UIScreen.h @@ -1,6 +1,8 @@ #pragma once -#include +#include +#include +#include #include "Common/Math/lin/vec3.h" #include "Common/UI/Screen.h" @@ -13,6 +15,21 @@ namespace Draw { class DrawContext; } +enum class QueuedEventType : u8 { + KEY, + AXIS, + TOUCH, +}; + +struct QueuedEvent { + QueuedEventType type; + union { + TouchInput touch; + KeyInput key; + AxisInput axis; + }; +}; + class UIScreen : public Screen { public: UIScreen(); @@ -57,6 +74,9 @@ private: bool recreateViews_ = true; bool lastVertical_; + + std::mutex eventQueueLock_; + std::deque eventQueue_; }; class UIDialogScreen : public UIScreen {