diff --git a/src/gui/input/InputAPIAddWindow.cpp b/src/gui/input/InputAPIAddWindow.cpp index a6d1f1a96..5bdd6f405 100644 --- a/src/gui/input/InputAPIAddWindow.cpp +++ b/src/gui/input/InputAPIAddWindow.cpp @@ -114,6 +114,12 @@ InputAPIAddWindow::InputAPIAddWindow(wxWindow* parent, const wxPoint& position, this->Bind(wxControllersRefreshed, &InputAPIAddWindow::on_controllers_refreshed, this); } +InputAPIAddWindow::~InputAPIAddWindow() +{ + std::lock_guard lock{m_search_thread_data->mutex}; + m_search_thread_data->discardResult = true; +} + void InputAPIAddWindow::on_add_button(wxCommandEvent& event) { const auto selection = m_input_api->GetSelection(); @@ -162,6 +168,10 @@ void InputAPIAddWindow::on_api_selected(wxCommandEvent& event) if (m_input_api->GetSelection() == wxNOT_FOUND) return; + m_search_running = false; + if(m_search_thread_data) + m_search_thread_data->discardResult = true; + m_controller_list->Enable(); m_controller_list->SetSelection(wxNOT_FOUND); @@ -239,19 +249,25 @@ void InputAPIAddWindow::on_controller_dropdown(wxCommandEvent& event) m_controller_list->Append(_("Searching for controllers..."), (wxClientData*)nullptr); m_controller_list->SetSelection(wxNOT_FOUND); - std::thread([this, provider, selected_uuid]() + m_search_thread_data = std::make_unique(); + std::thread([this, provider, selected_uuid](std::shared_ptr data) { auto available_controllers = provider->get_controllers(); - wxCommandEvent event(wxControllersRefreshed); - event.SetEventObject(m_controller_list); - event.SetClientObject(new wxCustomData(std::move(available_controllers))); - event.SetInt(provider->api()); - event.SetString(selected_uuid); - wxPostEvent(this, event); - - m_search_running = false; - }).detach(); + { + std::scoped_lock lock{data->mutex}; + if(!data->discardResult) + { + wxCommandEvent event(wxControllersRefreshed); + event.SetEventObject(m_controller_list); + event.SetClientObject(new wxCustomData(std::move(available_controllers))); + event.SetInt(provider->api()); + event.SetString(selected_uuid); + wxPostEvent(this, event); + m_search_running = false; + } + } + }, m_search_thread_data).detach(); } void InputAPIAddWindow::on_controller_selected(wxCommandEvent& event) diff --git a/src/gui/input/InputAPIAddWindow.h b/src/gui/input/InputAPIAddWindow.h index ebee05927..dd4eaf7fa 100644 --- a/src/gui/input/InputAPIAddWindow.h +++ b/src/gui/input/InputAPIAddWindow.h @@ -19,6 +19,7 @@ class InputAPIAddWindow : public wxDialog { public: InputAPIAddWindow(wxWindow* parent, const wxPoint& position, const std::vector& controllers); + ~InputAPIAddWindow(); bool is_valid() const { return m_type.has_value() && m_controller != nullptr; } InputAPI::Type get_type() const { return m_type.value(); } @@ -50,4 +51,10 @@ class InputAPIAddWindow : public wxDialog std::vector m_controllers; std::atomic_bool m_search_running = false; + struct AsyncThreadData + { + std::atomic_bool discardResult = false; + std::mutex mutex; + }; + std::shared_ptr m_search_thread_data; };