UI: Remove locks in event dispatching

This commit is contained in:
Henrik Rydgård 2023-08-06 11:15:13 +02:00
parent e0c0cb9a6d
commit 0c7b42b079

View file

@ -1,5 +1,3 @@
#include <atomic>
#include <mutex>
#include <deque>
#include "ppsspp_config.h"
@ -12,14 +10,12 @@
namespace UI {
static std::mutex focusLock;
static std::vector<int> focusMoves;
extern bool focusForced;
static View *focusedView;
static bool focusMovementEnabled;
bool focusForced;
static std::mutex eventMutex_;
static std::function<void(UISound, float)> soundCallback;
static bool soundEnabled = true;
@ -29,29 +25,20 @@ struct DispatchQueueItem {
EventParams params;
};
std::atomic<bool> hasDispatchQueue;
std::deque<DispatchQueueItem> g_dispatchQueue;
void EventTriggered(Event *e, EventParams params) {
DispatchQueueItem item{ e, params };
std::unique_lock<std::mutex> guard(eventMutex_);
// Set before adding so we lock and check the added value.
hasDispatchQueue = true;
g_dispatchQueue.push_front(item);
}
void DispatchEvents() {
while (hasDispatchQueue) {
while (!g_dispatchQueue.empty()) {
DispatchQueueItem item;
{
std::unique_lock<std::mutex> guard(eventMutex_);
if (g_dispatchQueue.empty())
break;
item = g_dispatchQueue.back();
g_dispatchQueue.pop_back();
hasDispatchQueue = !g_dispatchQueue.empty();
}
if (g_dispatchQueue.empty())
break;
item = g_dispatchQueue.back();
g_dispatchQueue.pop_back();
if (item.e) {
item.e->Dispatch(item.params);
}
@ -59,9 +46,6 @@ void DispatchEvents() {
}
void RemoveQueuedEventsByView(View *view) {
if (!hasDispatchQueue)
return;
std::unique_lock<std::mutex> guard(eventMutex_);
for (auto it = g_dispatchQueue.begin(); it != g_dispatchQueue.end(); ) {
if (it->params.v == view) {
it = g_dispatchQueue.erase(it);
@ -72,9 +56,6 @@ void RemoveQueuedEventsByView(View *view) {
}
void RemoveQueuedEventsByEvent(Event *event) {
if (!hasDispatchQueue)
return;
std::unique_lock<std::mutex> guard(eventMutex_);
for (auto it = g_dispatchQueue.begin(); it != g_dispatchQueue.end(); ) {
if (it->e == event) {
it = g_dispatchQueue.erase(it);
@ -214,7 +195,6 @@ static KeyEventResult KeyEventToFocusMoves(const KeyInput &key) {
hk.deviceId = key.deviceId;
hk.triggerTime = time_now_d() + repeatDelay;
std::lock_guard<std::mutex> lock(focusLock);
// Check if the key is already held. If it is, ignore it. This is to avoid
// multiple key repeat mechanisms colliding.
if (heldKeys.find(hk) != heldKeys.end()) {
@ -381,7 +361,6 @@ restart:
key.flags = KEY_DOWN;
KeyEvent(key, root);
std::lock_guard<std::mutex> lock(focusLock);
focusMoves.push_back(key.keyCode);
// Cannot modify the current item when looping over a set, so let's do this instead.
@ -404,7 +383,6 @@ void UpdateViewHierarchy(ViewGroup *root) {
}
if (focusMoves.size()) {
std::lock_guard<std::mutex> lock(focusLock);
EnableFocusMovement(true);
if (!GetFocusedView()) {
// Find a view to focus.