Input: Remove global variables from SDL Input

Changes the interface as well to remove any unique methods that
frontends needed to call such as StartJoystickEventHandler by
conditionally starting the polling thread only if the frontend hasn't
started it already. Additionally, moves all global state into a single
SDLState class in order to guarantee that the destructors are called in
the proper order
This commit is contained in:
James Rowe
2018-09-20 00:28:05 -06:00
committed by fearlessTobi
parent c8554d218b
commit 09ac66388c
9 changed files with 208 additions and 811 deletions

View File

@ -1,51 +1,64 @@
// Copyright 2017 Citra Emulator Project
// Copyright 2018 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <atomic>
#include <memory>
#include <vector>
#include "core/frontend/input.h"
#include <thread>
#include "common/threadsafe_queue.h"
#include "input_common/sdl/sdl.h"
union SDL_Event;
namespace Common {
class ParamPackage;
}
namespace InputCommon {
namespace Polling {
class DevicePoller;
enum class DeviceType;
} // namespace Polling
} // namespace InputCommon
using SDL_Joystick = struct _SDL_Joystick;
using SDL_JoystickID = s32;
namespace InputCommon {
namespace SDL {
namespace InputCommon::SDL {
/// Initializes and registers SDL device factories
void Init();
class SDLJoystick;
class SDLButtonFactory;
class SDLAnalogFactory;
/// Unresisters SDL device factories and shut them down.
void Shutdown();
class SDLState : public State {
public:
/// Initializes and registers SDL device factories
SDLState();
/// Needs to be called before SDL_QuitSubSystem.
void CloseSDLJoysticks();
/// Unresisters SDL device factories and shut them down.
~SDLState() override;
/// Handle SDL_Events for joysticks from SDL_PollEvent
void HandleGameControllerEvent(const SDL_Event& event);
/// Handle SDL_Events for joysticks from SDL_PollEvent
void HandleGameControllerEvent(const SDL_Event& event);
/// A Loop that calls HandleGameControllerEvent until Shutdown is called
void PollLoop();
std::shared_ptr<SDLJoystick> GetSDLJoystickBySDLID(SDL_JoystickID sdl_id);
std::shared_ptr<SDLJoystick> GetSDLJoystickByGUID(const std::string& guid, int port);
/// Creates a ParamPackage from an SDL_Event that can directly be used to create a ButtonDevice
Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event);
/// Get all DevicePoller that use the SDL backend for a specific device type
std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> GetPollers(
InputCommon::Polling::DeviceType type) override;
namespace Polling {
/// Used by the Pollers during config
std::atomic<bool> polling = false;
Common::SPSCQueue<SDL_Event> event_queue;
/// Get all DevicePoller that use the SDL backend for a specific device type
void GetPollers(InputCommon::Polling::DeviceType type,
std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>>& pollers);
private:
void InitJoystick(int joystick_index);
void CloseJoystick(SDL_Joystick* sdl_joystick);
} // namespace Polling
} // namespace SDL
} // namespace InputCommon
/// Needs to be called before SDL_QuitSubSystem.
void CloseJoysticks();
/// Map of GUID of a list of corresponding virtual Joysticks
std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;
std::mutex joystick_map_mutex;
std::shared_ptr<SDLButtonFactory> button_factory;
std::shared_ptr<SDLAnalogFactory> analog_factory;
bool start_thread = false;
std::atomic<bool> initialized = false;
std::thread poll_thread;
};
} // namespace InputCommon::SDL