Replace uses of wxThreadEvent with a statically typed event

This commit is contained in:
Thomas Goyne 2015-01-01 08:12:05 -08:00
parent ef4424f5e2
commit 57edbafdda
10 changed files with 88 additions and 39 deletions

View file

@ -20,7 +20,7 @@
#include <boost/gil/gil_all.hpp>
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<agi::Color> 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);
}

View file

@ -18,9 +18,11 @@
#include <libaegisub/color.h>
#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

View file

@ -34,6 +34,7 @@
#include "options.h"
#include "persist_location.h"
#include "utils.h"
#include "value_event.h"
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/make_unique.h>
@ -236,7 +237,7 @@ public:
#define STATIC_BORDER_FLAG wxSIMPLE_BORDER
#endif
wxDEFINE_EVENT(EVT_RECENT_SELECT, wxThreadEvent);
wxDEFINE_EVENT(EVT_RECENT_SELECT, ValueEvent<agi::Color>);
/// @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<agi::Color>(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<agi::Color>);
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<agi::Color>(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<agi::Color>& 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<agi::Color>();
void DialogColorPicker::OnRecentSelect(ValueEvent<agi::Color> &evt) {
agi::Color new_color = evt.Get();
new_color.a = cur_color.a;
SetColor(new_color);
}

View file

@ -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<agi::Color>& e) { color = e.Get(); });
d.Bind(wxEVT_SPINCTRL, [&](wxCommandEvent&) {
d.TransferDataFromWindow();
UpdateLengthDisplay();

View file

@ -24,6 +24,7 @@
#include "libresrc/libresrc.h"
#include "options.h"
#include "utils.h"
#include "value_event.h"
#include <libaegisub/dispatch.h>
#include <libaegisub/format_path.h>
@ -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<std::pair<int, wxString>>& 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<int, wxString>;
wxDEFINE_EVENT(EVT_ADD_TEXT, ValueEvent<color_str_pair>);
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<color_str_pair>(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<int, wxString> str = event.GetPayload<std::pair<int, wxString>>();
void DialogFontsCollector::OnAddText(ValueEvent<color_str_pair> &event) {
auto const& str = event.Get();
collection_log->SetReadOnly(false);
int pos = collection_log->GetLength();
auto const& utf8 = str.second.utf8_str();

View file

@ -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<agi::Color>&) {
TransferDataFromWindow();
SubsPreview->SetStyle(*work);
}
@ -503,9 +504,9 @@ void DialogStyleEditor::OnPreviewTextChange (wxCommandEvent &event) {
event.Skip();
}
void DialogStyleEditor::OnPreviewColourChange(wxThreadEvent &evt) {
SubsPreview->SetColour(evt.GetPayload<agi::Color>());
OPT_SET("Colour/Style Editor/Background/Preview")->SetColor(evt.GetPayload<agi::Color>());
void DialogStyleEditor::OnPreviewColourChange(ValueEvent<agi::Color> &evt) {
SubsPreview->SetColour(evt.Get());
OPT_SET("Colour/Style Editor/Background/Preview")->SetColor(evt.Get());
}
void DialogStyleEditor::OnCommandPreviewUpdate(wxCommandEvent &event) {

View file

@ -45,7 +45,8 @@ class wxSpinCtrl;
class wxTextCtrl;
class wxThreadEvent;
class wxWindow;
namespace agi { struct Context; }
namespace agi { struct Context; struct Color; }
template<typename T> 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<agi::Color> &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<agi::Color>& evt);
public:
DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Context *c, AssStyleStorage *store, std::string const& new_name, wxArrayString const& font_list);

View file

@ -53,6 +53,7 @@
#include "subs_controller.h"
#include "subtitles_provider_libass.h"
#include "utils.h"
#include "value_event.h"
#include "version.h"
#include <libaegisub/dispatch.h>
@ -99,7 +100,9 @@ AegisubApp::AegisubApp() {
wxSetEnv("UBUNTU_MENUPROXY", "0");
}
wxDEFINE_EVENT(EVT_CALL_THUNK, wxThreadEvent);
namespace {
wxDEFINE_EVENT(EVT_CALL_THUNK, ValueEvent<agi::dispatch::Thunk>);
}
/// 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<agi::dispatch::Thunk>(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<agi::dispatch::Thunk>& evt) {
try {
evt.GetPayload<std::function<void()>>()();
evt.Get()();
}
catch (...) {
OnExceptionInMainLoop();

View file

@ -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<agi::Color>());
OPTION_UPDATER(ColourUpdater, ValueEvent<agi::Color>, OptionValueColor, evt.Get());
static void browse_button(wxTextCtrl *ctrl) {
wxDirDialog dlg(nullptr, _("Please choose the folder:"), config::path->Decode(from_wx(ctrl->GetValue())).wstring());

46
src/value_event.h Normal file
View file

@ -0,0 +1,46 @@
// Copyright (c) 2015, Thomas Goyne <plorkyeran@aegisub.org>
//
// 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 <wx/event.h>
/// A wxEvent which holds a single templated value
template<typename T>
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<typename T>
wxEvent *ValueEvent<T>::Clone() const { return new ValueEvent<T>(*this); }
#define AGI_DECLARE_EVENT(evt_type, value_type) \
wxDECLARE_EVENT(evt_type, ValueEvent<value_type>); \
extern template class ValueEvent<value_type>;
#define AGI_DEFINE_EVENT(evt_type, value_type) \
wxDEFINE_EVENT(evt_type, ValueEvent<value_type>); \
template class ValueEvent<value_type>;