summaryrefslogtreecommitdiff
path: root/src/input_common/main.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash2020-08-27 15:16:47 -0400
committerGravatar Lioncash2020-08-27 16:11:17 -0400
commit9e1b0af25907f7a8b960aa5c1e7d931691f40196 (patch)
tree9bfda0b559cb025da3bc65168d28ee78144daa20 /src/input_common/main.cpp
parentMerge pull request #4530 from Morph1984/mjolnir-p1 (diff)
downloadyuzu-9e1b0af25907f7a8b960aa5c1e7d931691f40196.tar.gz
yuzu-9e1b0af25907f7a8b960aa5c1e7d931691f40196.tar.xz
yuzu-9e1b0af25907f7a8b960aa5c1e7d931691f40196.zip
input_common: Eliminate most global state
Abstracts most of the input mechanisms under an InputSubsystem class that is managed by the frontends, eliminating any static constructors and destructors. This gets rid of global accessor functions and also allows the frontends to have a more fine-grained control over the lifecycle of the input subsystem. This also makes it explicit which interfaces rely on the input subsystem instead of making it opaque in the interface functions. All that remains to migrate over is the factories, which can be done in a separate change.
Diffstat (limited to 'src/input_common/main.cpp')
-rw-r--r--src/input_common/main.cpp250
1 files changed, 143 insertions, 107 deletions
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index 8e67a7437..57e7a25fe 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -18,66 +18,166 @@
18 18
19namespace InputCommon { 19namespace InputCommon {
20 20
21static std::shared_ptr<Keyboard> keyboard; 21struct InputSubsystem::Impl {
22static std::shared_ptr<MotionEmu> motion_emu; 22 void Initialize() {
23 auto gcadapter = std::make_shared<GCAdapter::Adapter>();
24 gcbuttons = std::make_shared<GCButtonFactory>(gcadapter);
25 Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons);
26 gcanalog = std::make_shared<GCAnalogFactory>(gcadapter);
27 Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog);
28
29 keyboard = std::make_shared<Keyboard>();
30 Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
31 Input::RegisterFactory<Input::AnalogDevice>("analog_from_button",
32 std::make_shared<AnalogFromButton>());
33 motion_emu = std::make_shared<MotionEmu>();
34 Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
35
23#ifdef HAVE_SDL2 36#ifdef HAVE_SDL2
24static std::unique_ptr<SDL::State> sdl; 37 sdl = SDL::Init();
25#endif 38#endif
26static std::unique_ptr<CemuhookUDP::State> udp;
27static std::shared_ptr<GCButtonFactory> gcbuttons;
28static std::shared_ptr<GCAnalogFactory> gcanalog;
29
30void Init() {
31 auto gcadapter = std::make_shared<GCAdapter::Adapter>();
32 gcbuttons = std::make_shared<GCButtonFactory>(gcadapter);
33 Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons);
34 gcanalog = std::make_shared<GCAnalogFactory>(gcadapter);
35 Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog);
36
37 keyboard = std::make_shared<Keyboard>();
38 Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
39 Input::RegisterFactory<Input::AnalogDevice>("analog_from_button",
40 std::make_shared<AnalogFromButton>());
41 motion_emu = std::make_shared<MotionEmu>();
42 Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
43 39
40 udp = CemuhookUDP::Init();
41 }
42
43 void Shutdown() {
44 Input::UnregisterFactory<Input::ButtonDevice>("keyboard");
45 keyboard.reset();
46 Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
47 Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
48 motion_emu.reset();
44#ifdef HAVE_SDL2 49#ifdef HAVE_SDL2
45 sdl = SDL::Init(); 50 sdl.reset();
46#endif 51#endif
47 udp = CemuhookUDP::Init(); 52 udp.reset();
48} 53 Input::UnregisterFactory<Input::ButtonDevice>("gcpad");
54 Input::UnregisterFactory<Input::AnalogDevice>("gcpad");
55
56 gcbuttons.reset();
57 gcanalog.reset();
58 }
59
60 [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
61 std::vector<Common::ParamPackage> devices = {
62 Common::ParamPackage{{"display", "Any"}, {"class", "any"}},
63 Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}},
64 };
65#ifdef HAVE_SDL2
66 auto sdl_devices = sdl->GetInputDevices();
67 devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end());
68#endif
69 auto udp_devices = udp->GetInputDevices();
70 devices.insert(devices.end(), udp_devices.begin(), udp_devices.end());
71 return devices;
72 }
73
74 [[nodiscard]] AnalogMapping GetAnalogMappingForDevice(
75 const Common::ParamPackage& params) const {
76 if (!params.Has("class") || params.Get("class", "") == "any") {
77 return {};
78 }
79 if (params.Get("class", "") == "key") {
80 // TODO consider returning the SDL key codes for the default keybindings
81 return {};
82 }
83#ifdef HAVE_SDL2
84 if (params.Get("class", "") == "sdl") {
85 return sdl->GetAnalogMappingForDevice(params);
86 }
87#endif
88 return {};
89 }
90
91 [[nodiscard]] ButtonMapping GetButtonMappingForDevice(
92 const Common::ParamPackage& params) const {
93 if (!params.Has("class") || params.Get("class", "") == "any") {
94 return {};
95 }
96 if (params.Get("class", "") == "key") {
97 // TODO consider returning the SDL key codes for the default keybindings
98 return {};
99 }
100#ifdef HAVE_SDL2
101 if (params.Get("class", "") == "sdl") {
102 return sdl->GetButtonMappingForDevice(params);
103 }
104#endif
105 return {};
106 }
49 107
50void Shutdown() { 108 std::shared_ptr<Keyboard> keyboard;
51 Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); 109 std::shared_ptr<MotionEmu> motion_emu;
52 keyboard.reset();
53 Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
54 Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
55 motion_emu.reset();
56#ifdef HAVE_SDL2 110#ifdef HAVE_SDL2
57 sdl.reset(); 111 std::unique_ptr<SDL::State> sdl;
58#endif 112#endif
59 udp.reset(); 113 std::unique_ptr<CemuhookUDP::State> udp;
60 Input::UnregisterFactory<Input::ButtonDevice>("gcpad"); 114 std::shared_ptr<GCButtonFactory> gcbuttons;
61 Input::UnregisterFactory<Input::AnalogDevice>("gcpad"); 115 std::shared_ptr<GCAnalogFactory> gcanalog;
116};
117
118InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
119
120InputSubsystem::~InputSubsystem() = default;
121
122void InputSubsystem::Initialize() {
123 impl->Initialize();
124}
125
126void InputSubsystem::Shutdown() {
127 impl->Shutdown();
128}
129
130Keyboard* InputSubsystem::GetKeyboard() {
131 return impl->keyboard.get();
132}
133
134const Keyboard* InputSubsystem::GetKeyboard() const {
135 return impl->keyboard.get();
136}
137
138MotionEmu* InputSubsystem::GetMotionEmu() {
139 return impl->motion_emu.get();
140}
141
142const MotionEmu* InputSubsystem::GetMotionEmu() const {
143 return impl->motion_emu.get();
144}
145
146std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
147 return impl->GetInputDevices();
148}
149
150AnalogMapping InputSubsystem::GetAnalogMappingForDevice(const Common::ParamPackage& device) const {
151 return impl->GetAnalogMappingForDevice(device);
152}
62 153
63 gcbuttons.reset(); 154ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPackage& device) const {
64 gcanalog.reset(); 155 return impl->GetButtonMappingForDevice(device);
65} 156}
66 157
67Keyboard* GetKeyboard() { 158GCAnalogFactory* InputSubsystem::GetGCAnalogs() {
68 return keyboard.get(); 159 return impl->gcanalog.get();
69} 160}
70 161
71MotionEmu* GetMotionEmu() { 162const GCAnalogFactory* InputSubsystem::GetGCAnalogs() const {
72 return motion_emu.get(); 163 return impl->gcanalog.get();
73} 164}
74 165
75GCButtonFactory* GetGCButtons() { 166GCButtonFactory* InputSubsystem::GetGCButtons() {
76 return gcbuttons.get(); 167 return impl->gcbuttons.get();
77} 168}
78 169
79GCAnalogFactory* GetGCAnalogs() { 170const GCButtonFactory* InputSubsystem::GetGCButtons() const {
80 return gcanalog.get(); 171 return impl->gcbuttons.get();
172}
173
174std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers(
175 Polling::DeviceType type) const {
176#ifdef HAVE_SDL2
177 return impl->sdl->GetPollers(type);
178#else
179 return {};
180#endif
81} 181}
82 182
83std::string GenerateKeyboardParam(int key_code) { 183std::string GenerateKeyboardParam(int key_code) {
@@ -101,68 +201,4 @@ std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left,
101 }; 201 };
102 return circle_pad_param.Serialize(); 202 return circle_pad_param.Serialize();
103} 203}
104
105std::vector<Common::ParamPackage> GetInputDevices() {
106 std::vector<Common::ParamPackage> devices = {
107 Common::ParamPackage{{"display", "Any"}, {"class", "any"}},
108 Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}},
109 };
110#ifdef HAVE_SDL2
111 auto sdl_devices = sdl->GetInputDevices();
112 devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end());
113#endif
114 auto udp_devices = udp->GetInputDevices();
115 devices.insert(devices.end(), udp_devices.begin(), udp_devices.end());
116 return devices;
117}
118
119std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage> GetButtonMappingForDevice(
120 const Common::ParamPackage& params) {
121 std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage> mappings;
122 if (!params.Has("class") || params.Get("class", "") == "any") {
123 return {};
124 }
125 if (params.Get("class", "") == "key") {
126 // TODO consider returning the SDL key codes for the default keybindings
127 return {};
128 }
129#ifdef HAVE_SDL2
130 if (params.Get("class", "") == "sdl") {
131 return sdl->GetButtonMappingForDevice(params);
132 }
133#endif
134 return {};
135}
136
137std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage> GetAnalogMappingForDevice(
138 const Common::ParamPackage& params) {
139 std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage> mappings;
140 if (!params.Has("class") || params.Get("class", "") == "any") {
141 return {};
142 }
143 if (params.Get("class", "") == "key") {
144 // TODO consider returning the SDL key codes for the default keybindings
145 return {};
146 }
147#ifdef HAVE_SDL2
148 if (params.Get("class", "") == "sdl") {
149 return sdl->GetAnalogMappingForDevice(params);
150 }
151#endif
152 return {};
153}
154
155namespace Polling {
156
157std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type) {
158 std::vector<std::unique_ptr<DevicePoller>> pollers;
159
160#ifdef HAVE_SDL2
161 pollers = sdl->GetPollers(type);
162#endif
163
164 return pollers;
165}
166
167} // namespace Polling
168} // namespace InputCommon 204} // namespace InputCommon