diff --git a/source/core/StarImageProcessing.cpp b/source/core/StarImageProcessing.cpp index f66da30..4dfcf8a 100644 --- a/source/core/StarImageProcessing.cpp +++ b/source/core/StarImageProcessing.cpp @@ -174,36 +174,38 @@ ImageOperation imageOperationFromString(StringView string) { char ch = *ptr; if (ch == '=' || ch == ';' || ptr == end) { - char* c = which ? a : b; + if (hexLen != 0) { + char* c = which ? a : b; - if (hexLen == 3) { - nibbleDecode(hexPtr, 3, c, 4); - c[0] |= (c[0] << 4); - c[1] |= (c[1] << 4); - c[2] |= (c[2] << 4); - c[3] = 255; - } - else if (hexLen == 4) { - nibbleDecode(hexPtr, 4, c, 4); - c[0] |= (c[0] << 4); - c[1] |= (c[1] << 4); - c[2] |= (c[2] << 4); - c[3] |= (c[3] << 4); - } - else if (hexLen == 6) { - hexDecode(hexPtr, 6, c, 4); - c[3] = 255; - } - else if (hexLen == 8) { - hexDecode(hexPtr, 8, c, 4); - } - else - throw ImageOperationException(strf("Improper size for hex string '%s' in imageOperationFromString", StringView(hexPtr, hexLen)), false); + if (hexLen == 3) { + nibbleDecode(hexPtr, 3, c, 4); + c[0] |= (c[0] << 4); + c[1] |= (c[1] << 4); + c[2] |= (c[2] << 4); + c[3] = 255; + } + else if (hexLen == 4) { + nibbleDecode(hexPtr, 4, c, 4); + c[0] |= (c[0] << 4); + c[1] |= (c[1] << 4); + c[2] |= (c[2] << 4); + c[3] |= (c[3] << 4); + } + else if (hexLen == 6) { + hexDecode(hexPtr, 6, c, 4); + c[3] = 255; + } + else if (hexLen == 8) { + hexDecode(hexPtr, 8, c, 4); + } + else + throw ImageOperationException(strf("Improper size for hex string '%s' in imageOperationFromString", StringView(hexPtr, hexLen)), false); - if (which = !which) - operation.colorReplaceMap[*(Vec4B*)&a] = *(Vec4B*)&b; + if (which = !which) + operation.colorReplaceMap[*(Vec4B*)&a] = *(Vec4B*)&b; - hexLen = 0; + hexLen = 0; + } } else if (!hexLen++) hexPtr = ptr; diff --git a/source/game/StarNetworkedAnimator.cpp b/source/game/StarNetworkedAnimator.cpp index 5c5c3fb..c5b3591 100644 --- a/source/game/StarNetworkedAnimator.cpp +++ b/source/game/StarNetworkedAnimator.cpp @@ -255,6 +255,7 @@ NetworkedAnimator& NetworkedAnimator::operator=(NetworkedAnimator&& animator) { m_animationRate = move(animator.m_animationRate); m_globalTags = move(animator.m_globalTags); m_partTags = move(animator.m_partTags); + m_cachedPartDrawables = move(animator.m_cachedPartDrawables); setupNetStates(); @@ -278,6 +279,7 @@ NetworkedAnimator& NetworkedAnimator::operator=(NetworkedAnimator const& animato m_animationRate = animator.m_animationRate; m_globalTags = animator.m_globalTags; m_partTags = animator.m_partTags; + m_cachedPartDrawables = animator.m_cachedPartDrawables; setupNetStates(); @@ -638,7 +640,20 @@ List> NetworkedAnimator::drawablesWithZLevel(Vec2F const& if (usedImage[0] != '/') relativeImage = AssetPath::relativeTo(m_relativePath, usedImage); - auto drawable = Drawable::makeImage(!relativeImage.empty() ? relativeImage : usedImage, 1.0f / TilePixels, centered, Vec2F()); + size_t hash = hashOf(relativeImage); + auto find = m_cachedPartDrawables.find(partName); + bool fail = find == m_cachedPartDrawables.end() || find->second.first != hash; + if (fail) { + Drawable drawable = Drawable::makeImage(!relativeImage.empty() ? relativeImage : usedImage, 1.0f / TilePixels, centered, Vec2F()); + if (find == m_cachedPartDrawables.end()) + find = m_cachedPartDrawables.emplace(partName, std::pair{ hash, move(drawable) }).first; + else { + find->second.first = hash; + find->second.second = move(drawable); + } + } + + Drawable drawable = find->second.second; auto& imagePart = drawable.imagePart(); for (Directives const& directives : baseProcessingDirectives) imagePart.addDirectives(directives); diff --git a/source/game/StarNetworkedAnimator.hpp b/source/game/StarNetworkedAnimator.hpp index dc6d299..18ea4d5 100644 --- a/source/game/StarNetworkedAnimator.hpp +++ b/source/game/StarNetworkedAnimator.hpp @@ -324,6 +324,7 @@ private: NetElementHashMap m_globalTags; StableStringMap> m_partTags; + mutable StringMap> m_cachedPartDrawables; }; }