From 57edbafddac2ad42a45ec1ba4e2438cf6064b367 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 1 Jan 2015 08:12:05 -0800 Subject: [PATCH] Replace uses of wxThreadEvent with a statically typed event --- src/colour_button.cpp | 8 +++--- src/colour_button.h | 4 ++- src/dialog_colorpicker.cpp | 21 +++++++--------- src/dialog_dummy_video.cpp | 2 +- src/dialog_fonts_collector.cpp | 14 +++++------ src/dialog_style_editor.cpp | 11 ++++---- src/dialog_style_editor.h | 7 +++--- src/main.cpp | 12 +++++---- src/preferences_base.cpp | 2 +- src/value_event.h | 46 ++++++++++++++++++++++++++++++++++ 10 files changed, 88 insertions(+), 39 deletions(-) create mode 100644 src/value_event.h diff --git a/src/colour_button.cpp b/src/colour_button.cpp index f985e62f1..c0b1c5d58 100644 --- a/src/colour_button.cpp +++ b/src/colour_button.cpp @@ -20,7 +20,7 @@ #include -wxDEFINE_EVENT(EVT_COLOR, wxThreadEvent); +AGI_DEFINE_EVENT(EVT_COLOR, agi::Color); ColourButton::ColourButton(wxWindow *parent, wxSize const& size, bool alpha, agi::Color col, wxValidator const& validator) : wxButton(parent, -1, "", wxDefaultPosition, wxSize(size.GetWidth() + 6, size.GetHeight() + 6), 0, validator) @@ -33,9 +33,8 @@ ColourButton::ColourButton(wxWindow *parent, wxSize const& size, bool alpha, agi colour = new_color; UpdateBitmap(); - wxThreadEvent evt(EVT_COLOR, GetId()); + ValueEvent evt(EVT_COLOR, GetId(), colour); evt.SetEventObject(this); - evt.SetPayload(colour); AddPendingEvent(evt); }); }); @@ -43,7 +42,8 @@ ColourButton::ColourButton(wxWindow *parent, wxSize const& size, bool alpha, agi void ColourButton::UpdateBitmap() { using namespace boost::gil; - fill_pixels(interleaved_view(bmp.GetWidth(), bmp.GetHeight(), (bgr8_pixel_t*)bmp.GetData(), 3 * bmp.GetWidth()), + fill_pixels(interleaved_view(bmp.GetWidth(), bmp.GetHeight(), + (bgr8_pixel_t*)bmp.GetData(), 3 * bmp.GetWidth()), bgr8_pixel_t(colour.r, colour.g, colour.b)); SetBitmapLabel(bmp); } diff --git a/src/colour_button.h b/src/colour_button.h index 6d84c324b..b2e0f9335 100644 --- a/src/colour_button.h +++ b/src/colour_button.h @@ -18,9 +18,11 @@ #include +#include "value_event.h" + /// Emitted by ColourButton when the user picks a new color, with the chosen /// color set to the event payload -wxDECLARE_EVENT(EVT_COLOR, wxThreadEvent); +AGI_DECLARE_EVENT(EVT_COLOR, agi::Color); /// A button which displays a currently-selected color and lets the user pick /// a new color when clicked diff --git a/src/dialog_colorpicker.cpp b/src/dialog_colorpicker.cpp index 6e03df8ed..9035d2d65 100644 --- a/src/dialog_colorpicker.cpp +++ b/src/dialog_colorpicker.cpp @@ -34,6 +34,7 @@ #include "options.h" #include "persist_location.h" #include "utils.h" +#include "value_event.h" #include #include @@ -236,7 +237,7 @@ public: #define STATIC_BORDER_FLAG wxSIMPLE_BORDER #endif -wxDEFINE_EVENT(EVT_RECENT_SELECT, wxThreadEvent); +wxDEFINE_EVENT(EVT_RECENT_SELECT, ValueEvent); /// @class ColorPickerRecent /// @brief A grid of recently used colors which can be selected by clicking on them @@ -255,11 +256,8 @@ class ColorPickerRecent final : public wxStaticBitmap { if (cx < 0 || cx > cols || cy < 0 || cy > rows) return; int i = cols*cy + cx; - if (i >= 0 && i < (int)colors.size()) { - wxThreadEvent evnt(EVT_RECENT_SELECT, GetId()); - evnt.SetPayload(colors[i]); - AddPendingEvent(evnt); - } + if (i >= 0 && i < (int)colors.size()) + AddPendingEvent(ValueEvent(EVT_RECENT_SELECT, GetId(), colors[i])); } void UpdateBitmap() { @@ -331,7 +329,7 @@ public: } }; -wxDEFINE_EVENT(EVT_DROPPER_SELECT, wxThreadEvent); +wxDEFINE_EVENT(EVT_DROPPER_SELECT, ValueEvent); class ColorPickerScreenDropper final : public wxControl { wxBitmap capture; @@ -349,8 +347,7 @@ class ColorPickerScreenDropper final : public wxControl { agi::Color color(pdi.Red(), pdi.Green(), pdi.Blue(), 0); wxThreadEvent evnt(EVT_DROPPER_SELECT, GetId()); - evnt.SetPayload(color); - AddPendingEvent(evnt); + AddPendingEvent(ValueEvent(EVT_DROPPER_SELECT, GetId(), color)); } } @@ -500,7 +497,7 @@ class DialogColorPicker final : public wxDialog { void OnSpectrumChange(wxCommandEvent &evt); void OnSliderChange(wxCommandEvent &evt); void OnAlphaSliderChange(wxCommandEvent &evt); - void OnRecentSelect(wxThreadEvent &evt); // also handles dropper pick + void OnRecentSelect(ValueEvent& evt); // also handles dropper pick void OnDropperMouse(wxMouseEvent &evt); void OnMouse(wxMouseEvent &evt); void OnCaptureLost(wxMouseCaptureLostEvent&); @@ -1045,8 +1042,8 @@ void DialogColorPicker::OnAlphaSliderChange(wxCommandEvent &) { callback(cur_color); } -void DialogColorPicker::OnRecentSelect(wxThreadEvent &evt) { - agi::Color new_color = evt.GetPayload(); +void DialogColorPicker::OnRecentSelect(ValueEvent &evt) { + agi::Color new_color = evt.Get(); new_color.a = cur_color.a; SetColor(new_color); } diff --git a/src/dialog_dummy_video.cpp b/src/dialog_dummy_video.cpp index 8b6a6ee4f..23b32ce17 100644 --- a/src/dialog_dummy_video.cpp +++ b/src/dialog_dummy_video.cpp @@ -136,7 +136,7 @@ DialogDummyVideo::DialogDummyVideo(wxWindow *parent) d.CenterOnParent(); d.Bind(wxEVT_COMBOBOX, &DialogDummyVideo::OnResolutionShortcut, this); - color_btn->Bind(EVT_COLOR, [=](wxThreadEvent& e) { color = color_btn->GetColor(); }); + color_btn->Bind(EVT_COLOR, [=](ValueEvent& e) { color = e.Get(); }); d.Bind(wxEVT_SPINCTRL, [&](wxCommandEvent&) { d.TransferDataFromWindow(); UpdateLengthDisplay(); diff --git a/src/dialog_fonts_collector.cpp b/src/dialog_fonts_collector.cpp index 1e92b4d97..3989d3998 100644 --- a/src/dialog_fonts_collector.cpp +++ b/src/dialog_fonts_collector.cpp @@ -24,6 +24,7 @@ #include "libresrc/libresrc.h" #include "options.h" #include "utils.h" +#include "value_event.h" #include #include @@ -63,7 +64,7 @@ class DialogFontsCollector final : public wxDialog { void OnRadio(wxCommandEvent &e); /// Append text to log message from worker thread - void OnAddText(wxThreadEvent &event); + void OnAddText(ValueEvent>& event); /// Collection complete notification from the worker thread to reenable buttons void OnCollectionComplete(wxThreadEvent &); @@ -79,15 +80,14 @@ enum FcMode { SymlinkToFolder = 4 }; -wxDEFINE_EVENT(EVT_ADD_TEXT, wxThreadEvent); +using color_str_pair = std::pair; +wxDEFINE_EVENT(EVT_ADD_TEXT, ValueEvent); wxDEFINE_EVENT(EVT_COLLECTION_DONE, wxThreadEvent); void FontsCollectorThread(AssFile *subs, agi::fs::path const& destination, FcMode oper, wxEvtHandler *collector) { agi::dispatch::Background().Async([=]{ auto AppendText = [&](wxString text, int colour) { - wxThreadEvent event(EVT_ADD_TEXT); - event.SetPayload(std::make_pair(colour, text)); - collector->AddPendingEvent(event); + collector->AddPendingEvent(ValueEvent(EVT_ADD_TEXT, -1, {colour, text.Clone()})); }; auto paths = FontCollector(AppendText).GetFontPaths(subs); @@ -378,8 +378,8 @@ void DialogFontsCollector::OnRadio(wxCommandEvent &) { } } -void DialogFontsCollector::OnAddText(wxThreadEvent &event) { - std::pair str = event.GetPayload>(); +void DialogFontsCollector::OnAddText(ValueEvent &event) { + auto const& str = event.Get(); collection_log->SetReadOnly(false); int pos = collection_log->GetLength(); auto const& utf8 = str.second.utf8_str(); diff --git a/src/dialog_style_editor.cpp b/src/dialog_style_editor.cpp index f45386762..30dc95635 100644 --- a/src/dialog_style_editor.cpp +++ b/src/dialog_style_editor.cpp @@ -32,13 +32,14 @@ /// @ingroup style_editor /// +#include "dialog_style_editor.h" + #include "ass_dialogue.h" #include "ass_file.h" #include "ass_style.h" #include "ass_style_storage.h" #include "colour_button.h" #include "compat.h" -#include "dialog_style_editor.h" #include "help_button.h" #include "include/aegisub/context.h" #include "libresrc/libresrc.h" @@ -487,7 +488,7 @@ void DialogStyleEditor::UpdateWorkStyle() { work->strikeout = BoxStrikeout->IsChecked(); } -void DialogStyleEditor::OnSetColor(wxThreadEvent&) { +void DialogStyleEditor::OnSetColor(ValueEvent&) { TransferDataFromWindow(); SubsPreview->SetStyle(*work); } @@ -503,9 +504,9 @@ void DialogStyleEditor::OnPreviewTextChange (wxCommandEvent &event) { event.Skip(); } -void DialogStyleEditor::OnPreviewColourChange(wxThreadEvent &evt) { - SubsPreview->SetColour(evt.GetPayload()); - OPT_SET("Colour/Style Editor/Background/Preview")->SetColor(evt.GetPayload()); +void DialogStyleEditor::OnPreviewColourChange(ValueEvent &evt) { + SubsPreview->SetColour(evt.Get()); + OPT_SET("Colour/Style Editor/Background/Preview")->SetColor(evt.Get()); } void DialogStyleEditor::OnCommandPreviewUpdate(wxCommandEvent &event) { diff --git a/src/dialog_style_editor.h b/src/dialog_style_editor.h index f505daa67..41ad606ed 100644 --- a/src/dialog_style_editor.h +++ b/src/dialog_style_editor.h @@ -45,7 +45,8 @@ class wxSpinCtrl; class wxTextCtrl; class wxThreadEvent; class wxWindow; -namespace agi { struct Context; } +namespace agi { struct Context; struct Color; } +template class ValueEvent; class DialogStyleEditor final : public wxDialog { agi::Context *c; @@ -90,14 +91,14 @@ class DialogStyleEditor final : public wxDialog { void OnCommandPreviewUpdate(wxCommandEvent &event); void OnPreviewTextChange(wxCommandEvent &event); - void OnPreviewColourChange(wxThreadEvent &event); + void OnPreviewColourChange(ValueEvent &event); /// @brief Maybe apply changes and maybe close the dialog /// @param apply Should changes be applied? /// @param close Should the dialog be closed? void Apply(bool apply,bool close); /// @brief Sets color for one of the four color buttons - void OnSetColor(wxThreadEvent& evt); + void OnSetColor(ValueEvent& evt); public: DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Context *c, AssStyleStorage *store, std::string const& new_name, wxArrayString const& font_list); diff --git a/src/main.cpp b/src/main.cpp index ae17e5711..6c87eaa4c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -53,6 +53,7 @@ #include "subs_controller.h" #include "subtitles_provider_libass.h" #include "utils.h" +#include "value_event.h" #include "version.h" #include @@ -99,7 +100,9 @@ AegisubApp::AegisubApp() { wxSetEnv("UBUNTU_MENUPROXY", "0"); } -wxDEFINE_EVENT(EVT_CALL_THUNK, wxThreadEvent); +namespace { +wxDEFINE_EVENT(EVT_CALL_THUNK, ValueEvent); +} /// Message displayed when an exception has occurred. static wxString exception_message = "Oops, Aegisub has crashed!\n\nAn attempt has been made to save a copy of your file to:\n\n%s\n\nAegisub will now close."; @@ -146,14 +149,13 @@ bool AegisubApp::OnInit() { // Pointless `this` capture required due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51494 agi::dispatch::Init([this](agi::dispatch::Thunk f) { - auto evt = new wxThreadEvent(EVT_CALL_THUNK); - evt->SetPayload(f); + auto evt = new ValueEvent(EVT_CALL_THUNK, -1, std::move(f)); wxTheApp->QueueEvent(evt); }); - wxTheApp->Bind(EVT_CALL_THUNK, [this](wxThreadEvent &evt) { + wxTheApp->Bind(EVT_CALL_THUNK, [this](ValueEvent& evt) { try { - evt.GetPayload>()(); + evt.Get()(); } catch (...) { OnExceptionInMainLoop(); diff --git a/src/preferences_base.cpp b/src/preferences_base.cpp index a316e0fc0..32fa1fd7d 100644 --- a/src/preferences_base.cpp +++ b/src/preferences_base.cpp @@ -57,7 +57,7 @@ OPTION_UPDATER(IntUpdater, wxSpinEvent, OptionValueInt, evt.GetInt()); OPTION_UPDATER(IntCBUpdater, wxCommandEvent, OptionValueInt, evt.GetInt()); OPTION_UPDATER(DoubleUpdater, wxSpinEvent, OptionValueDouble, evt.GetInt()); OPTION_UPDATER(BoolUpdater, wxCommandEvent, OptionValueBool, !!evt.GetInt()); -OPTION_UPDATER(ColourUpdater, wxThreadEvent, OptionValueColor, evt.GetPayload()); +OPTION_UPDATER(ColourUpdater, ValueEvent, OptionValueColor, evt.Get()); static void browse_button(wxTextCtrl *ctrl) { wxDirDialog dlg(nullptr, _("Please choose the folder:"), config::path->Decode(from_wx(ctrl->GetValue())).wstring()); diff --git a/src/value_event.h b/src/value_event.h new file mode 100644 index 000000000..23a434988 --- /dev/null +++ b/src/value_event.h @@ -0,0 +1,46 @@ +// Copyright (c) 2015, Thomas Goyne +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// Aegisub Project http://www.aegisub.org/ + +#pragma once + +#include + +/// A wxEvent which holds a single templated value +template +class ValueEvent : public wxEvent { + const T value; + +public: + ValueEvent(wxEventType type, int id, T value) + : wxEvent(id, type) + , value(std::move(value)) + { } + + wxEvent *Clone() const override; + T const& Get() const { return value; } +}; + +// Defined out-of-line so that `extern template` can suppress the emission of +// the vtable in every object file that includes the declaration +template +wxEvent *ValueEvent::Clone() const { return new ValueEvent(*this); } + +#define AGI_DECLARE_EVENT(evt_type, value_type) \ + wxDECLARE_EVENT(evt_type, ValueEvent); \ + extern template class ValueEvent; +#define AGI_DEFINE_EVENT(evt_type, value_type) \ + wxDEFINE_EVENT(evt_type, ValueEvent); \ + template class ValueEvent;