InputCommon: Make the "input gate" not racey.

This commit is contained in:
Jordan Woyak 2019-11-06 15:59:36 -06:00
parent 93d7b3d159
commit 85ceb37ccd
17 changed files with 32 additions and 63 deletions

View File

@ -124,11 +124,6 @@ void Host_RequestRenderWindowSize(int width, int height)
jnicall.join(); jnicall.join();
} }
bool Host_UINeedsControllerState()
{
return true;
}
bool Host_RendererHasFocus() bool Host_RendererHasFocus()
{ {
return true; return true;

View File

@ -72,6 +72,7 @@
#include "Core/MemoryWatcher.h" #include "Core/MemoryWatcher.h"
#endif #endif
#include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "InputCommon/GCAdapter.h" #include "InputCommon/GCAdapter.h"
@ -1035,4 +1036,11 @@ void DoFrameStep()
} }
} }
void UpdateInputGate()
{
ControlReference::SetInputGate(
(SConfig::GetInstance().m_BackgroundInput || Host_RendererHasFocus()) &&
!Host_UIBlocksControllerState());
}
} // namespace Core } // namespace Core

View File

@ -110,4 +110,6 @@ void HostDispatchJobs();
void DoFrameStep(); void DoFrameStep();
void UpdateInputGate();
} // namespace Core } // namespace Core

View File

@ -737,6 +737,7 @@ void Update(u64 ticks)
if (s_half_line_of_next_si_poll == s_half_line_count) if (s_half_line_of_next_si_poll == s_half_line_count)
{ {
Core::UpdateInputGate();
SerialInterface::UpdateDevices(); SerialInterface::UpdateDevices();
s_half_line_of_next_si_poll += 2 * SerialInterface::GetPollXLines(); s_half_line_of_next_si_poll += 2 * SerialInterface::GetPollXLines();
} }

View File

@ -32,7 +32,6 @@ enum class HostMessageID
WMUserJobDispatch, WMUserJobDispatch,
}; };
bool Host_UINeedsControllerState();
bool Host_UIBlocksControllerState(); bool Host_UIBlocksControllerState();
bool Host_RendererHasFocus(); bool Host_RendererHasFocus();
bool Host_RendererIsFullscreen(); bool Host_RendererIsFullscreen();

View File

@ -212,7 +212,7 @@ IPCCommandResult USB_KBD::Write(const ReadWriteRequest& request)
IPCCommandResult USB_KBD::IOCtl(const IOCtlRequest& request) IPCCommandResult USB_KBD::IOCtl(const IOCtlRequest& request)
{ {
if (SConfig::GetInstance().m_WiiKeyboard && !Core::WantsDeterminism() && if (SConfig::GetInstance().m_WiiKeyboard && !Core::WantsDeterminism() &&
ControlReference::InputGateOn() && !m_message_queue.empty()) ControlReference::GetInputGate() && !m_message_queue.empty())
{ {
Memory::CopyToEmu(request.buffer_out, &m_message_queue.front(), sizeof(MessageData)); Memory::CopyToEmu(request.buffer_out, &m_message_queue.front(), sizeof(MessageData));
m_message_queue.pop(); m_message_queue.pop();

View File

@ -82,11 +82,6 @@ void Host_RequestRenderWindowSize(int width, int height)
{ {
} }
bool Host_UINeedsControllerState()
{
return false;
}
bool Host_RendererHasFocus() bool Host_RendererHasFocus()
{ {
return s_platform->IsWindowFocused(); return s_platform->IsWindowFocused();

View File

@ -25,7 +25,6 @@
#include "DolphinQt/Config/Mapping/MappingWidget.h" #include "DolphinQt/Config/Mapping/MappingWidget.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/Settings.h"
namespace namespace
{ {
@ -567,9 +566,6 @@ void MappingIndicator::DrawForce(ControllerEmu::Force& force)
void MappingIndicator::paintEvent(QPaintEvent*) void MappingIndicator::paintEvent(QPaintEvent*)
{ {
// TODO: The SetControllerStateNeeded interface leaks input into the game.
Settings::Instance().SetControllerStateNeeded(true);
switch (m_group->type) switch (m_group->type)
{ {
case ControllerEmu::GroupType::Cursor: case ControllerEmu::GroupType::Cursor:
@ -588,8 +584,6 @@ void MappingIndicator::paintEvent(QPaintEvent*)
default: default:
break; break;
} }
Settings::Instance().SetControllerStateNeeded(false);
} }
ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group) ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group)
@ -599,9 +593,7 @@ ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group)
void ShakeMappingIndicator::paintEvent(QPaintEvent*) void ShakeMappingIndicator::paintEvent(QPaintEvent*)
{ {
Settings::Instance().SetControllerStateNeeded(true);
DrawShake(); DrawShake();
Settings::Instance().SetControllerStateNeeded(false);
} }
void ShakeMappingIndicator::DrawShake() void ShakeMappingIndicator::DrawShake()

View File

@ -14,7 +14,6 @@
#include "DolphinQt/Config/Mapping/MappingIndicator.h" #include "DolphinQt/Config/Mapping/MappingIndicator.h"
#include "DolphinQt/Config/Mapping/MappingNumeric.h" #include "DolphinQt/Config/Mapping/MappingNumeric.h"
#include "DolphinQt/Config/Mapping/MappingWindow.h" #include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/Settings.h"
#include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerEmu/Control/Control.h" #include "InputCommon/ControllerEmu/Control/Control.h"
@ -31,11 +30,8 @@ MappingWidget::MappingWidget(MappingWindow* parent) : m_parent(parent)
const auto timer = new QTimer(this); const auto timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [this] { connect(timer, &QTimer::timeout, this, [this] {
// TODO: The SetControllerStateNeeded interface leaks input into the game.
const auto lock = m_parent->GetController()->GetStateLock(); const auto lock = m_parent->GetController()->GetStateLock();
Settings::Instance().SetControllerStateNeeded(true);
emit Update(); emit Update();
Settings::Instance().SetControllerStateNeeded(false);
}); });
timer->start(1000 / INDICATOR_UPDATE_FREQ); timer->start(1000 / INDICATOR_UPDATE_FREQ);

View File

@ -153,12 +153,6 @@ void Host_RequestRenderWindowSize(int w, int h)
emit Host::GetInstance()->RequestRenderSize(w, h); emit Host::GetInstance()->RequestRenderSize(w, h);
} }
bool Host_UINeedsControllerState()
{
return Settings::Instance().IsControllerStateNeeded() ||
(ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard);
}
bool Host_UIBlocksControllerState() bool Host_UIBlocksControllerState()
{ {
return ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard; return ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard;

View File

@ -25,6 +25,7 @@
#include "DolphinQt/Settings.h" #include "DolphinQt/Settings.h"
#include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/OnScreenDisplay.h"
@ -142,8 +143,14 @@ void HotkeyScheduler::Run()
if (Core::GetState() != Core::State::Stopping) if (Core::GetState() != Core::State::Stopping)
{ {
// Obey window focus before checking hotkeys.
Core::UpdateInputGate();
HotkeyManagerEmu::GetStatus(); HotkeyManagerEmu::GetStatus();
// Everything else on the host thread (controller config dialog) should always get input.
ControlReference::SetInputGate(true);
if (!Core::IsRunningAndStarted()) if (!Core::IsRunningAndStarted())
continue; continue;

View File

@ -388,16 +388,6 @@ bool Settings::IsBreakpointsVisible() const
return GetQSettings().value(QStringLiteral("debugger/showbreakpoints")).toBool(); return GetQSettings().value(QStringLiteral("debugger/showbreakpoints")).toBool();
} }
bool Settings::IsControllerStateNeeded() const
{
return m_controller_state_needed;
}
void Settings::SetControllerStateNeeded(bool needed)
{
m_controller_state_needed = needed;
}
void Settings::SetCodeVisible(bool enabled) void Settings::SetCodeVisible(bool enabled)
{ {
if (IsCodeVisible() != enabled) if (IsCodeVisible() != enabled)

View File

@ -57,8 +57,6 @@ public:
void SetLogVisible(bool visible); void SetLogVisible(bool visible);
bool IsLogConfigVisible() const; bool IsLogConfigVisible() const;
void SetLogConfigVisible(bool visible); void SetLogConfigVisible(bool visible);
bool IsControllerStateNeeded() const;
void SetControllerStateNeeded(bool needed);
void SetToolBarVisible(bool visible); void SetToolBarVisible(bool visible);
bool IsToolBarVisible() const; bool IsToolBarVisible() const;
void SetWidgetsLocked(bool visible); void SetWidgetsLocked(bool visible);
@ -179,7 +177,6 @@ signals:
private: private:
bool m_batch = false; bool m_batch = false;
bool m_controller_state_needed = false;
std::shared_ptr<NetPlay::NetPlayClient> m_client; std::shared_ptr<NetPlay::NetPlayClient> m_client;
std::shared_ptr<NetPlay::NetPlayServer> m_server; std::shared_ptr<NetPlay::NetPlayServer> m_server;
Settings(); Settings();

View File

@ -4,19 +4,18 @@
#include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControlReference/ControlReference.h"
// For InputGateOn()
// This is a bad layering violation, but it's the cleanest
// place I could find to put it.
#include "Core/ConfigManager.h"
#include "Core/Host.h"
using namespace ciface::ExpressionParser; using namespace ciface::ExpressionParser;
bool ControlReference::InputGateOn() static thread_local bool tls_input_gate = true;
void ControlReference::SetInputGate(bool enable)
{ {
return (SConfig::GetInstance().m_BackgroundInput || Host_RendererHasFocus() || tls_input_gate = enable;
Host_UINeedsControllerState()) && }
!Host_UIBlocksControllerState();
bool ControlReference::GetInputGate()
{
return tls_input_gate;
} }
// //
@ -90,7 +89,7 @@ bool OutputReference::IsInput() const
// //
ControlState InputReference::State(const ControlState ignore) ControlState InputReference::State(const ControlState ignore)
{ {
if (m_parsed_expression && InputGateOn()) if (m_parsed_expression && GetInputGate())
return m_parsed_expression->GetValue() * range; return m_parsed_expression->GetValue() * range;
return 0.0; return 0.0;
} }

View File

@ -22,7 +22,9 @@
class ControlReference class ControlReference
{ {
public: public:
static bool InputGateOn(); // Note: this is per thread.
static void SetInputGate(bool enable);
static bool GetInputGate();
virtual ~ControlReference(); virtual ~ControlReference();
virtual ControlState State(const ControlState state = 0) = 0; virtual ControlState State(const ControlState state = 0) = 0;

View File

@ -34,10 +34,6 @@ void Host_UpdateMainFrame()
void Host_RequestRenderWindowSize(int, int) void Host_RequestRenderWindowSize(int, int)
{ {
} }
bool Host_UINeedsControllerState()
{
return false;
}
bool Host_RendererHasFocus() bool Host_RendererHasFocus()
{ {
return false; return false;

View File

@ -31,10 +31,6 @@ void Host_UpdateMainFrame()
void Host_RequestRenderWindowSize(int, int) void Host_RequestRenderWindowSize(int, int)
{ {
} }
bool Host_UINeedsControllerState()
{
return false;
}
bool Host_UIBlocksControllerState() bool Host_UIBlocksControllerState()
{ {
return false; return false;