summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2019-11-06 15:59:36 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2019-11-06 16:31:02 -0600
commit85ceb37ccd24acc5ea026583ce3a0f6a4fb26eaa (patch)
tree1a4d9a86fdcd36a3c1273502af576bcb30449db1 /Source
parent93d7b3d15962a3393cf2971e14c4acf54d90cecd (diff)
InputCommon: Make the "input gate" not racey.
Diffstat (limited to 'Source')
-rw-r--r--Source/Android/jni/MainAndroid.cpp5
-rw-r--r--Source/Core/Core/Core.cpp8
-rw-r--r--Source/Core/Core/Core.h2
-rw-r--r--Source/Core/Core/HW/VideoInterface.cpp1
-rw-r--r--Source/Core/Core/Host.h1
-rw-r--r--Source/Core/Core/IOS/USB/USB_KBD.cpp2
-rw-r--r--Source/Core/DolphinNoGUI/MainNoGUI.cpp5
-rw-r--r--Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp8
-rw-r--r--Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp4
-rw-r--r--Source/Core/DolphinQt/Host.cpp6
-rw-r--r--Source/Core/DolphinQt/HotkeyScheduler.cpp7
-rw-r--r--Source/Core/DolphinQt/Settings.cpp10
-rw-r--r--Source/Core/DolphinQt/Settings.h3
-rw-r--r--Source/Core/InputCommon/ControlReference/ControlReference.cpp21
-rw-r--r--Source/Core/InputCommon/ControlReference/ControlReference.h4
-rw-r--r--Source/DSPTool/StubHost.cpp4
-rw-r--r--Source/UnitTests/StubHost.cpp4
17 files changed, 32 insertions, 63 deletions
diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp
index e1b19314c3..ec7bbafd2f 100644
--- a/Source/Android/jni/MainAndroid.cpp
+++ b/Source/Android/jni/MainAndroid.cpp
@@ -124,11 +124,6 @@ void Host_RequestRenderWindowSize(int width, int height)
jnicall.join();
}
-bool Host_UINeedsControllerState()
-{
- return true;
-}
-
bool Host_RendererHasFocus()
{
return true;
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index 5908cc1347..a2f60badae 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -72,6 +72,7 @@
#include "Core/MemoryWatcher.h"
#endif
+#include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerInterface/ControllerInterface.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
diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h
index 530079b8ab..4145895faf 100644
--- a/Source/Core/Core/Core.h
+++ b/Source/Core/Core/Core.h
@@ -110,4 +110,6 @@ void HostDispatchJobs();
void DoFrameStep();
+void UpdateInputGate();
+
} // namespace Core
diff --git a/Source/Core/Core/HW/VideoInterface.cpp b/Source/Core/Core/HW/VideoInterface.cpp
index 9af6f9f46a..7d78e314b9 100644
--- a/Source/Core/Core/HW/VideoInterface.cpp
+++ b/Source/Core/Core/HW/VideoInterface.cpp
@@ -737,6 +737,7 @@ void Update(u64 ticks)
if (s_half_line_of_next_si_poll == s_half_line_count)
{
+ Core::UpdateInputGate();
SerialInterface::UpdateDevices();
s_half_line_of_next_si_poll += 2 * SerialInterface::GetPollXLines();
}
diff --git a/Source/Core/Core/Host.h b/Source/Core/Core/Host.h
index 99c0c61708..d3f5ee4b61 100644
--- a/Source/Core/Core/Host.h
+++ b/Source/Core/Core/Host.h
@@ -32,7 +32,6 @@ enum class HostMessageID
WMUserJobDispatch,
};
-bool Host_UINeedsControllerState();
bool Host_UIBlocksControllerState();
bool Host_RendererHasFocus();
bool Host_RendererIsFullscreen();
diff --git a/Source/Core/Core/IOS/USB/USB_KBD.cpp b/Source/Core/Core/IOS/USB/USB_KBD.cpp
index 77deb65948..5f690506cb 100644
--- a/Source/Core/Core/IOS/USB/USB_KBD.cpp
+++ b/Source/Core/Core/IOS/USB/USB_KBD.cpp
@@ -212,7 +212,7 @@ IPCCommandResult USB_KBD::Write(const ReadWriteRequest& request)
IPCCommandResult USB_KBD::IOCtl(const IOCtlRequest& request)
{
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));
m_message_queue.pop();
diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp
index 711583f736..178501194a 100644
--- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp
+++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp
@@ -82,11 +82,6 @@ void Host_RequestRenderWindowSize(int width, int height)
{
}
-bool Host_UINeedsControllerState()
-{
- return false;
-}
-
bool Host_RendererHasFocus()
{
return s_platform->IsWindowFocused();
diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
index a1d0eb144c..08a4f1ccb4 100644
--- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
+++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
@@ -25,7 +25,6 @@
#include "DolphinQt/Config/Mapping/MappingWidget.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
-#include "DolphinQt/Settings.h"
namespace
{
@@ -567,9 +566,6 @@ void MappingIndicator::DrawForce(ControllerEmu::Force& force)
void MappingIndicator::paintEvent(QPaintEvent*)
{
- // TODO: The SetControllerStateNeeded interface leaks input into the game.
- Settings::Instance().SetControllerStateNeeded(true);
-
switch (m_group->type)
{
case ControllerEmu::GroupType::Cursor:
@@ -588,8 +584,6 @@ void MappingIndicator::paintEvent(QPaintEvent*)
default:
break;
}
-
- Settings::Instance().SetControllerStateNeeded(false);
}
ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group)
@@ -599,9 +593,7 @@ ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group)
void ShakeMappingIndicator::paintEvent(QPaintEvent*)
{
- Settings::Instance().SetControllerStateNeeded(true);
DrawShake();
- Settings::Instance().SetControllerStateNeeded(false);
}
void ShakeMappingIndicator::DrawShake()
diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp
index b9149027ea..ec4b055989 100644
--- a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp
@@ -14,7 +14,6 @@
#include "DolphinQt/Config/Mapping/MappingIndicator.h"
#include "DolphinQt/Config/Mapping/MappingNumeric.h"
#include "DolphinQt/Config/Mapping/MappingWindow.h"
-#include "DolphinQt/Settings.h"
#include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerEmu/Control/Control.h"
@@ -31,11 +30,8 @@ MappingWidget::MappingWidget(MappingWindow* parent) : m_parent(parent)
const auto timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [this] {
- // TODO: The SetControllerStateNeeded interface leaks input into the game.
const auto lock = m_parent->GetController()->GetStateLock();
- Settings::Instance().SetControllerStateNeeded(true);
emit Update();
- Settings::Instance().SetControllerStateNeeded(false);
});
timer->start(1000 / INDICATOR_UPDATE_FREQ);
diff --git a/Source/Core/DolphinQt/Host.cpp b/Source/Core/DolphinQt/Host.cpp
index ac9c91942f..fc53954195 100644
--- a/Source/Core/DolphinQt/Host.cpp
+++ b/Source/Core/DolphinQt/Host.cpp
@@ -153,12 +153,6 @@ void Host_RequestRenderWindowSize(int w, int h)
emit Host::GetInstance()->RequestRenderSize(w, h);
}
-bool Host_UINeedsControllerState()
-{
- return Settings::Instance().IsControllerStateNeeded() ||
- (ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard);
-}
-
bool Host_UIBlocksControllerState()
{
return ImGui::GetCurrentContext() && ImGui::GetIO().WantCaptureKeyboard;
diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp
index b2f5c86d98..cb67fba6ea 100644
--- a/Source/Core/DolphinQt/HotkeyScheduler.cpp
+++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp
@@ -25,6 +25,7 @@
#include "DolphinQt/Settings.h"
+#include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "VideoCommon/OnScreenDisplay.h"
@@ -142,8 +143,14 @@ void HotkeyScheduler::Run()
if (Core::GetState() != Core::State::Stopping)
{
+ // Obey window focus before checking hotkeys.
+ Core::UpdateInputGate();
+
HotkeyManagerEmu::GetStatus();
+ // Everything else on the host thread (controller config dialog) should always get input.
+ ControlReference::SetInputGate(true);
+
if (!Core::IsRunningAndStarted())
continue;
diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp
index 99322db7fe..cbc4849793 100644
--- a/Source/Core/DolphinQt/Settings.cpp
+++ b/Source/Core/DolphinQt/Settings.cpp
@@ -388,16 +388,6 @@ bool Settings::IsBreakpointsVisible() const
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)
{
if (IsCodeVisible() != enabled)
diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h
index f16ce2a474..c9c5f1a422 100644
--- a/Source/Core/DolphinQt/Settings.h
+++ b/Source/Core/DolphinQt/Settings.h
@@ -57,8 +57,6 @@ public:
void SetLogVisible(bool visible);
bool IsLogConfigVisible() const;
void SetLogConfigVisible(bool visible);
- bool IsControllerStateNeeded() const;
- void SetControllerStateNeeded(bool needed);
void SetToolBarVisible(bool visible);
bool IsToolBarVisible() const;
void SetWidgetsLocked(bool visible);
@@ -179,7 +177,6 @@ signals:
private:
bool m_batch = false;
- bool m_controller_state_needed = false;
std::shared_ptr<NetPlay::NetPlayClient> m_client;
std::shared_ptr<NetPlay::NetPlayServer> m_server;
Settings();
diff --git a/Source/Core/InputCommon/ControlReference/ControlReference.cpp b/Source/Core/InputCommon/ControlReference/ControlReference.cpp
index af7536547c..b1dd5deee3 100644
--- a/Source/Core/InputCommon/ControlReference/ControlReference.cpp
+++ b/Source/Core/InputCommon/ControlReference/ControlReference.cpp
@@ -4,19 +4,18 @@
#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;
-bool ControlReference::InputGateOn()
+static thread_local bool tls_input_gate = true;
+
+void ControlReference::SetInputGate(bool enable)
+{
+ tls_input_gate = enable;
+}
+
+bool ControlReference::GetInputGate()
{
- return (SConfig::GetInstance().m_BackgroundInput || Host_RendererHasFocus() ||
- Host_UINeedsControllerState()) &&
- !Host_UIBlocksControllerState();
+ return tls_input_gate;
}
//
@@ -90,7 +89,7 @@ bool OutputReference::IsInput() const
//
ControlState InputReference::State(const ControlState ignore)
{
- if (m_parsed_expression && InputGateOn())
+ if (m_parsed_expression && GetInputGate())
return m_parsed_expression->GetValue() * range;
return 0.0;
}
diff --git a/Source/Core/InputCommon/ControlReference/ControlReference.h b/Source/Core/InputCommon/ControlReference/ControlReference.h
index 3f2c205501..539c7f4927 100644
--- a/Source/Core/InputCommon/ControlReference/ControlReference.h
+++ b/Source/Core/InputCommon/ControlReference/ControlReference.h
@@ -22,7 +22,9 @@
class ControlReference
{
public:
- static bool InputGateOn();
+ // Note: this is per thread.
+ static void SetInputGate(bool enable);
+ static bool GetInputGate();
virtual ~ControlReference();
virtual ControlState State(const ControlState state = 0) = 0;
diff --git a/Source/DSPTool/StubHost.cpp b/Source/DSPTool/StubHost.cpp
index ac6ef92e52..75dd66296d 100644
--- a/Source/DSPTool/StubHost.cpp
+++ b/Source/DSPTool/StubHost.cpp
@@ -34,10 +34,6 @@ void Host_UpdateMainFrame()
void Host_RequestRenderWindowSize(int, int)
{
}
-bool Host_UINeedsControllerState()
-{
- return false;
-}
bool Host_RendererHasFocus()
{
return false;
diff --git a/Source/UnitTests/StubHost.cpp b/Source/UnitTests/StubHost.cpp
index 440ecd336a..4fa45ef1c2 100644
--- a/Source/UnitTests/StubHost.cpp
+++ b/Source/UnitTests/StubHost.cpp
@@ -31,10 +31,6 @@ void Host_UpdateMainFrame()
void Host_RequestRenderWindowSize(int, int)
{
}
-bool Host_UINeedsControllerState()
-{
- return false;
-}
bool Host_UIBlocksControllerState()
{
return false;