Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/core/StarString.cpp1
-rw-r--r--source/core/StarString.hpp51
-rw-r--r--source/core/StarStringView.cpp4
-rw-r--r--source/core/StarStringView.hpp1
-rw-r--r--source/game/StarNetworkedAnimator.cpp36
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 <typename Lookup>
String lookupTags(Lookup&& lookup) const;
+ // StringView variant
+ template <typename Lookup>
+ Maybe<String> maybeLookupTagsView(Lookup&& lookup) const;
+
+ template <typename Lookup>
+ 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 <typename Lookup>
+Maybe<String> String::maybeLookupTagsView(Lookup&& lookup) const {
+ List<std::string_view> 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<String>();
+
+ 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 <typename Lookup>
+String String::lookupTagsView(Lookup&& lookup) const {
+ auto result = maybeLookupTagsView(lookup);
+ return result ? move(result.take()) : String();
+}
+
template <typename MapType>
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<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
List<pair<Drawable, float>> 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<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
}
Maybe<unsigned> frame;
+ String frameStr;
+ String frameIndexStr;
if (activePart.activeState) {
- frame = activePart.activeState->frame;
+ unsigned stateFrame = activePart.activeState->frame;
+ frame = stateFrame;
+ frameStr = static_cast<String>(toString(stateFrame + 1));
+ frameIndexStr = static_cast<String>(toString(stateFrame));
if (auto directives = activePart.activeState->properties.value("processingDirectives").optString()) {
baseProcessingDirectives.append(*directives);
@@ -607,26 +616,29 @@ List<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
}
auto const& partTags = m_partTags.get(partName);
- image = image.lookupTags([&](String const& tag) -> String {
+ Maybe<String> 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<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
drawables.append({move(drawable), zLevel});
}
-
+
baseProcessingDirectives.resize(originalDirectivesSize);
});