Clean up OptionValue

Make the vtables less absurdly huge (knocks 100KB off aegisub32.exe),
eliminate some copies of the values when constructing the options, and
use an enum class for the value type.
This commit is contained in:
Thomas Goyne 2014-03-31 09:24:56 -07:00
parent 371f602100
commit c59b9d59b8
10 changed files with 174 additions and 128 deletions

View File

@ -125,43 +125,43 @@ void Options::Flush() const {
for (auto const& ov : values) { for (auto const& ov : values) {
switch (ov.second->GetType()) { switch (ov.second->GetType()) {
case OptionValue::Type_String: case OptionType::String:
put_option(obj_out, ov.first, ov.second->GetString()); put_option(obj_out, ov.first, ov.second->GetString());
break; break;
case OptionValue::Type_Int: case OptionType::Int:
put_option(obj_out, ov.first, ov.second->GetInt()); put_option(obj_out, ov.first, ov.second->GetInt());
break; break;
case OptionValue::Type_Double: case OptionType::Double:
put_option(obj_out, ov.first, ov.second->GetDouble()); put_option(obj_out, ov.first, ov.second->GetDouble());
break; break;
case OptionValue::Type_Color: case OptionType::Color:
put_option(obj_out, ov.first, ov.second->GetColor().GetRgbFormatted()); put_option(obj_out, ov.first, ov.second->GetColor().GetRgbFormatted());
break; break;
case OptionValue::Type_Bool: case OptionType::Bool:
put_option(obj_out, ov.first, ov.second->GetBool()); put_option(obj_out, ov.first, ov.second->GetBool());
break; break;
case OptionValue::Type_List_String: case OptionType::ListString:
put_array(obj_out, ov.first, "string", ov.second->GetListString()); put_array(obj_out, ov.first, "string", ov.second->GetListString());
break; break;
case OptionValue::Type_List_Int: case OptionType::ListInt:
put_array(obj_out, ov.first, "int", ov.second->GetListInt()); put_array(obj_out, ov.first, "int", ov.second->GetListInt());
break; break;
case OptionValue::Type_List_Double: case OptionType::ListDouble:
put_array(obj_out, ov.first, "double", ov.second->GetListDouble()); put_array(obj_out, ov.first, "double", ov.second->GetListDouble());
break; break;
case OptionValue::Type_List_Color: case OptionType::ListColor:
put_array(obj_out, ov.first, "color", ov.second->GetListColor()); put_array(obj_out, ov.first, "color", ov.second->GetListColor());
break; break;
case OptionValue::Type_List_Bool: case OptionType::ListBool:
put_array(obj_out, ov.first, "bool", ov.second->GetListBool()); put_array(obj_out, ov.first, "bool", ov.second->GetListBool());
break; break;
} }

View File

@ -59,9 +59,9 @@ void ConfigVisitor::Visit(const json::Object& object) {
} }
} }
template<class OptionValueType, class ValueType> template<class OptionValueType>
std::unique_ptr<OptionValue> ConfigVisitor::ReadArray(json::Array const& src, std::string const& array_type, void (OptionValueType::*)(const std::vector<ValueType>&)) { std::unique_ptr<OptionValue> ConfigVisitor::ReadArray(json::Array const& src, std::string const& array_type) {
std::vector<ValueType> arr; typename OptionValueType::value_type arr;
arr.reserve(src.size()); arr.reserve(src.size());
for (json::Object const& obj : src) { for (json::Object const& obj : src) {
@ -74,10 +74,10 @@ std::unique_ptr<OptionValue> ConfigVisitor::ReadArray(json::Array const& src, st
return nullptr; return nullptr;
} }
arr.push_back(ValueType(obj.begin()->second)); arr.push_back((typename OptionValueType::value_type::value_type)(obj.begin()->second));
} }
return util::make_unique<OptionValueType>(name, arr); return util::make_unique<OptionValueType>(name, std::move(arr));
} }
void ConfigVisitor::Visit(const json::Array& array) { void ConfigVisitor::Visit(const json::Array& array) {
@ -95,15 +95,15 @@ void ConfigVisitor::Visit(const json::Array& array) {
const std::string& array_type = front.begin()->first; const std::string& array_type = front.begin()->first;
if (array_type == "string") if (array_type == "string")
AddOptionValue(ReadArray(array, array_type, &OptionValueListString::SetListString)); AddOptionValue(ReadArray<OptionValueListString>(array, array_type));
else if (array_type == "int") else if (array_type == "int")
AddOptionValue(ReadArray(array, array_type, &OptionValueListInt::SetListInt)); AddOptionValue(ReadArray<OptionValueListInt>(array, array_type));
else if (array_type == "double") else if (array_type == "double")
AddOptionValue(ReadArray(array, array_type, &OptionValueListDouble::SetListDouble)); AddOptionValue(ReadArray<OptionValueListDouble>(array, array_type));
else if (array_type == "bool") else if (array_type == "bool")
AddOptionValue(ReadArray(array, array_type, &OptionValueListBool::SetListBool)); AddOptionValue(ReadArray<OptionValueListBool>(array, array_type));
else if (array_type == "color") else if (array_type == "color")
AddOptionValue(ReadArray(array, array_type, &OptionValueListColor::SetListColor)); AddOptionValue(ReadArray<OptionValueListColor>(array, array_type));
else else
Error<OptionJsonValueArray>("Array type not handled"); Error<OptionJsonValueArray>("Array type not handled");
} }

View File

@ -46,8 +46,8 @@ class ConfigVisitor final : public json::ConstVisitor {
template<class ErrorType> template<class ErrorType>
void Error(const char *message); void Error(const char *message);
template<class OptionValueType, class ValueType> template<class OptionValueType>
std::unique_ptr<OptionValue> ReadArray(json::Array const& src, std::string const& array_type, void (OptionValueType::*set_list)(const std::vector<ValueType>&)); std::unique_ptr<OptionValue> ReadArray(json::Array const& src, std::string const& array_type);
void AddOptionValue(std::unique_ptr<OptionValue>&& opt); void AddOptionValue(std::unique_ptr<OptionValue>&& opt);
public: public:

View File

@ -27,91 +27,119 @@ namespace agi {
DEFINE_BASE_EXCEPTION_NOINNER(OptionValueError, Exception) DEFINE_BASE_EXCEPTION_NOINNER(OptionValueError, Exception)
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorNotFound, OptionValueError, "options/not_found") DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorNotFound, OptionValueError, "options/not_found")
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidType, OptionValueError, "options/invalid_type") DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidType, OptionValueError, "options/invalid_type")
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidListType, OptionValueError, "options/array/invalid_type")
/// Option type
/// No bitsets here.
enum class OptionType {
String = 0, ///< String
Int = 1, ///< Integer
Double = 2, ///< Double
Color = 3, ///< Color
Bool = 4, ///< Bool
ListString = 100, ///< List of Strings
ListInt = 101, ///< List of Integers
ListDouble = 102, ///< List of Doubles
ListColor = 103, ///< List of Colors
ListBool = 104 ///< List of Bools
};
/// @class OptionValue /// @class OptionValue
/// Holds an actual option. /// Holds an actual option.
class OptionValue { class OptionValue {
agi::signal::Signal<OptionValue const&> ValueChanged; agi::signal::Signal<OptionValue const&> ValueChanged;
std::string name; std::string name;
std::string TypeToString(OptionType type) const {
switch (type) {
case OptionType::String: return "String";
case OptionType::Int: return "Integer";
case OptionType::Double: return "Double";
case OptionType::Color: return "Color";
case OptionType::Bool: return "Bool";
case OptionType::ListString: return "List of Strings";
case OptionType::ListInt: return "List of Integers";
case OptionType::ListDouble: return "List of Doubles";
case OptionType::ListColor: return "List of Colors";
case OptionType::ListBool: return "List of Bools";
}
throw agi::InternalError("Invalid option type", nullptr);
}
OptionValueErrorInvalidType TypeError(OptionType type) const {
return OptionValueErrorInvalidType("Invalid type for option " + name + ": expected " + TypeToString(type) + ", got " + TypeToString(GetType()));
}
template<typename T>
T *As(OptionType type) {
if (GetType() == type)
return static_cast<T *>(this);
throw TypeError(type);
}
template<typename T>
const T *As(OptionType type) const {
if (GetType() == type)
return static_cast<const T *>(this);
throw TypeError(type);
}
protected: protected:
void NotifyChanged() { ValueChanged(*this); } void NotifyChanged() { ValueChanged(*this); }
OptionValueErrorInvalidType TypeError(std::string type, std::string op = " retrieve ") const {
return OptionValueErrorInvalidType("Attempt to" + op + type + " with non-" + type + " value " + GetName());
}
OptionValueErrorInvalidListType ListTypeError(std::string type, std::string op = " retrieve ") const {
return OptionValueErrorInvalidListType("Attempt to" + op + type + " with non-" + type + " list " + GetName());
}
OptionValue(std::string name) : name(std::move(name)) { } OptionValue(std::string name) : name(std::move(name)) { }
public: public:
virtual ~OptionValue() {}; virtual ~OptionValue() {}
/// Option type
/// No bitsets here.
enum OptionType {
Type_String = 0, ///< String
Type_Int = 1, ///< Integer
Type_Double = 2, ///< Double
Type_Color = 3, ///< Color
Type_Bool = 4, ///< Bool
Type_List_String = 100, ///< List of Strings
Type_List_Int = 101, ///< List of Integers
Type_List_Double = 102, ///< List of Doubles
Type_List_Color = 103, ///< List of Colors
Type_List_Bool = 104 ///< List of Bools
};
std::string GetName() const { return name; } std::string GetName() const { return name; }
virtual OptionType GetType() const = 0; virtual OptionType GetType() const = 0;
virtual bool IsDefault() const = 0; virtual bool IsDefault() const = 0;
virtual void Reset() = 0; virtual void Reset() = 0;
virtual std::string GetString() const { throw TypeError("string"); } std::string const& GetString() const;
virtual int64_t GetInt() const { throw TypeError("int"); } int64_t const& GetInt() const;
virtual double GetDouble() const { throw TypeError("double"); } double const& GetDouble() const;
virtual Color GetColor() const { throw TypeError("color"); } Color const& GetColor() const;
virtual bool GetBool() const { throw TypeError("bool"); } bool const& GetBool() const;
virtual void SetString(const std::string) { throw TypeError("string", " set "); } void SetString(const std::string);
virtual void SetInt(const int64_t) { throw TypeError("int", " set "); } void SetInt(const int64_t);
virtual void SetDouble(const double) { throw TypeError("double", " set "); } void SetDouble(const double);
virtual void SetColor(const Color) { throw TypeError("color", " set "); } void SetColor(const Color);
virtual void SetBool(const bool) { throw TypeError("bool", " set "); } void SetBool(const bool);
virtual std::vector<std::string> const& GetListString() const { throw ListTypeError("string"); } std::vector<std::string> const& GetListString() const;
virtual std::vector<int64_t> const& GetListInt() const { throw ListTypeError("int"); } std::vector<int64_t> const& GetListInt() const;
virtual std::vector<double> const& GetListDouble() const { throw ListTypeError("double"); } std::vector<double> const& GetListDouble() const;
virtual std::vector<Color> const& GetListColor() const { throw ListTypeError("color"); } std::vector<Color> const& GetListColor() const;
virtual std::vector<bool> const& GetListBool() const { throw ListTypeError("string"); } std::vector<bool> const& GetListBool() const;
virtual void SetListString(const std::vector<std::string>&) { throw ListTypeError("string", " set "); } void SetListString(std::vector<std::string>);
virtual void SetListInt(const std::vector<int64_t>&) { throw ListTypeError("int", " set "); } void SetListInt(std::vector<int64_t>);
virtual void SetListDouble(const std::vector<double>&) { throw ListTypeError("double", " set "); } void SetListDouble(std::vector<double>);
virtual void SetListColor(const std::vector<Color>&) { throw ListTypeError("color", " set "); } void SetListColor(std::vector<Color>);
virtual void SetListBool(const std::vector<bool>&) { throw ListTypeError("string", " set "); } void SetListBool(std::vector<bool>);
virtual void Set(const OptionValue *new_value)=0; virtual void Set(const OptionValue *new_value)=0;
DEFINE_SIGNAL_ADDERS(ValueChanged, Subscribe) DEFINE_SIGNAL_ADDERS(ValueChanged, Subscribe)
}; };
#define CONFIG_OPTIONVALUE(type_name, type) \ #define CONFIG_OPTIONVALUE(type_name, type) \
class OptionValue##type_name final : public OptionValue { \ class OptionValue##type_name final : public OptionValue { \
type value; \ type value; \
type value_default; \ type value_default; \
public: \ public: \
OptionValue##type_name(std::string member_name, type member_value) \ typedef type value_type; \
: OptionValue(std::move(member_name)) \ OptionValue##type_name(std::string member_name, type member_value) \
, value(member_value), value_default(member_value) { } \ : OptionValue(std::move(member_name)) \
type Get##type_name() const { return value; } \ , value(member_value), value_default(member_value) { } \
void Set##type_name(const type new_val) { value = new_val; NotifyChanged(); } \ type const& GetValue() const { return value; } \
OptionType GetType() const { return OptionValue::Type_##type_name; } \ void SetValue(type new_val) { value = std::move(new_val); NotifyChanged(); } \
void Reset() { value = value_default; NotifyChanged(); } \ OptionType GetType() const { return OptionType::type_name; } \
bool IsDefault() const { return value == value_default; } \ void Reset() { value = value_default; NotifyChanged(); } \
void Set(const OptionValue *new_val) { Set##type_name(new_val->Get##type_name()); } \ bool IsDefault() const { return value == value_default; } \
void Set(const OptionValue *new_val) { SetValue(new_val->Get##type_name()); } \
}; };
CONFIG_OPTIONVALUE(String, std::string) CONFIG_OPTIONVALUE(String, std::string)
@ -120,21 +148,22 @@ CONFIG_OPTIONVALUE(Double, double)
CONFIG_OPTIONVALUE(Color, Color) CONFIG_OPTIONVALUE(Color, Color)
CONFIG_OPTIONVALUE(Bool, bool) CONFIG_OPTIONVALUE(Bool, bool)
#define CONFIG_OPTIONVALUE_LIST(type_name, type) \ #define CONFIG_OPTIONVALUE_LIST(type_name, type) \
class OptionValueList##type_name final : public OptionValue { \ class OptionValueList##type_name final : public OptionValue { \
std::vector<type> array; \ std::vector<type> array; \
std::vector<type> array_default; \ std::vector<type> array_default; \
std::string name; \ std::string name; \
public: \ public: \
typedef std::vector<type> value_type; \
OptionValueList##type_name(std::string name, std::vector<type> const& value = std::vector<type>()) \ OptionValueList##type_name(std::string name, std::vector<type> const& value = std::vector<type>()) \
: OptionValue(std::move(name)) \ : OptionValue(std::move(name)) \
, array(value), array_default(value) { } \ , array(value), array_default(value) { } \
std::vector<type> const& GetList##type_name() const { return array; } \ std::vector<type> const& GetValue() const { return array; } \
void SetList##type_name(const std::vector<type>& val) { array = val; NotifyChanged(); } \ void SetValue(std::vector<type> val) { array = std::move(val); NotifyChanged(); } \
OptionType GetType() const { return OptionValue::Type_List_##type_name; } \ OptionType GetType() const { return OptionType::List##type_name; } \
void Reset() { array = array_default; NotifyChanged(); } \ void Reset() { array = array_default; NotifyChanged(); } \
bool IsDefault() const { return array == array_default; } \ bool IsDefault() const { return array == array_default; } \
void Set(const OptionValue *nv) { SetList##type_name(nv->GetList##type_name()); } \ void Set(const OptionValue *nv) { SetValue(nv->GetList##type_name()); } \
}; };
CONFIG_OPTIONVALUE_LIST(String, std::string) CONFIG_OPTIONVALUE_LIST(String, std::string)
@ -143,4 +172,22 @@ CONFIG_OPTIONVALUE_LIST(Double, double)
CONFIG_OPTIONVALUE_LIST(Color, Color) CONFIG_OPTIONVALUE_LIST(Color, Color)
CONFIG_OPTIONVALUE_LIST(Bool, bool) CONFIG_OPTIONVALUE_LIST(Bool, bool)
#define CONFIG_OPTIONVALUE_ACCESSORS(ReturnType, Type) \
inline ReturnType const& OptionValue::Get##Type() const { return As<OptionValue##Type>(OptionType::Type)->GetValue(); } \
inline void OptionValue::Set##Type(ReturnType v) { As<OptionValue##Type>(OptionType::Type)->SetValue(std::move(v)); }
CONFIG_OPTIONVALUE_ACCESSORS(std::string, String)
CONFIG_OPTIONVALUE_ACCESSORS(int64_t, Int)
CONFIG_OPTIONVALUE_ACCESSORS(double, Double)
CONFIG_OPTIONVALUE_ACCESSORS(Color, Color)
CONFIG_OPTIONVALUE_ACCESSORS(bool, Bool)
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<std::string>, ListString)
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<int64_t>, ListInt)
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<double>, ListDouble)
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<Color>, ListColor)
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<bool>, ListBool)
#undef CONFIG_OPTIONVALUE
#undef CONFIG_OPTIONVALUE_LIST
#undef CONFIG_OPTIONVALUE_ACCESSORS
} // namespace agi } // namespace agi

View File

@ -176,8 +176,7 @@ void BaseGrid::OnShowColMenu(wxCommandEvent &event) {
int item = event.GetId() - MENU_SHOW_COL; int item = event.GetId() - MENU_SHOW_COL;
showCol[item] = !showCol[item]; showCol[item] = !showCol[item];
std::vector<bool> map(std::begin(showCol), std::end(showCol)); OPT_SET("Subtitle/Grid/Column")->SetListBool(std::vector<bool>(std::begin(showCol), std::end(showCol)));
OPT_SET("Subtitle/Grid/Column")->SetListBool(map);
SetColumnWidths(); SetColumnWidths();
Refresh(false); Refresh(false);

View File

@ -106,7 +106,7 @@ void DialogPasteOver::OnOK(wxCommandEvent &) {
std::vector<bool> options; std::vector<bool> options;
for (size_t i = 0; i < ListBox->GetCount(); ++i) for (size_t i = 0; i < ListBox->GetCount(); ++i)
options.push_back(ListBox->IsChecked(i)); options.push_back(ListBox->IsChecked(i));
OPT_SET("Tool/Paste Lines Over/Fields")->SetListBool(options); OPT_SET("Tool/Paste Lines Over/Fields")->SetListBool(std::move(options));
EndModal(0); EndModal(0);
} }

View File

@ -117,7 +117,7 @@ void init() {
migrations.emplace_back("duplicate -> split"); migrations.emplace_back("duplicate -> split");
} }
OPT_SET("App/Hotkey Migrations")->SetListString(migrations); OPT_SET("App/Hotkey Migrations")->SetListString(std::move(migrations));
} }
void clear() { void clear() {

View File

@ -117,7 +117,7 @@ wxControl *OptionPage::OptionAdd(wxFlexGridSizer *flex, const wxString &name, co
const agi::OptionValue *opt = OPT_GET(opt_name); const agi::OptionValue *opt = OPT_GET(opt_name);
switch (opt->GetType()) { switch (opt->GetType()) {
case agi::OptionValue::Type_Bool: { case agi::OptionType::Bool: {
wxCheckBox *cb = new wxCheckBox(this, -1, name); wxCheckBox *cb = new wxCheckBox(this, -1, name);
flex->Add(cb, 1, wxEXPAND, 0); flex->Add(cb, 1, wxEXPAND, 0);
cb->SetValue(opt->GetBool()); cb->SetValue(opt->GetBool());
@ -125,28 +125,28 @@ wxControl *OptionPage::OptionAdd(wxFlexGridSizer *flex, const wxString &name, co
return cb; return cb;
} }
case agi::OptionValue::Type_Int: { case agi::OptionType::Int: {
wxSpinCtrl *sc = new wxSpinCtrl(this, -1, std::to_wstring((int)opt->GetInt()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetInt()); wxSpinCtrl *sc = new wxSpinCtrl(this, -1, std::to_wstring((int)opt->GetInt()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetInt());
sc->Bind(wxEVT_SPINCTRL, IntUpdater(opt_name, parent)); sc->Bind(wxEVT_SPINCTRL, IntUpdater(opt_name, parent));
Add(flex, name, sc); Add(flex, name, sc);
return sc; return sc;
} }
case agi::OptionValue::Type_Double: { case agi::OptionType::Double: {
wxSpinCtrlDouble *scd = new wxSpinCtrlDouble(this, -1, wxString::Format("%g", opt->GetDouble()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetDouble(), inc); wxSpinCtrlDouble *scd = new wxSpinCtrlDouble(this, -1, wxString::Format("%g", opt->GetDouble()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetDouble(), inc);
scd->Bind(wxEVT_SPINCTRL, DoubleUpdater(opt_name, parent)); scd->Bind(wxEVT_SPINCTRL, DoubleUpdater(opt_name, parent));
Add(flex, name, scd); Add(flex, name, scd);
return scd; return scd;
} }
case agi::OptionValue::Type_String: { case agi::OptionType::String: {
wxTextCtrl *text = new wxTextCtrl(this, -1 , to_wx(opt->GetString())); wxTextCtrl *text = new wxTextCtrl(this, -1 , to_wx(opt->GetString()));
text->Bind(wxEVT_TEXT, StringUpdater(opt_name, parent)); text->Bind(wxEVT_TEXT, StringUpdater(opt_name, parent));
Add(flex, name, text); Add(flex, name, text);
return text; return text;
} }
case agi::OptionValue::Type_Color: { case agi::OptionType::Color: {
auto cb = new ColourButton(this, wxSize(40,10), false, opt->GetColor()); auto cb = new ColourButton(this, wxSize(40,10), false, opt->GetColor());
cb->Bind(EVT_COLOR, ColourUpdater(opt_name, parent)); cb->Bind(EVT_COLOR, ColourUpdater(opt_name, parent));
Add(flex, name, cb); Add(flex, name, cb);
@ -166,13 +166,13 @@ void OptionPage::OptionChoice(wxFlexGridSizer *flex, const wxString &name, const
Add(flex, name, cb); Add(flex, name, cb);
switch (opt->GetType()) { switch (opt->GetType()) {
case agi::OptionValue::Type_Int: { case agi::OptionType::Int: {
int val = opt->GetInt(); int val = opt->GetInt();
cb->Select(val < (int)choices.size() ? val : 0); cb->Select(val < (int)choices.size() ? val : 0);
cb->Bind(wxEVT_COMBOBOX, IntCBUpdater(opt_name, parent)); cb->Bind(wxEVT_COMBOBOX, IntCBUpdater(opt_name, parent));
break; break;
} }
case agi::OptionValue::Type_String: { case agi::OptionType::String: {
wxString val(to_wx(opt->GetString())); wxString val(to_wx(opt->GetString()));
if (cb->FindString(val) != wxNOT_FOUND) if (cb->FindString(val) != wxNOT_FOUND)
cb->SetStringSelection(val); cb->SetStringSelection(val);
@ -201,8 +201,8 @@ void OptionPage::OptionBrowse(wxFlexGridSizer *flex, const wxString &name, const
parent->AddChangeableOption(opt_name); parent->AddChangeableOption(opt_name);
const agi::OptionValue *opt = OPT_GET(opt_name); const agi::OptionValue *opt = OPT_GET(opt_name);
if (opt->GetType() != agi::OptionValue::Type_String) if (opt->GetType() != agi::OptionType::String)
throw PreferenceIncorrectType("Option must be agi::OptionValue::Type_String for BrowseButton."); throw PreferenceIncorrectType("Option must be agi::OptionType::String for BrowseButton.");
wxTextCtrl *text = new wxTextCtrl(this, -1 , to_wx(opt->GetString())); wxTextCtrl *text = new wxTextCtrl(this, -1 , to_wx(opt->GetString()));
text->SetMinSize(wxSize(160, -1)); text->SetMinSize(wxSize(160, -1));

View File

@ -200,7 +200,7 @@ void SubsTextEditCtrl::SetSyntaxStyle(int id, wxFont &font, std::string const& n
StyleSetBold(id, OPT_GET("Colour/Subtitle/Syntax/Bold/" + name)->GetBool()); StyleSetBold(id, OPT_GET("Colour/Subtitle/Syntax/Bold/" + name)->GetBool());
StyleSetForeground(id, to_wx(OPT_GET("Colour/Subtitle/Syntax/" + name)->GetColor())); StyleSetForeground(id, to_wx(OPT_GET("Colour/Subtitle/Syntax/" + name)->GetColor()));
const agi::OptionValue *background = OPT_GET("Colour/Subtitle/Syntax/Background/" + name); const agi::OptionValue *background = OPT_GET("Colour/Subtitle/Syntax/Background/" + name);
if (background->GetType() == agi::OptionValue::Type_Color) if (background->GetType() == agi::OptionType::Color)
StyleSetBackground(id, to_wx(background->GetColor())); StyleSetBackground(id, to_wx(background->GetColor()));
} }

View File

@ -212,50 +212,50 @@ TEST_F(lagi_option, empty_array_decays_to_first_used_type) {
empty_arr_options opt; empty_arr_options opt;
EXPECT_NO_THROW(opt.Get("arr")->GetListBool()); EXPECT_NO_THROW(opt.Get("arr")->GetListBool());
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidType);
} }
{ {
empty_arr_options opt; empty_arr_options opt;
EXPECT_NO_THROW(opt.Get("arr")->GetListColor()); EXPECT_NO_THROW(opt.Get("arr")->GetListColor());
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidType);
} }
{ {
empty_arr_options opt; empty_arr_options opt;
EXPECT_NO_THROW(opt.Get("arr")->GetListDouble()); EXPECT_NO_THROW(opt.Get("arr")->GetListDouble());
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidType);
} }
{ {
empty_arr_options opt; empty_arr_options opt;
EXPECT_NO_THROW(opt.Get("arr")->GetListInt()); EXPECT_NO_THROW(opt.Get("arr")->GetListInt());
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidType);
} }
{ {
empty_arr_options opt; empty_arr_options opt;
EXPECT_NO_THROW(opt.Get("arr")->GetListString()); EXPECT_NO_THROW(opt.Get("arr")->GetListString());
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidType);
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidListType); EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidType);
} }
} }