mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
DolphinQt: Rework TAS input threading, part 1 (buttons)
This gets rid of a blocking operation, improving performance and fixing https://bugs.dolphin-emu.org/issues/12893. This also makes us no longer directly access the state of certain UI elements from the CPU thread, which probably wasn't thread-safe but doesn't seem to have caused any observable issues so far.
This commit is contained in:
43
Source/Core/DolphinQt/TAS/TASControlState.h
Normal file
43
Source/Core/DolphinQt/TAS/TASControlState.h
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
class TASControlState
|
||||
{
|
||||
public:
|
||||
// Call this from the CPU thread to get the current value. (This function can also safely be
|
||||
// called from the UI thread, but you're effectively just getting the value the UI control has.)
|
||||
u16 GetValue() const;
|
||||
// Call this from the CPU thread when the controller state changes.
|
||||
// If the return value is true, queue up a call to ApplyControllerChangeValue on the UI thread.
|
||||
bool OnControllerValueChanged(u16 new_value);
|
||||
// Call this from the UI thread when the user changes the value using the UI.
|
||||
void OnUIValueChanged(u16 new_value);
|
||||
// Call this from the UI thread after OnControllerValueChanged returns true,
|
||||
// and set the state of the UI control to the return value.
|
||||
u16 ApplyControllerValueChange();
|
||||
|
||||
private:
|
||||
// A description of how threading is handled: The UI thread can update its copy of the state
|
||||
// whenever it wants to, and must *not* increment the version when doing so. The CPU thread can
|
||||
// update its copy of the state whenever it wants to, and *must* increment the version when doing
|
||||
// so. When the CPU thread updates its copy of the state, the UI thread should then (possibly
|
||||
// after a delay) mirror the change by copying the CPU thread's state to the UI thread's state.
|
||||
// This mirroring is the only way for the version number stored in the UI thread's state to
|
||||
// change. The version numbers of the two copies can be compared to check if the UI thread's view
|
||||
// of what has happened on the CPU thread is up to date.
|
||||
|
||||
struct State
|
||||
{
|
||||
u16 version = 0;
|
||||
u16 value = 0;
|
||||
};
|
||||
|
||||
std::atomic<State> m_ui_thread_state;
|
||||
std::atomic<State> m_cpu_thread_state;
|
||||
};
|
Reference in New Issue
Block a user