3
0
Fork 0
forked from suyu/suyu

input_common/sdl/sdl_impl: Simplify SDL_Joystick deleter handling

The deleter can just be set in the constructor and maintained throughout
the lifetime of the object.

If a contained pointer is null, then the deleter won't execute, so this
is safe to do. We don't need to swap it out with a version of a deleter
that does nothing.
This commit is contained in:
Lioncash 2019-06-03 16:10:08 -04:00
parent 7ea07c6063
commit b46e615551

View file

@ -46,9 +46,8 @@ static int SDLEventWatcher(void* userdata, SDL_Event* event) {
class SDLJoystick { class SDLJoystick {
public: public:
SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick)
decltype(&SDL_JoystickClose) deleter = &SDL_JoystickClose) : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose} {}
: guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, deleter} {}
void SetButton(int button, bool value) { void SetButton(int button, bool value) {
std::lock_guard lock{mutex}; std::lock_guard lock{mutex};
@ -114,10 +113,8 @@ public:
return sdl_joystick.get(); return sdl_joystick.get();
} }
void SetSDLJoystick(SDL_Joystick* joystick, void SetSDLJoystick(SDL_Joystick* joystick) {
decltype(&SDL_JoystickClose) deleter = &SDL_JoystickClose) { sdl_joystick.reset(joystick);
sdl_joystick =
std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)>(joystick, deleter);
} }
private: private:
@ -140,13 +137,13 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& g
const auto it = joystick_map.find(guid); const auto it = joystick_map.find(guid);
if (it != joystick_map.end()) { if (it != joystick_map.end()) {
while (it->second.size() <= static_cast<std::size_t>(port)) { while (it->second.size() <= static_cast<std::size_t>(port)) {
auto joystick = std::make_shared<SDLJoystick>(guid, static_cast<int>(it->second.size()), auto joystick =
nullptr, [](SDL_Joystick*) {}); std::make_shared<SDLJoystick>(guid, static_cast<int>(it->second.size()), nullptr);
it->second.emplace_back(std::move(joystick)); it->second.emplace_back(std::move(joystick));
} }
return it->second[port]; return it->second[port];
} }
auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, [](SDL_Joystick*) {}); auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr);
return joystick_map[guid].emplace_back(std::move(joystick)); return joystick_map[guid].emplace_back(std::move(joystick));
} }
@ -222,12 +219,13 @@ void SDLState::InitJoystick(int joystick_index) {
} }
void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) { void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) {
std::string guid = GetGUID(sdl_joystick); const std::string guid = GetGUID(sdl_joystick);
std::shared_ptr<SDLJoystick> joystick; std::shared_ptr<SDLJoystick> joystick;
{ {
std::lock_guard lock{joystick_map_mutex}; std::lock_guard lock{joystick_map_mutex};
// This call to guid is safe since the joystick is guaranteed to be in the map // This call to guid is safe since the joystick is guaranteed to be in the map
auto& joystick_guid_list = joystick_map[guid]; const auto& joystick_guid_list = joystick_map[guid];
const auto joystick_it = const auto joystick_it =
std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(),
[&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) { [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) {
@ -235,9 +233,10 @@ void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) {
}); });
joystick = *joystick_it; joystick = *joystick_it;
} }
// Destruct SDL_Joystick outside the lock guard because SDL can internally call event calback
// which locks the mutex again // Destruct SDL_Joystick outside the lock guard because SDL can internally call the
joystick->SetSDLJoystick(nullptr, [](SDL_Joystick*) {}); // event callback which locks the mutex again.
joystick->SetSDLJoystick(nullptr);
} }
void SDLState::HandleGameControllerEvent(const SDL_Event& event) { void SDLState::HandleGameControllerEvent(const SDL_Event& event) {