From ed3d5dffc099b1c5bcb14451fffc63de1b6ac634 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 26 Jun 2023 14:40:14 +1000 Subject: [PATCH] slight NetworkedAnimator drawables optimization --- source/core/StarString.cpp | 1 + source/core/StarString.hpp | 51 +++++++++++++++++++++++++++ source/core/StarStringView.cpp | 4 +++ source/core/StarStringView.hpp | 1 + source/game/StarNetworkedAnimator.cpp | 36 ++++++++++++------- 5 files changed, 81 insertions(+), 12 deletions(-) diff --git a/source/core/StarString.cpp b/source/core/StarString.cpp index 81c6b2e..9394e23 100644 --- a/source/core/StarString.cpp +++ b/source/core/StarString.cpp @@ -1,4 +1,5 @@ #include "StarString.hpp" +#include "StarStringView.hpp" #include "StarBytes.hpp" #include "StarFormat.hpp" diff --git a/source/core/StarString.hpp b/source/core/StarString.hpp index ddc7926..5adb0f9 100644 --- a/source/core/StarString.hpp +++ b/source/core/StarString.hpp @@ -212,6 +212,13 @@ public: template String lookupTags(Lookup&& lookup) const; + // StringView variant + template + Maybe maybeLookupTagsView(Lookup&& lookup) const; + + template + String lookupTagsView(Lookup&& lookup) const; + // Replace angle bracket tags in the string with values given by the tags // map. If replaceWithDefault is true, then values that are not found in the // tags map are replace with the default string. If replaceWithDefault is @@ -424,6 +431,50 @@ String String::lookupTags(Lookup&& lookup) const { return move(finalString); } +template +Maybe String::maybeLookupTagsView(Lookup&& lookup) const { + List finalViews = {}; + std::string_view view(utf8()); + + size_t start = 0; + while (true) { + if (start >= view.size()) + break; + + size_t beginTag = view.find_first_of('<', start); + if (beginTag == NPos && !start) + return Maybe(); + + size_t endTag = view.find_first_of('>', beginTag); + if (beginTag != NPos && endTag != NPos) { + finalViews.append(view.substr(start, beginTag - start)); + finalViews.append(lookup(view.substr(beginTag + 1, endTag - beginTag - 1)).takeUtf8()); + start = endTag + 1; + } else { + finalViews.append(view.substr(start)); + break; + } + } + + std::string finalString; + size_t finalSize = 0; + for (auto& view : finalViews) + finalSize += view.size(); + + finalString.reserve(finalSize); + + for (auto& view : finalViews) + finalString += view; + + return move(finalString); +} + +template +String String::lookupTagsView(Lookup&& lookup) const { + auto result = maybeLookupTagsView(lookup); + return result ? move(result.take()) : String(); +} + template String String::replaceTags(MapType const& tags, bool replaceWithDefault, String defaultValue) const { return lookupTags([&](String const& key) -> String { diff --git a/source/core/StarStringView.cpp b/source/core/StarStringView.cpp index 1bea5e5..d0e0e07 100644 --- a/source/core/StarStringView.cpp +++ b/source/core/StarStringView.cpp @@ -409,6 +409,10 @@ StringView& StringView::operator=(StringView s) { return *this; } +bool operator==(StringView s1, const char* s2) { + return s1.m_view.compare(s2) == 0; +} + bool operator==(StringView s1, StringView s2) { return s1.m_view == s2.m_view; } diff --git a/source/core/StarStringView.hpp b/source/core/StarStringView.hpp index 928c37a..ff6e564 100644 --- a/source/core/StarStringView.hpp +++ b/source/core/StarStringView.hpp @@ -95,6 +95,7 @@ public: StringView& operator=(StringView s); + friend bool operator==(StringView s1, const char* s2); friend bool operator==(StringView s1, StringView s2); friend bool operator!=(StringView s1, StringView s2); friend bool operator<(StringView s1, StringView s2); diff --git a/source/game/StarNetworkedAnimator.cpp b/source/game/StarNetworkedAnimator.cpp index db3524b..5c5c3fb 100644 --- a/source/game/StarNetworkedAnimator.cpp +++ b/source/game/StarNetworkedAnimator.cpp @@ -583,7 +583,11 @@ List> NetworkedAnimator::drawablesWithZLevel(Vec2F const& List> drawables; m_animatedParts.forEachActivePart([&](String const& partName, AnimatedPartSet::ActivePartInformation const& activePart) { - String image = activePart.properties.value("image").optString().value(); + // Make sure we don't copy the original image + String fallback = ""; + Json jImage = activePart.properties.value("image", {}); + String const& image = jImage.isType(Json::Type::String) ? *jImage.stringPtr() : fallback; + bool centered = activePart.properties.value("centered").optBool().value(true); bool fullbright = activePart.properties.value("fullbright").optBool().value(false); @@ -598,8 +602,13 @@ List> NetworkedAnimator::drawablesWithZLevel(Vec2F const& } Maybe frame; + String frameStr; + String frameIndexStr; if (activePart.activeState) { - frame = activePart.activeState->frame; + unsigned stateFrame = activePart.activeState->frame; + frame = stateFrame; + frameStr = static_cast(toString(stateFrame + 1)); + frameIndexStr = static_cast(toString(stateFrame)); if (auto directives = activePart.activeState->properties.value("processingDirectives").optString()) { baseProcessingDirectives.append(*directives); @@ -607,26 +616,29 @@ List> NetworkedAnimator::drawablesWithZLevel(Vec2F const& } auto const& partTags = m_partTags.get(partName); - image = image.lookupTags([&](String const& tag) -> String { + Maybe processedImage = image.maybeLookupTagsView([&](StringView tag) -> StringView { if (tag == "frame") { if (frame) - return toString(*frame + 1); + return frameStr; } else if (tag == "frameIndex") { if (frame) - return toString(*frame); + return frameIndexStr; } else if (auto p = partTags.ptr(tag)) { - return *p; + return StringView(*p); } else if (auto p = m_globalTags.ptr(tag)) { - return *p; + return StringView(*p); } - return "default"; + return StringView("default"); }); + String const& usedImage = processedImage ? processedImage.get() : image; - if (!image.empty() && image[0] != ':' && image[0] != '?') { - image = AssetPath::relativeTo(m_relativePath, image); + if (!usedImage.empty() && usedImage[0] != ':' && usedImage[0] != '?') { + String relativeImage; + if (usedImage[0] != '/') + relativeImage = AssetPath::relativeTo(m_relativePath, usedImage); - auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, centered, Vec2F()); + auto drawable = Drawable::makeImage(!relativeImage.empty() ? relativeImage : usedImage, 1.0f / TilePixels, centered, Vec2F()); auto& imagePart = drawable.imagePart(); for (Directives const& directives : baseProcessingDirectives) imagePart.addDirectives(directives); @@ -637,7 +649,7 @@ List> NetworkedAnimator::drawablesWithZLevel(Vec2F const& drawables.append({move(drawable), zLevel}); } - + baseProcessingDirectives.resize(originalDirectivesSize); });