mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-28 12:40:12 +00:00
Perform refactoring of pads to remove the ugly pad initialization.
This commit is contained in:
parent
b01e7e3362
commit
d1cde4d0a7
@ -1,5 +1,6 @@
|
||||
#include "basic_keyboard_handler.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
|
||||
void basic_keyboard_handler::Init(const u32 max_connect)
|
||||
@ -17,16 +18,33 @@ void basic_keyboard_handler::Init(const u32 max_connect)
|
||||
m_info.status[0] = CELL_KB_STATUS_CONNECTED; // (TODO: Support for more keyboards)
|
||||
}
|
||||
|
||||
basic_keyboard_handler::basic_keyboard_handler(QObject* target, QObject* parent) : QObject(parent), m_target(target)
|
||||
basic_keyboard_handler::basic_keyboard_handler() : QObject()
|
||||
{
|
||||
// Adds event filter to the target to filter keyevents.
|
||||
}
|
||||
|
||||
/* Sets the target window for the event handler, and also installs an event filter on the target. */
|
||||
void basic_keyboard_handler::SetTargetWindow(QWindow* target)
|
||||
{
|
||||
if (target != nullptr)
|
||||
{
|
||||
m_target = target;
|
||||
target->installEventFilter(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this is hit, it probably means that some refactoring occurs because currently a gsframe is created in Load.
|
||||
// We still want events so filter from application instead since target is null.
|
||||
QApplication::instance()->installEventFilter(this);
|
||||
LOG_ERROR(GENERAL, "Trying to set keyboard handler to a null target window.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool basic_keyboard_handler::eventFilter(QObject* target, QEvent* ev)
|
||||
{
|
||||
// Commenting target since I don't know how to target game window yet.
|
||||
//if (target == m_target)
|
||||
// !m_target is for future proofing when gsrender isn't automatically initialized on load.
|
||||
// !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target)
|
||||
if (!m_target || !m_target->isVisible() || target == m_target)
|
||||
{
|
||||
if (ev->type() == QEvent::KeyPress)
|
||||
{
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Io/KeyboardHandler.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QKeyEvent>
|
||||
#include <QWindow>
|
||||
|
||||
class basic_keyboard_handler final : public QObject, public KeyboardHandlerBase
|
||||
{
|
||||
@ -12,12 +12,13 @@ class basic_keyboard_handler final : public QObject, public KeyboardHandlerBase
|
||||
public:
|
||||
virtual void Init(const u32 max_connect) override;
|
||||
|
||||
explicit basic_keyboard_handler(QObject* target = nullptr, QObject* parent = nullptr);
|
||||
explicit basic_keyboard_handler();
|
||||
|
||||
void SetTargetWindow(QWindow* target);
|
||||
bool eventFilter(QObject* obj, QEvent* ev);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
void LoadSettings();
|
||||
private:
|
||||
QObject* m_target;
|
||||
QWindow* m_target = nullptr;
|
||||
};
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "basic_mouse_handler.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
void basic_mouse_handler::Init(const u32 max_connect)
|
||||
{
|
||||
m_mice.emplace_back(Mouse());
|
||||
@ -13,15 +15,31 @@ void basic_mouse_handler::Init(const u32 max_connect)
|
||||
m_info.product_id[0] = 0x1234;
|
||||
}
|
||||
|
||||
basic_mouse_handler::basic_mouse_handler(QObject* target, QObject* parent) : QObject(parent), m_target(target)
|
||||
basic_mouse_handler::basic_mouse_handler() : QObject()
|
||||
{}
|
||||
|
||||
/* Sets the target window for the event handler, and also installs an event filter on the target. */
|
||||
void basic_mouse_handler::SetTargetWindow(QWindow* target)
|
||||
{
|
||||
if (target != nullptr)
|
||||
{
|
||||
m_target = target;
|
||||
target->installEventFilter(this);
|
||||
}
|
||||
|
||||
bool basic_mouse_handler::eventFilter(QObject* obj, QEvent* ev)
|
||||
else
|
||||
{
|
||||
// Commenting target since I don't know how to target game window yet.
|
||||
//if (m_target == obj)
|
||||
// If this is hit, it probably means that some refactoring occurs because currently a gsframe is created in Load.
|
||||
// We still want events so filter from application instead since target is null.
|
||||
QApplication::instance()->installEventFilter(this);
|
||||
LOG_ERROR(GENERAL, "Trying to set mouse handler to a null target window.");
|
||||
}
|
||||
}
|
||||
|
||||
bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev)
|
||||
{
|
||||
// !m_target is for future proofing when gsrender isn't automatically initialized on load to ensure events still occur
|
||||
// !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target)
|
||||
if (!m_target || !m_target->isVisible() || target == m_target)
|
||||
{
|
||||
switch (ev->type())
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Io/MouseHandler.h"
|
||||
|
||||
#include <QWindow>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
|
||||
@ -12,8 +13,9 @@ class basic_mouse_handler final : public QObject, public MouseHandlerBase
|
||||
public:
|
||||
virtual void Init(const u32 max_connect) override;
|
||||
|
||||
basic_mouse_handler(QObject* target, QObject* parent);
|
||||
basic_mouse_handler();
|
||||
|
||||
void SetTargetWindow(QWindow* target);
|
||||
void MouseButtonDown(QMouseEvent* event);
|
||||
void MouseButtonUp(QMouseEvent* event);
|
||||
void MouseScroll(QWheelEvent* event);
|
||||
@ -21,5 +23,5 @@ public:
|
||||
|
||||
bool eventFilter(QObject* obj, QEvent* ev);
|
||||
private:
|
||||
QObject* m_target;
|
||||
QWindow* m_target = nullptr;
|
||||
};
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include "keyboard_pad_handler.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
keyboard_pad_config g_kbpad_config;
|
||||
|
||||
void keyboard_pad_handler::Init(const u32 max_connect)
|
||||
@ -12,15 +14,15 @@ void keyboard_pad_handler::Init(const u32 max_connect)
|
||||
m_info.now_connect = std::min(m_pads.size(), (size_t)max_connect);
|
||||
}
|
||||
|
||||
keyboard_pad_handler::keyboard_pad_handler(QObject* target, QObject* parent) : QObject(parent), m_target(target)
|
||||
keyboard_pad_handler::keyboard_pad_handler() : QObject()
|
||||
{
|
||||
target->installEventFilter(this);
|
||||
}
|
||||
|
||||
bool keyboard_pad_handler::eventFilter(QObject* target, QEvent* ev)
|
||||
{
|
||||
// Commenting target since I don't know how to target game window yet.
|
||||
//if (target == m_target)
|
||||
// !m_target is for future proofing when gsrender isn't automatically initialized on load.
|
||||
// !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target)
|
||||
if (!m_target || !m_target->isVisible()|| target == m_target)
|
||||
{
|
||||
if (ev->type() == QEvent::KeyPress)
|
||||
{
|
||||
@ -34,6 +36,23 @@ bool keyboard_pad_handler::eventFilter(QObject* target, QEvent* ev)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Sets the target window for the event handler, and also installs an event filter on the target. */
|
||||
void keyboard_pad_handler::SetTargetWindow(QWindow* target)
|
||||
{
|
||||
if (target != nullptr)
|
||||
{
|
||||
m_target = target;
|
||||
target->installEventFilter(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
QApplication::instance()->installEventFilter(this);
|
||||
// If this is hit, it probably means that some refactoring occurs because currently a gsframe is created in Load.
|
||||
// We still want events so filter from application instead since target is null.
|
||||
LOG_ERROR(GENERAL, "Trying to set pad handler to a null target window.");
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_pad_handler::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (event->isAutoRepeat())
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include <QWindow>
|
||||
#include <QKeyEvent>
|
||||
#include <QObject>
|
||||
|
||||
struct keyboard_pad_config final : cfg::node
|
||||
{
|
||||
@ -58,13 +58,14 @@ class keyboard_pad_handler final : public QObject, public PadHandlerBase
|
||||
public:
|
||||
virtual void Init(const u32 max_connect) override;
|
||||
|
||||
keyboard_pad_handler(QObject* target, QObject* parent);
|
||||
keyboard_pad_handler();
|
||||
|
||||
void SetTargetWindow(QWindow* target);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
void LoadSettings();
|
||||
|
||||
bool eventFilter(QObject* obj, QEvent* ev);
|
||||
private:
|
||||
QObject* m_target;
|
||||
QWindow* m_target = nullptr;
|
||||
};
|
||||
|
@ -63,9 +63,6 @@ void rpcs3_app::Init()
|
||||
// Create the main window
|
||||
RPCS3MainWin = new main_window(guiSettings, nullptr);
|
||||
|
||||
// Reset the pads -- see the method for why this is currently needed.
|
||||
ResetPads();
|
||||
|
||||
// Create callbacks from the emulator, which reference the handlers.
|
||||
InitializeCallbacks();
|
||||
|
||||
@ -113,7 +110,13 @@ void rpcs3_app::InitializeCallbacks()
|
||||
switch (keyboard_handler type = g_cfg.io.keyboard)
|
||||
{
|
||||
case keyboard_handler::null: return std::make_shared<NullKeyboardHandler>();
|
||||
case keyboard_handler::basic: return m_basicKeyboardHandler;
|
||||
case keyboard_handler::basic:
|
||||
{
|
||||
basic_keyboard_handler* ret = new basic_keyboard_handler();
|
||||
ret->moveToThread(thread());
|
||||
ret->SetTargetWindow(gameWindow);
|
||||
return std::shared_ptr<KeyboardHandlerBase>(ret);
|
||||
}
|
||||
default: fmt::throw_exception("Invalid keyboard handler: %s", type);
|
||||
}
|
||||
};
|
||||
@ -123,7 +126,13 @@ void rpcs3_app::InitializeCallbacks()
|
||||
switch (mouse_handler type = g_cfg.io.mouse)
|
||||
{
|
||||
case mouse_handler::null: return std::make_shared<NullMouseHandler>();
|
||||
case mouse_handler::basic: return m_basicMouseHandler;
|
||||
case mouse_handler::basic:
|
||||
{
|
||||
basic_mouse_handler* ret = new basic_mouse_handler();
|
||||
ret->moveToThread(thread());
|
||||
ret->SetTargetWindow(gameWindow);
|
||||
return std::shared_ptr<MouseHandlerBase>(ret);
|
||||
}
|
||||
default: fmt::throw_exception("Invalid mouse handler: %s", type);
|
||||
}
|
||||
};
|
||||
@ -133,7 +142,13 @@ void rpcs3_app::InitializeCallbacks()
|
||||
switch (pad_handler type = g_cfg.io.pad)
|
||||
{
|
||||
case pad_handler::null: return std::make_shared<NullPadHandler>();
|
||||
case pad_handler::keyboard: return m_keyboardPadHandler;
|
||||
case pad_handler::keyboard:
|
||||
{
|
||||
keyboard_pad_handler* ret = new keyboard_pad_handler();
|
||||
ret->moveToThread(thread());
|
||||
ret->SetTargetWindow(gameWindow);
|
||||
return std::shared_ptr<PadHandlerBase>(ret);
|
||||
}
|
||||
case pad_handler::ds4: return std::make_shared<ds4_pad_handler>();
|
||||
#ifdef _MSC_VER
|
||||
case pad_handler::xinput: return std::make_shared<xinput_pad_handler>();
|
||||
@ -166,11 +181,31 @@ void rpcs3_app::InitializeCallbacks()
|
||||
|
||||
switch (video_renderer type = g_cfg.video.renderer)
|
||||
{
|
||||
case video_renderer::null: return std::make_unique<gs_frame>("Null", w, h, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
case video_renderer::opengl: return std::make_unique<gl_gs_frame>(w, h, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
case video_renderer::vulkan: return std::make_unique<gs_frame>("Vulkan", w, h, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
case video_renderer::null:
|
||||
{
|
||||
gs_frame* ret = new gs_frame("Null", size.first, size.second, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
gameWindow = ret;
|
||||
return std::unique_ptr<gs_frame>(ret);
|
||||
}
|
||||
case video_renderer::opengl:
|
||||
{
|
||||
gl_gs_frame* ret = new gl_gs_frame(size.first, size.second, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
gameWindow = ret;
|
||||
return std::unique_ptr<gl_gs_frame>(ret);
|
||||
}
|
||||
case video_renderer::vulkan:
|
||||
{
|
||||
gs_frame* ret = new gs_frame("Vulkan", size.first, size.second, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
gameWindow = ret;
|
||||
return std::unique_ptr<gs_frame>(ret);
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12: return std::make_unique<gs_frame>("DirectX 12", w, h, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
case video_renderer::dx12:
|
||||
{
|
||||
gs_frame* ret = new gs_frame("DirectX 12", size.first, size.second, RPCS3MainWin->GetAppIcon(), disableMouse);
|
||||
gameWindow = ret;
|
||||
return std::unique_ptr<gs_frame>(ret);
|
||||
}
|
||||
#endif
|
||||
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
||||
}
|
||||
@ -237,7 +272,6 @@ void rpcs3_app::InitializeConnects()
|
||||
connect(this, &rpcs3_app::RequestCallAfter, this, &rpcs3_app::HandleCallAfter);
|
||||
|
||||
connect(this, &rpcs3_app::OnEmulatorRun, RPCS3MainWin, &main_window::OnEmuRun);
|
||||
connect(this, &rpcs3_app::OnEmulatorStop, this, &rpcs3_app::ResetPads);
|
||||
connect(this, &rpcs3_app::OnEmulatorStop, RPCS3MainWin, &main_window::OnEmuStop);
|
||||
connect(this, &rpcs3_app::OnEmulatorPause, RPCS3MainWin, &main_window::OnEmuPause);
|
||||
connect(this, &rpcs3_app::OnEmulatorResume, RPCS3MainWin, &main_window::OnEmuResume);
|
||||
@ -269,17 +303,3 @@ void rpcs3_app::HandleCallAfter(const std::function<void()>& func)
|
||||
{
|
||||
func();
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to make this in the main thread to receive events from the main thread.
|
||||
* This leads to the tricky situation. Creating it while booting leads to deadlock with a blocking connection.
|
||||
* So, I need to make them before, but when?
|
||||
* I opted to reset them when the Emu stops and on first init. Potentially a race condition on restart? Never encountered issues.
|
||||
* The other tricky issue is that I don't want Init to be called twice on the same object. Reseting the pointer on emu stop should handle this as well!
|
||||
*/
|
||||
void rpcs3_app::ResetPads()
|
||||
{
|
||||
m_basicKeyboardHandler.reset(new basic_keyboard_handler(this, this));
|
||||
m_basicMouseHandler.reset(new basic_mouse_handler(this, this));
|
||||
m_keyboardPadHandler.reset(new keyboard_pad_handler(this, this));
|
||||
}
|
||||
|
@ -41,17 +41,12 @@ Q_SIGNALS:
|
||||
private Q_SLOTS:
|
||||
void OnChangeStyleSheetRequest(const QString& path);
|
||||
void HandleCallAfter(const std::function<void()>& func);
|
||||
void ResetPads();
|
||||
private:
|
||||
void InitializeCallbacks();
|
||||
void InitializeConnects();
|
||||
|
||||
// See ResetPads() for why these shared pointers exist.
|
||||
std::shared_ptr<keyboard_pad_handler> m_keyboardPadHandler;
|
||||
std::shared_ptr<basic_keyboard_handler> m_basicKeyboardHandler;
|
||||
std::shared_ptr<basic_mouse_handler> m_basicMouseHandler;
|
||||
|
||||
main_window* RPCS3MainWin;
|
||||
|
||||
std::shared_ptr<gui_settings> guiSettings;
|
||||
QWindow* gameWindow = nullptr; //! (Currently) only needed so that pad handlers have a valid target for event filtering.
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user