Eliminate uses of dynamic_cast on everything but GUI widgets

This commit is contained in:
Thomas Goyne 2014-12-26 08:51:14 -08:00
parent 6d74f22e92
commit 76afcdafa1
7 changed files with 52 additions and 33 deletions

View file

@ -30,19 +30,19 @@ namespace agi {
typedef Type *result_type; typedef Type *result_type;
template<class InType> Type *operator()(InType &ptr) const { template<class InType> Type *operator()(InType &ptr) const {
return dynamic_cast<Type *>(&ptr); return typeid(ptr) == typeid(Type) ? static_cast<Type*>(&ptr) : nullptr;
} }
template<class InType> Type *operator()(std::unique_ptr<InType>& ptr) const { template<class InType> Type *operator()(std::unique_ptr<InType>& ptr) const {
return dynamic_cast<Type *>(ptr.get()); return (*this)(*ptr);
} }
template<class InType> Type *operator()(std::unique_ptr<InType> const& ptr) const { template<class InType> Type *operator()(std::unique_ptr<InType> const& ptr) const {
return dynamic_cast<Type *>(ptr.get()); return (*this)(*ptr);
} }
template<class InType> Type *operator()(InType *ptr) const { template<class InType> Type *operator()(InType *ptr) const {
return dynamic_cast<Type *>(ptr); return (*this)(*ptr);
} }
}; };

View file

@ -91,15 +91,18 @@ void AssKaraoke::ParseSyllables(AssDialogue *line, Syllable &syl) {
for (auto& block : line->ParseTags()) { for (auto& block : line->ParseTags()) {
std::string text = block->GetText(); std::string text = block->GetText();
if (dynamic_cast<AssDialogueBlockPlain*>(block.get())) switch (block->GetType()) {
case AssBlockType::PLAIN:
syl.text += text; syl.text += text;
else if (dynamic_cast<AssDialogueBlockComment*>(block.get())) break;
case AssBlockType::COMMENT:
// drawings aren't override tags but they shouldn't show up in the
// stripped text so pretend they are
case AssBlockType::DRAWING:
syl.ovr_tags[syl.text.size()] += text; syl.ovr_tags[syl.text.size()] += text;
else if (dynamic_cast<AssDialogueBlockDrawing*>(block.get())) break;
// drawings aren't override tags but they shouldn't show up in the case AssBlockType::OVERRIDE:
// stripped text so pretend they are auto ovr = static_cast<AssDialogueBlockOverride*>(block.get());
syl.ovr_tags[syl.text.size()] += text;
else if (AssDialogueBlockOverride *ovr = dynamic_cast<AssDialogueBlockOverride*>(block.get())) {
bool in_tag = false; bool in_tag = false;
for (auto& tag : ovr->Tags) { for (auto& tag : ovr->Tags) {
if (tag.IsValid() && boost::istarts_with(tag.Name, "\\k")) { if (tag.IsValid() && boost::istarts_with(tag.Name, "\\k")) {
@ -137,6 +140,7 @@ void AssKaraoke::ParseSyllables(AssDialogue *line, Syllable &syl) {
if (in_tag) if (in_tag)
syl.ovr_tags[syl.text.size()] += "}"; syl.ovr_tags[syl.text.size()] += "}";
break;
} }
} }

View file

@ -237,13 +237,13 @@ namespace {
lua_pushvalue(L, 1); lua_pushvalue(L, 1);
std::unique_ptr<AssEntry> et(Automation4::LuaAssFile::LuaToAssEntry(L)); std::unique_ptr<AssEntry> et(Automation4::LuaAssFile::LuaToAssEntry(L));
auto st = dynamic_cast<AssStyle*>(et.get());
lua_pop(L, 1); lua_pop(L, 1);
if (!st) if (typeid(*et) != typeid(AssStyle))
return error(L, "Not a style entry"); return error(L, "Not a style entry");
double width, height, descent, extlead; double width, height, descent, extlead;
if (!Automation4::CalculateTextExtents(st, check_string(L, 2), width, height, descent, extlead)) if (!Automation4::CalculateTextExtents(static_cast<AssStyle*>(et.get()),
check_string(L, 2), width, height, descent, extlead))
return error(L, "Some internal error occurred calculating text_extents"); return error(L, "Some internal error occurred calculating text_extents");
push_value(L, width); push_value(L, width);
@ -788,12 +788,12 @@ namespace {
throw LuaForEachBreak(); throw LuaForEachBreak();
} }
auto diag = dynamic_cast<AssDialogue*>(lines[cur - 1]); if (typeid(*lines[cur - 1]) != typeid(AssDialogue)) {
if (!diag) {
wxLogError("Selected row %d is not a dialogue line", cur); wxLogError("Selected row %d is not a dialogue line", cur);
throw LuaForEachBreak(); throw LuaForEachBreak();
} }
auto diag = static_cast<AssDialogue*>(lines[cur - 1]);
sel.insert(diag); sel.insert(diag);
if (!active_line || active_idx == cur) if (!active_line || active_idx == cur)
active_line = diag; active_line = diag;

View file

@ -123,6 +123,11 @@ namespace {
default: return AssFile::COMMIT_SCRIPTINFO; default: return AssFile::COMMIT_SCRIPTINFO;
} }
} }
template<typename T, typename U>
T check_cast(U value) {
return typeid(T) == typeid(value) ? static_cast<T>(value) : nullptr;
}
} }
namespace Automation4 { namespace Automation4 {
@ -150,13 +155,13 @@ namespace Automation4 {
set_field(L, "section", e->GroupHeader()); set_field(L, "section", e->GroupHeader());
if (auto info = dynamic_cast<const AssInfo*>(e)) { if (auto info = check_cast<const AssInfo*>(e)) {
set_field(L, "raw", info->GetEntryData()); set_field(L, "raw", info->GetEntryData());
set_field(L, "key", info->Key()); set_field(L, "key", info->Key());
set_field(L, "value", info->Value()); set_field(L, "value", info->Value());
set_field(L, "class", "info"); set_field(L, "class", "info");
} }
else if (auto dia = dynamic_cast<const AssDialogue*>(e)) { else if (auto dia = check_cast<const AssDialogue*>(e)) {
set_field(L, "raw", dia->GetEntryData()); set_field(L, "raw", dia->GetEntryData());
set_field(L, "comment", dia->Comment); set_field(L, "comment", dia->Comment);
@ -187,7 +192,7 @@ namespace Automation4 {
set_field(L, "class", "dialogue"); set_field(L, "class", "dialogue");
} }
else if (auto sty = dynamic_cast<const AssStyle*>(e)) { else if (auto sty = check_cast<const AssStyle*>(e)) {
set_field(L, "raw", sty->GetEntryData()); set_field(L, "raw", sty->GetEntryData());
set_field(L, "name", sty->name); set_field(L, "name", sty->name);
@ -618,7 +623,7 @@ namespace Automation4 {
int LuaAssFile::LuaParseKaraokeData(lua_State *L) int LuaAssFile::LuaParseKaraokeData(lua_State *L)
{ {
auto e = LuaToAssEntry(L, ass); auto e = LuaToAssEntry(L, ass);
auto dia = dynamic_cast<AssDialogue*>(e.get()); auto dia = check_cast<AssDialogue*>(e.get());
argcheck(L, !!dia, 1, "Subtitle line must be a dialogue line"); argcheck(L, !!dia, 1, "Subtitle line must be a dialogue line");
int idx = 0; int idx = 0;

View file

@ -75,8 +75,9 @@ void FontCollector::ProcessDialogueLine(const AssDialogue *line, int index) {
bool overriden = false; bool overriden = false;
for (auto& block : line->ParseTags()) { for (auto& block : line->ParseTags()) {
if (auto ovr = dynamic_cast<AssDialogueBlockOverride *>(block.get())) { switch (block->GetType()) {
for (auto const& tag : ovr->Tags) { case AssBlockType::OVERRIDE:
for (auto const& tag : static_cast<AssDialogueBlockOverride&>(*block).Tags) {
if (tag.Name == "\\r") { if (tag.Name == "\\r") {
style = styles[tag.Params[0].Get(line->Style.get())]; style = styles[tag.Params[0].Get(line->Style.get())];
overriden = false; overriden = false;
@ -94,9 +95,9 @@ void FontCollector::ProcessDialogueLine(const AssDialogue *line, int index) {
overriden = true; overriden = true;
} }
} }
} break;
else if (auto txt = dynamic_cast<AssDialogueBlockPlain *>(block.get())) { case AssBlockType::PLAIN: {
auto text = txt->GetText(); auto text = block->GetText();
if (text.empty()) if (text.empty())
continue; continue;
@ -135,8 +136,12 @@ void FontCollector::ProcessDialogueLine(const AssDialogue *line, int index) {
sort(begin(chars), end(chars)); sort(begin(chars), end(chars));
chars.erase(unique(chars.begin(), chars.end()), chars.end()); chars.erase(unique(chars.begin(), chars.end()), chars.end());
break;
}
case AssBlockType::DRAWING:
case AssBlockType::COMMENT:
break;
} }
// Do nothing with drawing and comment blocks
} }
} }

View file

@ -485,9 +485,9 @@ std::string SRTSubtitleFormat::ConvertTags(const AssDialogue *diag) const {
std::string final; std::string final;
for (auto& block : diag->ParseTags()) { for (auto& block : diag->ParseTags()) {
if (AssDialogueBlockOverride* ovr = dynamic_cast<AssDialogueBlockOverride*>(block.get())) { switch (block->GetType()) {
// Iterate through overrides case AssBlockType::OVERRIDE:
for (auto const& tag : ovr->Tags) { for (auto const& tag : static_cast<AssDialogueBlockOverride&>(*block).Tags) {
if (!tag.IsValid() || tag.Name.size() != 2) if (!tag.IsValid() || tag.Name.size() != 2)
continue; continue;
for (auto& state : tag_states) { for (auto& state : tag_states) {
@ -501,10 +501,14 @@ std::string SRTSubtitleFormat::ConvertTags(const AssDialogue *diag) const {
state.value = temp; state.value = temp;
} }
} }
break;
case AssBlockType::PLAIN:
final += block->GetText();
break;
case AssBlockType::DRAWING:
case AssBlockType::COMMENT:
break;
} }
// Plain text
else if (AssDialogueBlockPlain *plain = dynamic_cast<AssDialogueBlockPlain*>(block.get()))
final += plain->GetText();
} }
// Ensure all tags are closed // Ensure all tags are closed

View file

@ -534,7 +534,8 @@ void VisualToolBase::SetOverride(AssDialogue* line, std::string const& tag, std:
auto blocks = line->ParseTags(); auto blocks = line->ParseTags();
AssDialogueBlock *block = blocks.front().get(); AssDialogueBlock *block = blocks.front().get();
if (AssDialogueBlockOverride *ovr = dynamic_cast<AssDialogueBlockOverride*>(block)) { if (block->GetType() == AssBlockType::OVERRIDE) {
auto ovr = static_cast<AssDialogueBlockOverride*>(block);
// Remove old of same // Remove old of same
for (size_t i = 0; i < ovr->Tags.size(); i++) { for (size_t i = 0; i < ovr->Tags.size(); i++) {
std::string const& name = ovr->Tags[i].Name; std::string const& name = ovr->Tags[i].Name;