diff --git a/aegisub/build/Aegisub/Aegisub.vcxproj b/aegisub/build/Aegisub/Aegisub.vcxproj index e0a060076..35a522f99 100644 --- a/aegisub/build/Aegisub/Aegisub.vcxproj +++ b/aegisub/build/Aegisub/Aegisub.vcxproj @@ -232,7 +232,6 @@ - @@ -426,7 +425,6 @@ - diff --git a/aegisub/build/Aegisub/Aegisub.vcxproj.filters b/aegisub/build/Aegisub/Aegisub.vcxproj.filters index ef0128fb1..86e99171d 100644 --- a/aegisub/build/Aegisub/Aegisub.vcxproj.filters +++ b/aegisub/build/Aegisub/Aegisub.vcxproj.filters @@ -630,9 +630,6 @@ Utilities - - Utilities - Features\Help @@ -1179,9 +1176,6 @@ Utilities - - Utilities - Features\Help @@ -1245,4 +1239,4 @@ Resources - \ No newline at end of file + diff --git a/aegisub/src/Makefile b/aegisub/src/Makefile index fbc6c1da1..632a0c624 100644 --- a/aegisub/src/Makefile +++ b/aegisub/src/Makefile @@ -245,7 +245,6 @@ SRC += \ tooltip_manager.cpp \ utils.cpp \ validators.cpp \ - variable_data.cpp \ vector2d.cpp \ version.cpp \ video_box.cpp \ diff --git a/aegisub/src/ass_override.cpp b/aegisub/src/ass_override.cpp index 7621b5735..dfcda5916 100644 --- a/aegisub/src/ass_override.cpp +++ b/aegisub/src/ass_override.cpp @@ -39,6 +39,7 @@ #include "ass_dialogue.h" #include "ass_override.h" +#include "compat.h" #include "utils.h" #include @@ -50,6 +51,84 @@ using namespace boost::adaptors; +AssOverrideParameter::AssOverrideParameter(VariableDataType type, AssParameterClass classification) +: type(type) +, classification(classification) +{ +} + +AssOverrideParameter::AssOverrideParameter(AssOverrideParameter&& o) +: value(std::move(o.value)) +, block(std::move(o.block)) +, type(o.type) +, classification(o.classification) +{ +} + +AssOverrideParameter::~AssOverrideParameter() { +} + +template<> wxString AssOverrideParameter::Get() const { + if (omitted) throw agi::InternalError("AssOverrideParameter::Get() called on omitted parameter", 0); + if (block.get()) { + wxString str(block->GetText()); + str.Replace("{", ""); + str.Replace("}", ""); + return str; + } + return value; +} + +template<> int AssOverrideParameter::Get() const { + long v = 0; + Get().ToLong(&v); + return v; +} + +template<> double AssOverrideParameter::Get() const { + double v = 0; + Get().ToDouble(&v); + return v; +} + +template<> float AssOverrideParameter::Get() const { + return Get(); +} + +template<> bool AssOverrideParameter::Get() const { + return Get() != 0; +} + +template<> agi::Color AssOverrideParameter::Get() const { + return from_wx(Get()); +} + +template<> AssDialogueBlockOverride *AssOverrideParameter::Get() const { + if (!block.get()) { + block.reset(new AssDialogueBlockOverride(Get())); + block->ParseTags(); + } + return block.get(); +} + +template<> void AssOverrideParameter::Set(wxString new_value) { + omitted = false; + value = new_value; + block.reset(); +} + +template<> void AssOverrideParameter::Set(int new_value) { + Set(wxString::Format("%d", new_value)); +} + +template<> void AssOverrideParameter::Set(double new_value) { + Set(wxString::Format("%g", new_value)); +} + +template<> void AssOverrideParameter::Set(bool new_value) { + Set(new_value); +} + namespace { /// The parameter is absent unless the total number of parameters is the /// indicated number. Note that only arguments not at the end need to be marked @@ -324,75 +403,19 @@ void parse_parameters(AssOverrideTag *tag, const wxString &text, AssOverrideTagP unsigned curPar = 0; for (auto& curproto : proto_it->params) { // Create parameter - tag->Params.emplace_back(); + tag->Params.emplace_back(curproto.type, curproto.classification); AssOverrideParameter *newparam = &tag->Params.back(); - newparam->classification = curproto.classification; // Check if it's optional and not present if (!(curproto.optional & parsFlag) || curPar >= totalPars) continue; - wxString curtok = paramList[curPar++]; - - if (curtok.empty()) { - curPar++; - continue; - } - - wxChar firstChar = curtok[0]; - bool auto4 = (firstChar == '!' || firstChar == '$' || firstChar == '%') && curproto.type != VARDATA_BLOCK; - if (auto4) { - newparam->Set(curtok); - continue; - } - - switch (curproto.type) { - case VARDATA_INT: { - long temp; - curtok.ToLong(&temp); - newparam->Set(temp); - break; - } - case VARDATA_FLOAT: { - double temp; - curtok.ToDouble(&temp); - newparam->Set(temp); - break; - } - case VARDATA_TEXT: - newparam->Set(curtok); - break; - case VARDATA_BOOL: { - long temp; - curtok.ToLong(&temp); - newparam->Set(temp != 0); - break; - } - case VARDATA_BLOCK: { - AssDialogueBlockOverride *temp = new AssDialogueBlockOverride(curtok); - temp->ParseTags(); - newparam->Set(temp); - break; - } - default: - break; - } + tag->Params.back().Set(paramList[curPar++]); } } } -AssOverrideParameter::AssOverrideParameter() -: classification(PARCLASS_NORMAL) -{ -} - -AssOverrideParameter::AssOverrideParameter(AssOverrideParameter&& o) -: VariableData(std::move(o)) -, classification(o.classification) -{ -} - // From ass_dialogue.h AssDialogueBlockOverride::~AssDialogueBlockOverride() { delete_clear(Tags); @@ -409,9 +432,8 @@ void AssDialogueBlockOverride::ParseTags() { curTag += tkn.GetNextToken(); // Check for parenthesis matching for \t - while (curTag.Freq('(') > curTag.Freq(')') && tkn.HasMoreTokens()) { + while (curTag.Freq('(') > curTag.Freq(')') && tkn.HasMoreTokens()) curTag << "\\" << tkn.GetNextToken(); - } Tags.push_back(new AssOverrideTag(curTag)); @@ -431,7 +453,7 @@ wxString AssDialogueBlockOverride::GetText() { void AssDialogueBlockOverride::ProcessParameters(ProcessParametersCallback callback, void *userData) { for (auto tag : Tags) { for (auto& par : tag->Params) { - if (par.GetType() == VARDATA_NONE) continue; + if (par.omitted) continue; callback(tag->Name, &par, userData); @@ -478,7 +500,7 @@ AssOverrideTag::operator wxString() const { // Add parameters result += join(Params - | filtered([](AssOverrideParameter const& p) { return p.GetType() != VARDATA_NONE; }) + | filtered([](AssOverrideParameter const& p) { return !p.omitted; } ) | transformed(param_str), wxS(",")); diff --git a/aegisub/src/ass_override.h b/aegisub/src/ass_override.h index feccb11b7..faad0f76b 100644 --- a/aegisub/src/ass_override.h +++ b/aegisub/src/ass_override.h @@ -32,9 +32,12 @@ /// @ingroup subs_storage /// +#include +#include #include -#include "variable_data.h" +class AssDialogueBlockOverride; +class wxString; /// Type of parameter; probably only used by the resample tool enum AssParameterClass { @@ -50,15 +53,37 @@ enum AssParameterClass { PARCLASS_DRAWING }; +enum VariableDataType { + VARDATA_INT, + VARDATA_FLOAT, + VARDATA_TEXT, + VARDATA_BOOL, + VARDATA_BLOCK +}; + /// A single parameter to an override tag -class AssOverrideParameter : public VariableData { +class AssOverrideParameter : boost::noncopyable { + wxString value; + mutable std::unique_ptr block; + VariableDataType type; + public: + AssOverrideParameter(VariableDataType type, AssParameterClass classification); AssOverrideParameter(AssOverrideParameter&&); + ~AssOverrideParameter(); /// Type of parameter AssParameterClass classification; - AssOverrideParameter(); + /// Is this parameter actually present? + bool omitted; + + VariableDataType GetType() const { return type; } + template void Set(T param); + template T Get() const; + template T Get(T def) const { + return !omitted ? Get() : def; + } }; class AssOverrideTag : boost::noncopyable { diff --git a/aegisub/src/subtitle_format_ebu3264.cpp b/aegisub/src/subtitle_format_ebu3264.cpp index 8065625d8..d63565118 100644 --- a/aegisub/src/subtitle_format_ebu3264.cpp +++ b/aegisub/src/subtitle_format_ebu3264.cpp @@ -130,7 +130,7 @@ namespace italic = t->Params[0].Get(style_italic); else if (t->Name == "\\an") align = t->Params[0].Get(align); - else if (t->Name == "\\a" && t->Params[0].GetType() != VARDATA_NONE) + else if (t->Name == "\\a" && !t->Params[0].omitted) align = AssStyle::SsaToAss(t->Params[0].Get()); } } diff --git a/aegisub/src/variable_data.cpp b/aegisub/src/variable_data.cpp deleted file mode 100644 index eb125685e..000000000 --- a/aegisub/src/variable_data.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) 2005, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Aegisub Project http://www.aegisub.org/ - -/// @file variable_data.cpp -/// @brief A variant-type implementation -/// @ingroup utility subs_storage - -#include "config.h" - -#include "variable_data.h" - -#include "ass_dialogue.h" -#include "ass_style.h" -#include "compat.h" -#include "utils.h" - -#include - -VariableData::VariableData() { - type = VARDATA_NONE; - value = nullptr; -} - -VariableData::VariableData(VariableData&& o) -: value(o.value) -, type(o.type) -{ -} - -VariableData::~VariableData() { - DeleteValue(); -} - -void VariableData::DeleteValue() { - if (!value) return; - if (type == VARDATA_NONE) return; - switch (type) { - case VARDATA_INT: delete value_int; break; - case VARDATA_FLOAT: delete value_float; break; - case VARDATA_TEXT: delete value_text; break; - case VARDATA_BOOL: delete value_bool; break; - case VARDATA_COLOUR: delete value_colour; break; - case VARDATA_BLOCK: delete *value_block; delete value_block; break; - default: break; - } - type = VARDATA_NONE; - value = nullptr; -} - -template static inline VariableDataType get_type(); - -template<> inline VariableDataType get_type() { - return VARDATA_INT; -} -template<> inline VariableDataType get_type() { - return VARDATA_FLOAT; -} -template<> inline VariableDataType get_type() { - return VARDATA_FLOAT; -} -template<> inline VariableDataType get_type() { - return VARDATA_BOOL; -} -template<> inline VariableDataType get_type() { - return VARDATA_TEXT; -} -template<> inline VariableDataType get_type() { - return VARDATA_COLOUR; -} -template<> inline VariableDataType get_type() { - return VARDATA_BLOCK; -} - -template -void VariableData::Set(T param) { - DeleteValue(); - type = get_type(); - value = new T(param); -} -template void VariableData::Set(int param); -template void VariableData::Set(float param); -template void VariableData::Set(double param); -template void VariableData::Set(bool param); -template void VariableData::Set(wxString param); -template void VariableData::Set(agi::Color param); -template void VariableData::Set(AssDialogueBlockOverride * param); - -template<> int VariableData::Get() const { - if (!value) throw "Null parameter"; - if (type == VARDATA_BOOL) return !!(*value_bool); - if (type == VARDATA_INT) return *value_int; - if (type == VARDATA_FLOAT) return (int)(*value_float); - if (type == VARDATA_TEXT) return 0; - throw "Wrong parameter type, should be int"; -} - -template<> float VariableData::Get() const { - if (!value) throw "Null parameter"; - if (type == VARDATA_FLOAT) return (float)*value_float; - if (type == VARDATA_INT) return (float)(*value_int); - if (type == VARDATA_TEXT) return 0.0f; - throw "Wrong parameter type, should be float"; -} -template<> double VariableData::Get() const { - if (!value) throw "Null parameter"; - if (type == VARDATA_FLOAT) return *value_float; - if (type == VARDATA_INT) return (float)(*value_int); - if (type == VARDATA_TEXT) return 0.0; - throw "Wrong parameter type, should be float"; -} - -template<> bool VariableData::Get() const { - if (!value) throw "Null parameter"; - if (type == VARDATA_BOOL) return *value_bool; - if (type == VARDATA_INT) return ((*value_int)!=0); - if (type == VARDATA_FLOAT) return ((*value_float)!=0); - if (type == VARDATA_TEXT) return false; - throw "Wrong parameter type, should be bool"; -} - -template<> agi::Color VariableData::Get() const { - if (!value) throw "Null parameter"; - if (type == VARDATA_COLOUR) return *value_colour; - else if (type == VARDATA_TEXT) { - return agi::Color(from_wx(*value_text)); - } - else throw "Wrong parameter type, should be colour"; -} - -template<> AssDialogueBlockOverride *VariableData::Get() const { - if (!value) throw "Null parameter"; - if (type != VARDATA_BLOCK) throw "Wrong parameter type, should be block"; - return *value_block; -} - -template<> wxString VariableData::Get() const { - if (!value) throw "Null parameter"; - if (type != VARDATA_TEXT) { - if (type == VARDATA_INT) return wxString::Format("%i",*value_int); - if (type == VARDATA_FLOAT) return wxString::Format("%g",*value_float); - if (type == VARDATA_COLOUR) return to_wx(value_colour->GetHexFormatted()); - if (type == VARDATA_BOOL) return *value_bool ? "1" : "0"; - if (type == VARDATA_BLOCK) { - wxString str((*value_block)->GetText()); - str.Replace("{", ""); - str.Replace("}", ""); - return str; - } - throw "Wrong parameter type, should be text"; - } - return *value_text; -} diff --git a/aegisub/src/variable_data.h b/aegisub/src/variable_data.h deleted file mode 100644 index fcbc9d08f..000000000 --- a/aegisub/src/variable_data.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2005, Rodrigo Braz Monteiro -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the Aegisub Group nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Aegisub Project http://www.aegisub.org/ - -/// @file variable_data.h -/// @see variable_data.cpp -/// @ingroup utility subs_storage -/// - -#pragma once - -#include - -namespace agi { struct Color; } -class wxString; - -enum VariableDataType { - VARDATA_NONE, - VARDATA_INT, - VARDATA_FLOAT, - VARDATA_TEXT, - VARDATA_BOOL, - VARDATA_COLOUR, - VARDATA_BLOCK -}; - -class AssDialogueBlockOverride; - -class VariableData : private boost::noncopyable { -private: - union { - void *value; - int *value_int; - double *value_float; - bool *value_bool; - wxString *value_text; - agi::Color *value_colour; - AssDialogueBlockOverride **value_block; - }; - - VariableDataType type; - -protected: - void DeleteValue(); - -public: - VariableData(); - VariableData(VariableData&& o); - virtual ~VariableData(); - - VariableDataType GetType() const { return type; } - template void Set(T param); - template T Get() const; - template T Get(T def) const { - return value ? Get() : def; - } -}; diff --git a/aegisub/src/visual_tool.cpp b/aegisub/src/visual_tool.cpp index 388773ef2..2058f3362 100644 --- a/aegisub/src/visual_tool.cpp +++ b/aegisub/src/visual_tool.cpp @@ -373,7 +373,7 @@ static param_vec find_tag(boost::ptr_vector& blocks, wxString static Vector2D vec_or_bad(param_vec tag, size_t x_idx, size_t y_idx) { if (!tag || tag->size() <= x_idx || tag->size() <= y_idx || - (*tag)[x_idx].GetType() == VARDATA_NONE || (*tag)[y_idx].GetType() == VARDATA_NONE) + (*tag)[x_idx].omitted || (*tag)[y_idx].omitted) { return Vector2D(); } @@ -401,8 +401,8 @@ Vector2D VisualToolBase::GetLinePosition(AssDialogue *diag) { param_vec align_tag; int ovr_align = 0; - if ((align_tag = find_tag(blocks, "\\an")) && (*align_tag)[0].GetType() != VARDATA_NONE) - ovr_align = (*align_tag)[0].Get(); + if ((align_tag = find_tag(blocks, "\\an"))) + ovr_align = (*align_tag)[0].Get(ovr_align); else if ((align_tag = find_tag(blocks, "\\a"))) ovr_align = AssStyle::SsaToAss((*align_tag)[0].Get(2)); @@ -462,13 +462,13 @@ void VisualToolBase::GetLineRotation(AssDialogue *diag, float &rx, float &ry, fl boost::ptr_vector blocks(diag->ParseTags()); if (param_vec tag = find_tag(blocks, "\\frx")) - rx = tag->front().Get(rx); + rx = tag->front().Get(rx); if (param_vec tag = find_tag(blocks, "\\fry")) - ry = tag->front().Get(ry); + ry = tag->front().Get(ry); if (param_vec tag = find_tag(blocks, "\\frz")) - rz = tag->front().Get(rz); + rz = tag->front().Get(rz); else if ((tag = find_tag(blocks, "\\fr"))) - rz = tag->front().Get(rz); + rz = tag->front().Get(rz); } void VisualToolBase::GetLineScale(AssDialogue *diag, Vector2D &scale) { @@ -482,9 +482,9 @@ void VisualToolBase::GetLineScale(AssDialogue *diag, Vector2D &scale) { boost::ptr_vector blocks(diag->ParseTags()); if (param_vec tag = find_tag(blocks, "\\fscx")) - x = tag->front().Get(x); + x = tag->front().Get(x); if (param_vec tag = find_tag(blocks, "\\fscy")) - y = tag->front().Get(y); + y = tag->front().Get(y); scale = Vector2D(x, y); }