Skip to content

Commit

Permalink
UI: Remove locks in event dispatching
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Nov 11, 2023
1 parent e0c0cb9 commit 0c7b42b
Showing 1 changed file with 5 additions and 27 deletions.
32 changes: 5 additions & 27 deletions Common/UI/Root.cpp
@@ -1,5 +1,3 @@
#include <atomic>
#include <mutex>
#include <deque>

#include "ppsspp_config.h"
Expand All @@ -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;
Expand All @@ -29,39 +25,27 @@ 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);
}
}
}

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);
Expand All @@ -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);
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -381,7 +361,6 @@ static void ProcessHeldKeys(ViewGroup *root) {
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.
Expand All @@ -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.
Expand Down

0 comments on commit 0c7b42b

Please sign in to comment.