summaryrefslogtreecommitdiff
path: root/gfx/gl/instanceVertices.h
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2024-06-30 12:30:48 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2024-06-30 12:30:48 +0100
commit340dc8fa5be06ed909fe54bc4ca135921dc70cae (patch)
tree940c95c22757e60a0ae3bad997fb6240a6c9dba2 /gfx/gl/instanceVertices.h
parentImplement partition on InstanceVertices (diff)
downloadilt-340dc8fa5be06ed909fe54bc4ca135921dc70cae.tar.bz2
ilt-340dc8fa5be06ed909fe54bc4ca135921dc70cae.tar.xz
ilt-340dc8fa5be06ed909fe54bc4ca135921dc70cae.zip
Maintain a reverse index in instance vertices
Removes need to search unused and/or index when moving/adding things
Diffstat (limited to 'gfx/gl/instanceVertices.h')
-rw-r--r--gfx/gl/instanceVertices.h24
1 files changed, 16 insertions, 8 deletions
diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h
index ad1716d..28e11ee 100644
--- a/gfx/gl/instanceVertices.h
+++ b/gfx/gl/instanceVertices.h
@@ -107,10 +107,12 @@ public:
auto idx = unused.back();
unused.pop_back();
index[idx] = base::size();
+ reverseIndex.emplace_back(idx);
base::emplace_back(std::forward<Params>(params)...);
return InstanceProxy {this, idx};
}
index.emplace_back(base::size());
+ reverseIndex.push_back(base::size());
base::emplace_back(std::forward<Params>(params)...);
return InstanceProxy {this, index.size() - 1};
}
@@ -132,24 +134,27 @@ public:
}
protected:
+ static constexpr auto npos = static_cast<size_t>(-1);
friend InstanceProxy;
void
release(const size_t pidx)
{
- if (base::size() - 1 != index[pidx]) {
+ if (const size_t last = base::size() - 1; last != index[pidx]) {
lookup(pidx) = std::move(base::back());
- *std::find_if(index.begin(), index.end(), [this, old = base::size() - 1](const auto & i) {
- return i == old && !std::binary_search(unused.begin(), unused.end(), &i - index.data());
- }) = index[pidx];
+ const auto movedKey = reverseIndex[last];
+ index[movedKey] = std::exchange(index[pidx], npos);
+ reverseIndex[index[movedKey]] = movedKey;
}
base::pop_back();
+ reverseIndex.pop_back();
if (pidx == index.size() - 1) {
index.pop_back();
}
else {
- // Remember p.index is free index now, keeping it sorted
- unused.insert(std::upper_bound(unused.begin(), unused.end(), pidx), pidx);
+ index[pidx] = npos;
+ // Remember p.index is free index now
+ unused.emplace_back(pidx);
}
}
@@ -168,8 +173,10 @@ protected:
last = --std::find_if(std::make_reverse_iterator(last), std::make_reverse_iterator(first), pred).base();
if (first < last) {
std::iter_swap(first, last);
- std::iter_swap(std::find(index.begin(), index.end(), first - base::begin()),
- std::find(index.begin(), index.end(), last - base::begin()));
+ const auto fidx = static_cast<size_t>(first - base::begin()),
+ lidx = static_cast<size_t>(last - base::begin());
+ std::swap(index[reverseIndex[fidx]], index[reverseIndex[lidx]]);
+ std::swap(reverseIndex[fidx], reverseIndex[lidx]);
}
}
return first;
@@ -177,6 +184,7 @@ protected:
// Index into buffer given to nth proxy
std::vector<size_t> index;
+ std::vector<size_t> reverseIndex;
// List of free spaces in index
std::vector<size_t> unused;
};