Dependency injection for apu/gpu/hid.

This commit is contained in:
Ben Vanik
2015-11-08 15:02:24 -08:00
parent 9a6c5c5c74
commit 5834a42ef3
34 changed files with 217 additions and 158 deletions

View File

@@ -22,12 +22,51 @@
#include "xenia/ui/imgui_drawer.h"
#include "xenia/ui/window.h"
// Available input drivers:
#include "xenia/hid/nop/nop_hid.h"
#if XE_PLATFORM_WIN32
#include "xenia/hid/winkey/winkey_hid.h"
#include "xenia/hid/xinput/xinput_hid.h"
#endif // XE_PLATFORM_WIN32
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");
namespace xe {
namespace hid {
std::unique_ptr<xe::ui::ImGuiDrawer> imgui_drawer_;
std::unique_ptr<xe::hid::InputSystem> input_system_;
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
ui::Window* window) {
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
if (FLAGS_hid.compare("nop") == 0) {
drivers.emplace_back(xe::hid::nop::Create(window));
#if XE_PLATFORM_WIN32
} else if (FLAGS_hid.compare("winkey") == 0) {
drivers.emplace_back(xe::hid::winkey::Create(window));
} else if (FLAGS_hid.compare("xinput") == 0) {
drivers.emplace_back(xe::hid::xinput::Create(window));
#endif // XE_PLATFORM_WIN32
} else {
#if XE_PLATFORM_WIN32
auto xinput_driver = xe::hid::xinput::Create(window);
if (xinput_driver) {
drivers.emplace_back(std::move(xinput_driver));
}
auto winkey_driver = xe::hid::winkey::Create(window);
if (winkey_driver) {
drivers.emplace_back(std::move(winkey_driver));
}
#endif // XE_PLATFORM_WIN32
if (drivers.empty()) {
// Fallback to nop if none created.
drivers.emplace_back(xe::hid::nop::Create(window));
}
}
return drivers;
}
std::unique_ptr<xe::ui::GraphicsContext> CreateDemoContext(
xe::ui::Window* window) {
return xe::ui::gl::GLContext::Create(window);
@@ -70,7 +109,11 @@ int hid_demo_main(const std::vector<std::wstring>& args) {
imgui_drawer_->SetupDefaultInput();
// Initialize input system and all drivers.
input_system_ = xe::hid::InputSystem::Create(window.get());
input_system_ = std::make_unique<xe::hid::InputSystem>(window.get());
auto drivers = CreateInputDrivers(window.get());
for (size_t i = 0; i < drivers.size(); ++i) {
input_system_->AddDriver(std::move(drivers[i]));
}
});
window->on_painting.AddListener([&](xe::ui::UIEvent* e) {

View File

@@ -8,5 +8,3 @@
*/
#include "xenia/hid/hid_flags.h"
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");

View File

@@ -12,6 +12,4 @@
#include <gflags/gflags.h>
DECLARE_string(hid);
#endif // XENIA_HID_HID_FLAGS_H_

View File

@@ -12,8 +12,7 @@
namespace xe {
namespace hid {
InputDriver::InputDriver(InputSystem* input_system)
: input_system_(input_system) {}
InputDriver::InputDriver(xe::ui::Window* window) : window_(window) {}
InputDriver::~InputDriver() = default;

View File

@@ -13,6 +13,12 @@
#include "xenia/hid/input.h"
#include "xenia/xbox.h"
namespace xe {
namespace ui {
class Window;
} // namespace ui
} // namespace xe
namespace xe {
namespace hid {
@@ -33,9 +39,9 @@ class InputDriver {
X_INPUT_KEYSTROKE* out_keystroke) = 0;
protected:
explicit InputDriver(InputSystem* input_system);
explicit InputDriver(xe::ui::Window* window);
InputSystem* input_system_ = nullptr;
xe::ui::Window* window_ = nullptr;
};
} // namespace hid

View File

@@ -13,54 +13,9 @@
#include "xenia/hid/hid_flags.h"
#include "xenia/hid/input_driver.h"
#include "xenia/hid/nop/nop_hid.h"
#if XE_PLATFORM_WIN32
#include "xenia/hid/winkey/winkey_hid.h"
#include "xenia/hid/xinput/xinput_hid.h"
#endif // XE_PLATFORM_WIN32
namespace xe {
namespace hid {
std::unique_ptr<InputSystem> InputSystem::Create(xe::ui::Window* window) {
std::unique_ptr<InputSystem> input_system(new InputSystem(window));
if (FLAGS_hid.compare("nop") == 0) {
input_system->AddDriver(xe::hid::nop::Create(input_system.get()));
#if XE_PLATFORM_WIN32
} else if (FLAGS_hid.compare("winkey") == 0) {
input_system->AddDriver(xe::hid::winkey::Create(input_system.get()));
} else if (FLAGS_hid.compare("xinput") == 0) {
input_system->AddDriver(xe::hid::xinput::Create(input_system.get()));
#endif // WIN32
} else {
// Create all available.
bool any_created = false;
// NOTE: in any mode we create as many as we can, falling back to nop.
#if XE_PLATFORM_WIN32
auto xinput_driver = xe::hid::xinput::Create(input_system.get());
if (xinput_driver) {
input_system->AddDriver(std::move(xinput_driver));
any_created = true;
}
auto winkey_driver = xe::hid::winkey::Create(input_system.get());
if (winkey_driver) {
input_system->AddDriver(std::move(winkey_driver));
any_created = true;
}
#endif // WIN32
// Fallback to nop if none created.
if (!any_created) {
input_system->AddDriver(xe::hid::nop::Create(input_system.get()));
}
}
return input_system;
}
InputSystem::InputSystem(xe::ui::Window* window) : window_(window) {}
InputSystem::~InputSystem() = default;

View File

@@ -14,6 +14,7 @@
#include <vector>
#include "xenia/hid/input.h"
#include "xenia/hid/input_driver.h"
#include "xenia/xbox.h"
namespace xe {
@@ -25,14 +26,11 @@ class Window;
namespace xe {
namespace hid {
class InputDriver;
class InputSystem {
public:
explicit InputSystem(xe::ui::Window* window);
~InputSystem();
static std::unique_ptr<InputSystem> Create(xe::ui::Window* window);
xe::ui::Window* window() const { return window_; }
X_STATUS Setup();
@@ -47,8 +45,6 @@ class InputSystem {
X_INPUT_KEYSTROKE* out_keystroke);
private:
explicit InputSystem(xe::ui::Window* window);
xe::ui::Window* window_ = nullptr;
std::vector<std::unique_ptr<InputDriver>> drivers_;

View File

@@ -15,8 +15,8 @@ namespace xe {
namespace hid {
namespace nop {
std::unique_ptr<InputDriver> Create(InputSystem* input_system) {
return std::make_unique<NopInputDriver>(input_system);
std::unique_ptr<InputDriver> Create(xe::ui::Window* window) {
return std::make_unique<NopInputDriver>(window);
}
} // namespace nop

View File

@@ -18,7 +18,7 @@ namespace xe {
namespace hid {
namespace nop {
std::unique_ptr<InputDriver> Create(InputSystem* input_system);
std::unique_ptr<InputDriver> Create(xe::ui::Window* window);
} // namespace nop
} // namespace hid

View File

@@ -15,10 +15,9 @@ namespace xe {
namespace hid {
namespace nop {
NopInputDriver::NopInputDriver(InputSystem* input_system)
: InputDriver(input_system) {}
NopInputDriver::NopInputDriver(xe::ui::Window* window) : InputDriver(window) {}
NopInputDriver::~NopInputDriver() {}
NopInputDriver::~NopInputDriver() = default;
X_STATUS NopInputDriver::Setup() { return X_STATUS_SUCCESS; }

View File

@@ -18,7 +18,7 @@ namespace nop {
class NopInputDriver : public InputDriver {
public:
explicit NopInputDriver(InputSystem* input_system);
explicit NopInputDriver(xe::ui::Window* window);
~NopInputDriver() override;
X_STATUS Setup() override;

View File

@@ -15,8 +15,8 @@ namespace xe {
namespace hid {
namespace winkey {
std::unique_ptr<InputDriver> Create(InputSystem* input_system) {
return std::make_unique<WinKeyInputDriver>(input_system);
std::unique_ptr<InputDriver> Create(xe::ui::Window* window) {
return std::make_unique<WinKeyInputDriver>(window);
}
} // namespace winkey

View File

@@ -18,7 +18,7 @@ namespace xe {
namespace hid {
namespace winkey {
std::unique_ptr<InputDriver> Create(InputSystem* input_system);
std::unique_ptr<InputDriver> Create(xe::ui::Window* window);
} // namespace winkey
} // namespace hid

View File

@@ -19,10 +19,10 @@ namespace xe {
namespace hid {
namespace winkey {
WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
: InputDriver(input_system), packet_number_(1) {
WinKeyInputDriver::WinKeyInputDriver(xe::ui::Window* window)
: InputDriver(window), packet_number_(1) {
// Register a key listener.
input_system_->window()->on_key_down.AddListener([this](ui::KeyEvent* evt) {
window_->on_key_down.AddListener([this](ui::KeyEvent* evt) {
auto global_lock = global_critical_region_.Acquire();
KeyEvent key;
@@ -32,7 +32,7 @@ WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
key.repeat_count = evt->repeat_count();
key_events_.push(key);
});
input_system_->window()->on_key_up.AddListener([this](ui::KeyEvent* evt) {
window_->on_key_up.AddListener([this](ui::KeyEvent* evt) {
auto global_lock = global_critical_region_.Acquire();
KeyEvent key;
@@ -89,7 +89,7 @@ X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
int16_t thumb_rx = 0;
int16_t thumb_ry = 0;
if (input_system_->window()->has_focus()) {
if (window_->has_focus()) {
if (IS_KEY_TOGGLED(VK_CAPITAL)) {
// dpad toggled
if (IS_KEY_DOWN(0x41)) {

View File

@@ -21,7 +21,7 @@ namespace winkey {
class WinKeyInputDriver : public InputDriver {
public:
explicit WinKeyInputDriver(InputSystem* input_system);
explicit WinKeyInputDriver(xe::ui::Window* window);
~WinKeyInputDriver() override;
X_STATUS Setup() override;

View File

@@ -15,8 +15,8 @@ namespace xe {
namespace hid {
namespace xinput {
std::unique_ptr<InputDriver> Create(InputSystem* input_system) {
return std::make_unique<XInputInputDriver>(input_system);
std::unique_ptr<InputDriver> Create(xe::ui::Window* window) {
return std::make_unique<XInputInputDriver>(window);
}
} // namespace xinput

View File

@@ -18,7 +18,7 @@ namespace xe {
namespace hid {
namespace xinput {
std::unique_ptr<InputDriver> Create(InputSystem* input_system);
std::unique_ptr<InputDriver> Create(xe::ui::Window* window);
} // namespace xinput
} // namespace hid

View File

@@ -19,8 +19,8 @@ namespace xe {
namespace hid {
namespace xinput {
XInputInputDriver::XInputInputDriver(InputSystem* input_system)
: InputDriver(input_system) {
XInputInputDriver::XInputInputDriver(xe::ui::Window* window)
: InputDriver(window) {
XInputEnable(TRUE);
}

View File

@@ -18,7 +18,7 @@ namespace xinput {
class XInputInputDriver : public InputDriver {
public:
explicit XInputInputDriver(InputSystem* input_system);
explicit XInputInputDriver(xe::ui::Window* window);
~XInputInputDriver() override;
X_STATUS Setup() override;