From adf6e46200c57093db4e4332e78f398349f5ac3f Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 11 Aug 2015 22:05:18 -0700 Subject: [PATCH] DolphinWX: Ensure TASInputDlg only gets modified on the main thread --- Source/Core/DolphinWX/TASInputDlg.cpp | 70 ++++++++++++++++++++++----- Source/Core/DolphinWX/TASInputDlg.h | 2 + 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/Source/Core/DolphinWX/TASInputDlg.cpp b/Source/Core/DolphinWX/TASInputDlg.cpp index 8896a8bb02..2a95bdc57c 100644 --- a/Source/Core/DolphinWX/TASInputDlg.cpp +++ b/Source/Core/DolphinWX/TASInputDlg.cpp @@ -23,6 +23,16 @@ #include "InputCommon/GCPadStatus.h" #include "InputCommon/InputConfig.h" +wxDEFINE_EVENT(WIIMOTE_UPDATE_CALLBACK, wxCommandEvent); +wxDEFINE_EVENT(GCPAD_UPDATE_CALLBACK, wxCommandEvent); + +struct TASWiimoteReport +{ + u8* data; + WiimoteEmu::ReportFeatures rptf; + int ext; + const wiimote_key key; +}; TASInputDlg::TASInputDlg(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) @@ -65,9 +75,6 @@ void TASInputDlg::CreateBaseLayout() m_buttons_dpad->AddSpacer(20); m_buttons_dpad->Add(m_dpad_down.checkbox); m_buttons_dpad->AddSpacer(20); - - Bind(wxEVT_CLOSE_WINDOW, &TASInputDlg::OnCloseWindow, this); - Bind(wxEVT_TEXT, &TASInputDlg::UpdateFromText, this); } const int TASInputDlg::m_gc_pad_buttons_bitmask[12] = { @@ -193,6 +200,15 @@ void TASInputDlg::CreateWiiLayout(int num) m_main_szr->Add(m_cc_szr); HandleExtensionChange(); + FinishLayout(); +} + +void TASInputDlg::FinishLayout() +{ + Bind(wxEVT_CLOSE_WINDOW, &TASInputDlg::OnCloseWindow, this); + Bind(GCPAD_UPDATE_CALLBACK, &TASInputDlg::GetValuesCallback, this); + Bind(WIIMOTE_UPDATE_CALLBACK, &TASInputDlg::GetValuesCallback, this); + Bind(wxEVT_TEXT, &TASInputDlg::UpdateFromText, this); m_has_layout = true; } @@ -354,7 +370,7 @@ void TASInputDlg::CreateGCLayout() SetSizerAndFit(main_szr); ResetValues(); - m_has_layout = true; + FinishLayout(); } @@ -483,10 +499,7 @@ void TASInputDlg::SetStickValue(bool* ActivatedByKeyboard, int* AmountPressed, w return; } - Textbox->ChangeValue(std::to_string(*AmountPressed)); - wxCommandEvent* evt = new wxCommandEvent(wxEVT_TEXT, Textbox->GetId()); - evt->SetEventObject(Textbox); - wxQueueEvent(this, evt); + Textbox->SetValue(std::to_string(*AmountPressed)); } void TASInputDlg::SetSliderValue(Control* control, int CurrentValue) @@ -627,6 +640,15 @@ void TASInputDlg::GetValues(u8* data, WiimoteEmu::ReportFeatures rptf, int ext, if (!IsShown() || !m_has_layout) return; + if (!wxIsMainThread()) + { + TASWiimoteReport* report = new TASWiimoteReport{ data, rptf, ext, key }; + wxCommandEvent* evt = new wxCommandEvent(WIIMOTE_UPDATE_CALLBACK); + evt->SetClientData(report); + wxQueueEvent(this, evt); + return; + } + GetKeyBoardInput(data, rptf, ext, key); u8* const coreData = rptf.core ? (data + rptf.core) : nullptr; @@ -764,11 +786,37 @@ void TASInputDlg::GetValues(u8* data, WiimoteEmu::ReportFeatures rptf, int ext, } } +void TASInputDlg::GetValuesCallback(wxCommandEvent& event) +{ + if (event.GetEventType() == WIIMOTE_UPDATE_CALLBACK) + { + TASWiimoteReport* report = static_cast(event.GetClientData()); + GetValues(report->data, report->rptf, report->ext, report->key); + delete report; + } + else if (event.GetEventType() == GCPAD_UPDATE_CALLBACK) + { + GCPadStatus* pad = static_cast(event.GetClientData()); + GetValues(pad); + delete pad; + } +} + void TASInputDlg::GetValues(GCPadStatus* PadStatus) { - if (!IsShown()) + if (!IsShown() || !m_has_layout) return; + if (!wxIsMainThread()) + { + GCPadStatus* status = new GCPadStatus(*PadStatus); + wxCommandEvent* evt = new wxCommandEvent(GCPAD_UPDATE_CALLBACK); + evt->SetClientData(status); + wxQueueEvent(this, evt); + return; + } + + //TODO:: Make this instant not when polled. GetKeyBoardInput(PadStatus); @@ -868,9 +916,7 @@ void TASInputDlg::UpdateStickBitmap(Stick stick) x = 256 - (u8)x; if (stick.y_cont.reverse) y = 256 - (u8)y; - // If TASInputDlg::UpdateFromText(wxCommandEvent&) interrupts stick initialization, this bitmap is a nullptr - if (stick.bitmap != nullptr) - stick.bitmap->SetBitmap(CreateStickBitmap(x, y)); + stick.bitmap->SetBitmap(CreateStickBitmap(x, y)); } void TASInputDlg::OnCloseWindow(wxCloseEvent& event) diff --git a/Source/Core/DolphinWX/TASInputDlg.h b/Source/Core/DolphinWX/TASInputDlg.h index 1a6cc60a22..83897817bc 100644 --- a/Source/Core/DolphinWX/TASInputDlg.h +++ b/Source/Core/DolphinWX/TASInputDlg.h @@ -89,6 +89,8 @@ class TASInputDlg : public wxDialog }; wxBoxSizer* CreateCCLayout(); + void FinishLayout(); + void GetValuesCallback(wxCommandEvent& event); void SetStickValue(bool* ActivatedByKeyboard, int* AmountPressed, wxTextCtrl* Textbox, int CurrentValue, int center = 128); void SetButtonValue(Button* button, bool CurrentState); void SetSliderValue(Control* control, int CurrentValue);