From 3ece61b10354c53babfe34a7189b6de116dae144 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Sat, 20 Sep 2025 21:27:52 -0400 Subject: [PATCH] Use fewer templates in RGBGFX pal_packing.cpp --- src/gfx/pal_packing.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/gfx/pal_packing.cpp b/src/gfx/pal_packing.cpp index 9a9c7233..859eb4c7 100644 --- a/src/gfx/pal_packing.cpp +++ b/src/gfx/pal_packing.cpp @@ -42,9 +42,11 @@ struct ColorSetAttrs { std::vector bannedPages; explicit ColorSetAttrs(size_t index) : colorSetIndex(index) {} + bool isBannedFrom(size_t index) const { return index < bannedPages.size() && bannedPages[index]; } + void banFrom(size_t index) { if (bannedPages.size() <= index) { bannedPages.resize(index + 1); @@ -62,9 +64,8 @@ class AssignedSets { std::vector const *_colorSets; public: - template - AssignedSets(std::vector const &colorSets, Ts &&...elems) - : _assigned{std::forward(elems)...}, _colorSets{&colorSets} {} + AssignedSets(std::vector const &colorSets, std::optional &&attrs) + : _assigned{attrs}, _colorSets{&colorSets} {} private: template typename Constness> @@ -119,34 +120,34 @@ private: std::swap(lhs._iter, rhs._iter); } }; + public: using iterator = Iter; iterator begin() { return iterator{&_assigned, _assigned.begin()}.skipEmpty(); } iterator end() { return iterator{&_assigned, _assigned.end()}; } + using const_iterator = Iter; const_iterator begin() const { return const_iterator{&_assigned, _assigned.begin()}.skipEmpty(); } const_iterator end() const { return const_iterator{&_assigned, _assigned.end()}; } - // Assigns a new ColorSetAttrs in a free slot, assuming there is one - // Args are passed to the `ColorSetAttrs`'s constructor - template - void assign(Ts &&...args) { + void assign(ColorSetAttrs const &&attrs) { auto freeSlot = std::find_if_not(RANGE(_assigned), [](std::optional const &slot) { return slot.has_value(); }); - - if (freeSlot == _assigned.end()) { // We are full, use a new slot - _assigned.emplace_back(std::forward(args)...); - } else { // Reuse a free slot - freeSlot->emplace(std::forward(args)...); + if (freeSlot == _assigned.end()) { + _assigned.emplace_back(attrs); // We are full, use a new slot + } else { + freeSlot->emplace(attrs); // Reuse a free slot } } + void remove(iterator const &iter) { iter._iter->reset(); // This time, we want to access the `optional` itself } + void clear() { _assigned.clear(); } bool empty() const { @@ -171,6 +172,7 @@ private: colors.insert(RANGE(colorSet)); } } + // This function should stay private because it returns a reference to a unique object std::unordered_set &uniqueColors() const { // We check for *distinct* colors by stuffing them into a `set`; this should be @@ -181,9 +183,11 @@ private: addUniqueColors(colors, RANGE(*this), *_colorSets); return colors; } + public: // Returns the number of distinct colors size_t volume() const { return uniqueColors().size(); } + bool canFit(ColorSet const &colorSet) const { std::unordered_set &colors = uniqueColors(); colors.insert(RANGE(colorSet)); @@ -239,6 +243,7 @@ public: addUniqueColors(colors, std::forward(begin), end, colorSets); return colors.size(); } + // Computes the "relative size" of a set of colors on this palette template size_t combinedVolume(Iter &&begin, Iter &&end) const { @@ -302,7 +307,7 @@ static void decant(std::vector &assignments, std::vector // If the entire palettes can be merged, move all of `from`'s color sets if (to.combinedVolume(RANGE(from), colorSets) <= options.maxOpaqueColors()) { for (ColorSetAttrs &attrs : from) { - to.assign(attrs.colorSetIndex); + to.assign(std::move(attrs)); } from.clear(); }