reduce some Directives exceptions down to error strings for perf
additionally, image operations that don't exist simply pass through now
This commit is contained in:
parent
1b86da7f36
commit
a81490c35c
@ -14,7 +14,9 @@
|
|||||||
"offset" : [0, 13]
|
"offset" : [0, 13]
|
||||||
},
|
},
|
||||||
"specialDamageBar" : {
|
"specialDamageBar" : {
|
||||||
"nameStyle" : {}
|
"nameStyle" : {
|
||||||
|
"fontSize" : 18
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"textStyle" : {},
|
"textStyle" : {},
|
||||||
"buttonTextStyle" : {
|
"buttonTextStyle" : {
|
||||||
|
@ -1160,7 +1160,10 @@ shared_ptr<Assets::AssetData> Assets::loadImage(AssetPath const& path) const {
|
|||||||
Image newImage = *source->image;
|
Image newImage = *source->image;
|
||||||
path.directives.forEach([&](auto const& entry, Directives const&) {
|
path.directives.forEach([&](auto const& entry, Directives const&) {
|
||||||
if (auto error = entry.operation.template ptr<ErrorImageOperation>())
|
if (auto error = entry.operation.template ptr<ErrorImageOperation>())
|
||||||
std::rethrow_exception(error->exception);
|
if (auto string = error->cause.ptr<std::string>())
|
||||||
|
throw DirectivesException::format("ImageOperation parse error: {}", *string);
|
||||||
|
else
|
||||||
|
std::rethrow_exception(error->cause.get<std::exception_ptr>());
|
||||||
else
|
else
|
||||||
processImageOperation(entry.operation, newImage, [&](String const& ref) { return references.get(ref).get(); });
|
processImageOperation(entry.operation, newImage, [&](String const& ref) { return references.get(ref).get(); });
|
||||||
});
|
});
|
||||||
|
@ -160,10 +160,10 @@ std::ostream& operator<<(std::ostream& os, AssetPath const& rhs) {
|
|||||||
os << *rhs.subPath;
|
os << *rhs.subPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
rhs.directives.forEach([&](auto const& entry, Directives const& directives) {
|
rhs.directives.forEach([&](Directives::Entry const& entry, Directives const& directives) {
|
||||||
os << "?";
|
os << "?";
|
||||||
os << entry.string(*directives);
|
os << entry.string(*directives);
|
||||||
});
|
});
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,10 @@ Directives::Entry::Entry(Entry const& other) {
|
|||||||
|
|
||||||
ImageOperation const& Directives::Entry::loadOperation(Shared const& parent) const {
|
ImageOperation const& Directives::Entry::loadOperation(Shared const& parent) const {
|
||||||
if (operation.is<NullImageOperation>()) {
|
if (operation.is<NullImageOperation>()) {
|
||||||
try { operation = imageOperationFromString(string(parent)); }
|
try
|
||||||
catch (StarException const& e) { operation = ErrorImageOperation{ std::current_exception() }; }
|
{ operation = imageOperationFromString(string(parent)); }
|
||||||
|
catch (StarException const& e)
|
||||||
|
{ operation = ErrorImageOperation{std::exception_ptr()}; }
|
||||||
}
|
}
|
||||||
return operation;
|
return operation;
|
||||||
}
|
}
|
||||||
@ -44,10 +46,9 @@ bool Directives::Shared::empty() const {
|
|||||||
|
|
||||||
Directives::Shared::Shared() {}
|
Directives::Shared::Shared() {}
|
||||||
|
|
||||||
Directives::Shared::Shared(List<Entry>&& givenEntries, String&& givenString, StringView givenPrefix) {
|
Directives::Shared::Shared(List<Entry>&& givenEntries, String&& givenString) {
|
||||||
entries = std::move(givenEntries);
|
entries = std::move(givenEntries);
|
||||||
string = std::move(givenString);
|
string = std::move(givenString);
|
||||||
prefix = givenPrefix;
|
|
||||||
hash = string.empty() ? 0 : XXH3_64bits(string.utf8Ptr(), string.utf8Size());
|
hash = string.empty() ? 0 : XXH3_64bits(string.utf8Ptr(), string.utf8Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,32 +131,25 @@ void Directives::parse(String&& directives) {
|
|||||||
|
|
||||||
List<Entry> entries;
|
List<Entry> entries;
|
||||||
StringView view(directives);
|
StringView view(directives);
|
||||||
StringView prefix = "";
|
|
||||||
view.forEachSplitView("?", [&](StringView split, size_t beg, size_t end) {
|
view.forEachSplitView("?", [&](StringView split, size_t beg, size_t end) {
|
||||||
if (!split.empty()) {
|
if (!split.empty()) {
|
||||||
|
ImageOperation operation = NullImageOperation();
|
||||||
if (beg == 0) {
|
if (beg == 0) {
|
||||||
try {
|
try
|
||||||
ImageOperation operation = imageOperationFromString(split);
|
{ operation = imageOperationFromString(split); }
|
||||||
entries.emplace_back(std::move(operation), beg, end);
|
catch (StarException const& e)
|
||||||
}
|
{ operation = ErrorImageOperation{std::exception_ptr()}; }
|
||||||
catch (StarException const& e) {
|
|
||||||
prefix = split;
|
|
||||||
entries.emplace_back(ImageOperation(ErrorImageOperation{std::current_exception()}), beg, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ImageOperation operation = NullImageOperation();
|
|
||||||
entries.emplace_back(std::move(operation), beg, end);
|
|
||||||
}
|
}
|
||||||
|
entries.emplace_back(std::move(operation), beg, end);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (entries.empty() && !prefix.empty()) {
|
if (entries.empty()) {
|
||||||
m_shared.reset();
|
m_shared.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shared = std::make_shared<Shared const>(std::move(entries), std::move(directives), prefix);
|
m_shared = std::make_shared<Shared const>(std::move(entries), std::move(directives));
|
||||||
if (view.utf8().size() < 1000) { // Pre-load short enough directives
|
if (view.utf8().size() < 1000) { // Pre-load short enough directives
|
||||||
for (auto& entry : m_shared->entries)
|
for (auto& entry : m_shared->entries)
|
||||||
entry.loadOperation(*m_shared);
|
entry.loadOperation(*m_shared);
|
||||||
@ -169,13 +163,6 @@ String Directives::string() const {
|
|||||||
return m_shared->string;
|
return m_shared->string;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView Directives::prefix() const {
|
|
||||||
if (!m_shared)
|
|
||||||
return "";
|
|
||||||
else
|
|
||||||
return m_shared->prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
String const* Directives::stringPtr() const {
|
String const* Directives::stringPtr() const {
|
||||||
if (!m_shared)
|
if (!m_shared)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -186,10 +173,10 @@ String const* Directives::stringPtr() const {
|
|||||||
|
|
||||||
String Directives::buildString() const {
|
String Directives::buildString() const {
|
||||||
if (m_shared) {
|
if (m_shared) {
|
||||||
String built = m_shared->prefix;
|
String built;
|
||||||
|
|
||||||
for (auto& entry : m_shared->entries) {
|
for (auto& entry : m_shared->entries) {
|
||||||
built += "?";
|
if (entry.begin > 0)
|
||||||
|
built += "?";
|
||||||
built += entry.string(*m_shared);
|
built += entry.string(*m_shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,14 +319,11 @@ String DirectivesGroup::toString() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DirectivesGroup::addToString(String& string) const {
|
void DirectivesGroup::addToString(String& string) const {
|
||||||
for (auto& directives : m_directives) {
|
for (auto& entry : m_directives) {
|
||||||
if (directives) {
|
if (entry && !entry->string.empty()) {
|
||||||
auto& dirString = directives->string;
|
if (!string.empty() && string.utf8().back() != '?' && entry->string.utf8()[0] != '?')
|
||||||
if (!dirString.empty()) {
|
string.append('?');
|
||||||
if (dirString.utf8().front() != '?')
|
string += entry->string;
|
||||||
string += "?";
|
|
||||||
string += dirString;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,7 +360,10 @@ void DirectivesGroup::applyExistingImage(Image& image) const {
|
|||||||
forEach([&](auto const& entry, Directives const& directives) {
|
forEach([&](auto const& entry, Directives const& directives) {
|
||||||
ImageOperation const& operation = entry.loadOperation(*directives);
|
ImageOperation const& operation = entry.loadOperation(*directives);
|
||||||
if (auto error = operation.ptr<ErrorImageOperation>())
|
if (auto error = operation.ptr<ErrorImageOperation>())
|
||||||
std::rethrow_exception(error->exception);
|
if (auto string = error->cause.ptr<std::string>())
|
||||||
|
throw DirectivesException::format("ImageOperation parse error: {}", *string);
|
||||||
|
else
|
||||||
|
std::rethrow_exception(error->cause.get<std::exception_ptr>());
|
||||||
else
|
else
|
||||||
processImageOperation(operation, image);
|
processImageOperation(operation, image);
|
||||||
});
|
});
|
||||||
|
@ -31,13 +31,12 @@ public:
|
|||||||
struct Shared {
|
struct Shared {
|
||||||
List<Entry> entries;
|
List<Entry> entries;
|
||||||
String string;
|
String string;
|
||||||
StringView prefix;
|
|
||||||
size_t hash = 0;
|
size_t hash = 0;
|
||||||
mutable Mutex mutex;
|
mutable Mutex mutex;
|
||||||
|
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
Shared();
|
Shared();
|
||||||
Shared(List<Entry>&& givenEntries, String&& givenString, StringView givenPrefix);
|
Shared(List<Entry>&& givenEntries, String&& givenString);
|
||||||
};
|
};
|
||||||
|
|
||||||
Directives();
|
Directives();
|
||||||
@ -57,7 +56,6 @@ public:
|
|||||||
void loadOperations() const;
|
void loadOperations() const;
|
||||||
void parse(String&& directives);
|
void parse(String&& directives);
|
||||||
String string() const;
|
String string() const;
|
||||||
StringView prefix() const;
|
|
||||||
String const* stringPtr() const;
|
String const* stringPtr() const;
|
||||||
String buildString() const;
|
String buildString() const;
|
||||||
String& addToString(String& out) const;
|
String& addToString(String& out) const;
|
||||||
|
@ -199,13 +199,11 @@ ImageOperation imageOperationFromString(StringView string) {
|
|||||||
hexDecode(hexPtr, 8, c, 4);
|
hexDecode(hexPtr, 8, c, 4);
|
||||||
}
|
}
|
||||||
else if (!which || (ptr != end && ++ptr != end))
|
else if (!which || (ptr != end && ++ptr != end))
|
||||||
throw ImageOperationException(strf("Improper size for hex string '{}' in imageOperationFromString", StringView(hexPtr, hexLen)), false);
|
return ErrorImageOperation{strf("Improper size for hex string '{}'", StringView(hexPtr, hexLen))};
|
||||||
else // we're in A of A=B. In vanilla only A=B pairs are evaluated, so only throw an exception if B is also there.
|
else // we're in A of A=B. In vanilla only A=B pairs are evaluated, so only throw an error if B is also there.
|
||||||
return operation;
|
return operation;
|
||||||
|
|
||||||
|
if (which = !which)
|
||||||
which = !which;
|
|
||||||
if (which)
|
|
||||||
operation.colorReplaceMap[*(Vec4B*)&a] = *(Vec4B*)&b;
|
operation.colorReplaceMap[*(Vec4B*)&a] = *(Vec4B*)&b;
|
||||||
|
|
||||||
hexLen = 0;
|
hexLen = 0;
|
||||||
@ -341,12 +339,12 @@ ImageOperation imageOperationFromString(StringView string) {
|
|||||||
return FlipImageOperation{FlipImageOperation::FlipXY};
|
return FlipImageOperation{FlipImageOperation::FlipXY};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw ImageOperationException(strf("Could not recognize ImageOperation type {}", type), false);
|
return NullImageOperation();
|
||||||
}
|
}
|
||||||
} catch (OutOfRangeException const& e) {
|
} catch (OutOfRangeException const& e) {
|
||||||
throw ImageOperationException("Error reading ImageOperation", e);
|
return ErrorImageOperation{std::exception_ptr()};
|
||||||
} catch (BadLexicalCast const& e) {
|
} catch (BadLexicalCast const& e) {
|
||||||
throw ImageOperationException("Error reading ImageOperation", e);
|
return ErrorImageOperation{std::exception_ptr()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,11 +18,11 @@ StringList colorDirectivesFromConfig(JsonArray const& directives);
|
|||||||
String paletteSwapDirectivesFromConfig(Json const& swaps);
|
String paletteSwapDirectivesFromConfig(Json const& swaps);
|
||||||
|
|
||||||
struct NullImageOperation {
|
struct NullImageOperation {
|
||||||
|
bool unloaded = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ErrorImageOperation {
|
struct ErrorImageOperation {
|
||||||
std::exception_ptr exception;
|
Variant<std::string, std::exception_ptr> cause;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HueShiftImageOperation {
|
struct HueShiftImageOperation {
|
||||||
|
@ -64,12 +64,17 @@ const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Cha
|
|||||||
|
|
||||||
for (auto& entry : directives->entries) {
|
for (auto& entry : directives->entries) {
|
||||||
if (auto error = entry.operation.ptr<ErrorImageOperation>()) {
|
if (auto error = entry.operation.ptr<ErrorImageOperation>()) {
|
||||||
if (error->exception) {
|
if (auto string = error->cause.ptr<std::string>()) {
|
||||||
|
if (!string->empty()) {
|
||||||
|
Logger::error("Error parsing font directives: {}", *string);
|
||||||
|
string->clear();
|
||||||
|
}
|
||||||
|
} else if (auto& exception = error->cause.get<std::exception_ptr>()) {
|
||||||
try
|
try
|
||||||
{ std::rethrow_exception(error->exception); }
|
{ std::rethrow_exception(error->cause.get<std::exception_ptr>()); }
|
||||||
catch (std::exception const& e)
|
catch (std::exception const& e)
|
||||||
{ Logger::error("Exception parsing font directives: {}", e.what()); }
|
{ Logger::error("Exception parsing font directives: {}", e.what()); };
|
||||||
error->exception = {};
|
exception = {};
|
||||||
}
|
}
|
||||||
image.forEachPixel([](unsigned x, unsigned y, Vec4B& pixel) {
|
image.forEachPixel([](unsigned x, unsigned y, Vec4B& pixel) {
|
||||||
pixel = ((x + y) % 2 == 0) ? Vec4B(255, 0, 255, pixel[3]) : Vec4B(0, 0, 0, pixel[3]);
|
pixel = ((x + y) % 2 == 0) ? Vec4B(255, 0, 255, pixel[3]) : Vec4B(0, 0, 0, pixel[3]);
|
||||||
|
Loading…
Reference in New Issue
Block a user