mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Use fewer templates in RGBGFX pal_packing.cpp
This commit is contained in:
@@ -42,9 +42,11 @@ struct ColorSetAttrs {
|
|||||||
std::vector<bool> bannedPages;
|
std::vector<bool> bannedPages;
|
||||||
|
|
||||||
explicit ColorSetAttrs(size_t index) : colorSetIndex(index) {}
|
explicit ColorSetAttrs(size_t index) : colorSetIndex(index) {}
|
||||||
|
|
||||||
bool isBannedFrom(size_t index) const {
|
bool isBannedFrom(size_t index) const {
|
||||||
return index < bannedPages.size() && bannedPages[index];
|
return index < bannedPages.size() && bannedPages[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void banFrom(size_t index) {
|
void banFrom(size_t index) {
|
||||||
if (bannedPages.size() <= index) {
|
if (bannedPages.size() <= index) {
|
||||||
bannedPages.resize(index + 1);
|
bannedPages.resize(index + 1);
|
||||||
@@ -62,9 +64,8 @@ class AssignedSets {
|
|||||||
std::vector<ColorSet> const *_colorSets;
|
std::vector<ColorSet> const *_colorSets;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename... Ts>
|
AssignedSets(std::vector<ColorSet> const &colorSets, std::optional<ColorSetAttrs> &&attrs)
|
||||||
AssignedSets(std::vector<ColorSet> const &colorSets, Ts &&...elems)
|
: _assigned{attrs}, _colorSets{&colorSets} {}
|
||||||
: _assigned{std::forward<Ts>(elems)...}, _colorSets{&colorSets} {}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename Inner, template<typename> typename Constness>
|
template<typename Inner, template<typename> typename Constness>
|
||||||
@@ -119,34 +120,34 @@ private:
|
|||||||
std::swap(lhs._iter, rhs._iter);
|
std::swap(lhs._iter, rhs._iter);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using iterator = Iter<decltype(_assigned)::iterator, std::remove_const_t>;
|
using iterator = Iter<decltype(_assigned)::iterator, std::remove_const_t>;
|
||||||
iterator begin() { return iterator{&_assigned, _assigned.begin()}.skipEmpty(); }
|
iterator begin() { return iterator{&_assigned, _assigned.begin()}.skipEmpty(); }
|
||||||
iterator end() { return iterator{&_assigned, _assigned.end()}; }
|
iterator end() { return iterator{&_assigned, _assigned.end()}; }
|
||||||
|
|
||||||
using const_iterator = Iter<decltype(_assigned)::const_iterator, std::add_const_t>;
|
using const_iterator = Iter<decltype(_assigned)::const_iterator, std::add_const_t>;
|
||||||
const_iterator begin() const {
|
const_iterator begin() const {
|
||||||
return const_iterator{&_assigned, _assigned.begin()}.skipEmpty();
|
return const_iterator{&_assigned, _assigned.begin()}.skipEmpty();
|
||||||
}
|
}
|
||||||
const_iterator end() const { return const_iterator{&_assigned, _assigned.end()}; }
|
const_iterator end() const { return const_iterator{&_assigned, _assigned.end()}; }
|
||||||
|
|
||||||
// Assigns a new ColorSetAttrs in a free slot, assuming there is one
|
void assign(ColorSetAttrs const &&attrs) {
|
||||||
// Args are passed to the `ColorSetAttrs`'s constructor
|
|
||||||
template<typename... Ts>
|
|
||||||
void assign(Ts &&...args) {
|
|
||||||
auto freeSlot =
|
auto freeSlot =
|
||||||
std::find_if_not(RANGE(_assigned), [](std::optional<ColorSetAttrs> const &slot) {
|
std::find_if_not(RANGE(_assigned), [](std::optional<ColorSetAttrs> const &slot) {
|
||||||
return slot.has_value();
|
return slot.has_value();
|
||||||
});
|
});
|
||||||
|
if (freeSlot == _assigned.end()) {
|
||||||
if (freeSlot == _assigned.end()) { // We are full, use a new slot
|
_assigned.emplace_back(attrs); // We are full, use a new slot
|
||||||
_assigned.emplace_back(std::forward<Ts>(args)...);
|
} else {
|
||||||
} else { // Reuse a free slot
|
freeSlot->emplace(attrs); // Reuse a free slot
|
||||||
freeSlot->emplace(std::forward<Ts>(args)...);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(iterator const &iter) {
|
void remove(iterator const &iter) {
|
||||||
iter._iter->reset(); // This time, we want to access the `optional` itself
|
iter._iter->reset(); // This time, we want to access the `optional` itself
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() { _assigned.clear(); }
|
void clear() { _assigned.clear(); }
|
||||||
|
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
@@ -171,6 +172,7 @@ private:
|
|||||||
colors.insert(RANGE(colorSet));
|
colors.insert(RANGE(colorSet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function should stay private because it returns a reference to a unique object
|
// This function should stay private because it returns a reference to a unique object
|
||||||
std::unordered_set<uint16_t> &uniqueColors() const {
|
std::unordered_set<uint16_t> &uniqueColors() const {
|
||||||
// We check for *distinct* colors by stuffing them into a `set`; this should be
|
// We check for *distinct* colors by stuffing them into a `set`; this should be
|
||||||
@@ -181,9 +183,11 @@ private:
|
|||||||
addUniqueColors(colors, RANGE(*this), *_colorSets);
|
addUniqueColors(colors, RANGE(*this), *_colorSets);
|
||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Returns the number of distinct colors
|
// Returns the number of distinct colors
|
||||||
size_t volume() const { return uniqueColors().size(); }
|
size_t volume() const { return uniqueColors().size(); }
|
||||||
|
|
||||||
bool canFit(ColorSet const &colorSet) const {
|
bool canFit(ColorSet const &colorSet) const {
|
||||||
std::unordered_set<uint16_t> &colors = uniqueColors();
|
std::unordered_set<uint16_t> &colors = uniqueColors();
|
||||||
colors.insert(RANGE(colorSet));
|
colors.insert(RANGE(colorSet));
|
||||||
@@ -239,6 +243,7 @@ public:
|
|||||||
addUniqueColors(colors, std::forward<Iter>(begin), end, colorSets);
|
addUniqueColors(colors, std::forward<Iter>(begin), end, colorSets);
|
||||||
return colors.size();
|
return colors.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes the "relative size" of a set of colors on this palette
|
// Computes the "relative size" of a set of colors on this palette
|
||||||
template<typename Iter>
|
template<typename Iter>
|
||||||
size_t combinedVolume(Iter &&begin, Iter &&end) const {
|
size_t combinedVolume(Iter &&begin, Iter &&end) const {
|
||||||
@@ -302,7 +307,7 @@ static void decant(std::vector<AssignedSets> &assignments, std::vector<ColorSet>
|
|||||||
// If the entire palettes can be merged, move all of `from`'s color sets
|
// If the entire palettes can be merged, move all of `from`'s color sets
|
||||||
if (to.combinedVolume(RANGE(from), colorSets) <= options.maxOpaqueColors()) {
|
if (to.combinedVolume(RANGE(from), colorSets) <= options.maxOpaqueColors()) {
|
||||||
for (ColorSetAttrs &attrs : from) {
|
for (ColorSetAttrs &attrs : from) {
|
||||||
to.assign(attrs.colorSetIndex);
|
to.assign(std::move(attrs));
|
||||||
}
|
}
|
||||||
from.clear();
|
from.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user