Bypass normal UI messages to avoid slowing down unsynchrononized touch messages.

This commit is contained in:
Henrik Rydgård 2023-09-04 11:04:15 +02:00
parent 109205a56a
commit 78c064cc96
2 changed files with 45 additions and 21 deletions

View file

@ -367,7 +367,7 @@ void OnScreenMessagesView::Draw(UIContext &dc) {
edges[(size_t)pos].maxWidth = std::max(edges[(size_t)pos].maxWidth, measuredEntry.w);
}
std::vector<DismissZone> dismissZones;
std::vector<ClickZone> dismissZones;
// Now, perform layout for all 8 edges.
for (size_t i = 0; i < (size_t)ScreenEdgePosition::VALUE_COUNT; i++) {
@ -446,19 +446,30 @@ void OnScreenMessagesView::Draw(UIContext &dc) {
float alpha = Clamp((float)(entry.endTime - now) * 4.0f, 0.0f, 1.0f);
RenderOSDEntry(dc, entry, b, measuredEntry.h1, measuredEntry.align, alpha);
switch (entry.type) {
case OSDType::MESSAGE_INFO:
case OSDType::MESSAGE_SUCCESS:
case OSDType::MESSAGE_WARNING:
case OSDType::MESSAGE_ERROR:
case OSDType::MESSAGE_ERROR_DUMP:
case OSDType::MESSAGE_FILE_LINK:
case OSDType::ACHIEVEMENT_UNLOCKED:
// Save the location of the popup, for easy dismissal.
dismissZones.push_back(ClickZone{ (int)j, b });
break;
}
break;
}
}
// Save the location of the popup, for easy dismissal.
dismissZones.push_back(DismissZone{ (int)j, b });
y += (measuredEntry.h + 4.0f) * measuredEntry.alpha;
}
}
std::lock_guard<std::mutex> lock(dismissMutex_);
dismissZones_ = dismissZones;
std::lock_guard<std::mutex> lock(clickMutex_);
clickZones_ = dismissZones;
}
std::string OnScreenMessagesView::DescribeText() const {
@ -473,18 +484,25 @@ std::string OnScreenMessagesView::DescribeText() const {
return ss.str();
}
bool OnScreenMessagesView::Touch(const TouchInput &input) {
if (input.flags & TOUCH_DOWN) {
bool dismissed = false;
std::lock_guard<std::mutex> lock(dismissMutex_);
double now = time_now_d();
for (auto &zone : dismissZones_) {
if (zone.bounds.Contains(input.x, input.y)) {
g_OSD.DismissEntry(zone.index, now);
dismissed = true;
}
// Asynchronous!
bool OnScreenMessagesView::Dismiss(float x, float y) {
bool dismissed = false;
std::lock_guard<std::mutex> lock(clickMutex_);
double now = time_now_d();
for (auto &zone : clickZones_) {
if (zone.bounds.Contains(x, y)) {
g_OSD.DismissEntry(zone.index, now);
dismissed = true;
}
return dismissed;
}
return dismissed;
}
bool OSDOverlayScreen::UnsyncTouch(const TouchInput &touch) {
// Don't really need to forward.
// UIScreen::UnsyncTouch(touch);
if ((touch.flags & TOUCH_DOWN) && osmView_) {
return osmView_->Dismiss(touch.x, touch.y);
} else {
return false;
}
@ -493,7 +511,7 @@ bool OnScreenMessagesView::Touch(const TouchInput &input) {
void OSDOverlayScreen::CreateViews() {
root_ = new UI::AnchorLayout();
root_->SetTag("OSDOverlayScreen");
root_->Add(new OnScreenMessagesView(new UI::AnchorLayoutParams(0.0f, 0.0f, 0.0f, 0.0f)));
osmView_ = root_->Add(new OnScreenMessagesView(new UI::AnchorLayoutParams(0.0f, 0.0f, 0.0f, 0.0f)));
}
void OSDOverlayScreen::render() {

View file

@ -21,24 +21,30 @@ class OnScreenMessagesView : public UI::InertView {
public:
OnScreenMessagesView(UI::LayoutParams *layoutParams = nullptr) : UI::InertView(layoutParams) {}
void Draw(UIContext &dc) override;
bool Touch(const TouchInput &input) override;
bool Dismiss(float x, float y); // Not reusing Touch since it's asynchronous.
std::string DescribeText() const override;
private:
struct DismissZone {
struct ClickZone {
int index;
Bounds bounds;
};
// Argh, would really like to avoid this.
std::mutex dismissMutex_;
std::vector<DismissZone> dismissZones_;
std::mutex clickMutex_;
std::vector<ClickZone> clickZones_;
};
class OSDOverlayScreen : public UIScreen {
public:
const char *tag() const override { return "OSDOverlayScreen"; }
bool UnsyncTouch(const TouchInput &touch) override;
void CreateViews() override;
void render() override;
private:
OnScreenMessagesView *osmView_ = nullptr;
};
enum class NoticeLevel {