diff options
Diffstat (limited to 'gfx/gl/instanceVertices.h')
| -rw-r--r-- | gfx/gl/instanceVertices.h | 111 |
1 files changed, 83 insertions, 28 deletions
diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h index 28e11ee..9963a96 100644 --- a/gfx/gl/instanceVertices.h +++ b/gfx/gl/instanceVertices.h @@ -1,17 +1,20 @@ #pragma once -#include "glContainer.h" +#include "glAllocator.h" +#include <algorithm> #include <cassert> +#include <functional> #include <special_members.h> #include <utility> -template<typename T> class InstanceVertices : protected glContainer<T> { - using base = glContainer<T>; +template<typename T> class InstanceVertices : protected glVector<T> { + using base = glVector<T>; + using IndexT = uint32_t; public: class [[nodiscard]] InstanceProxy { public: - InstanceProxy(InstanceVertices * iv, std::size_t idx) : instances {iv}, index {idx} { } + InstanceProxy(InstanceVertices * iv, IndexT idx) : instances {iv}, index {idx} { } InstanceProxy(InstanceProxy && other) noexcept : instances {std::exchange(other.instances, nullptr)}, index {other.index} @@ -47,13 +50,15 @@ public: } // NOLINTNEXTLINE)hicpp-explicit-conversions - [[nodiscard]] operator T &() + [[nodiscard]] + operator T &() { return instances->lookup(index); } // NOLINTNEXTLINE)hicpp-explicit-conversions - [[nodiscard]] operator const T &() const + [[nodiscard]] + operator const T &() const { return instances->lookup(index); } @@ -94,9 +99,9 @@ public: return instances->lookup(index); } - private: + // private: InstanceVertices<T> * instances; - std::size_t index; + IndexT index; }; template<typename... Params> @@ -106,41 +111,91 @@ public: if (!unused.empty()) { auto idx = unused.back(); unused.pop_back(); - index[idx] = base::size(); + index[idx] = static_cast<IndexT>(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()); + index.emplace_back(static_cast<IndexT>(base::size())); + reverseIndex.push_back(static_cast<IndexT>(base::size())); base::emplace_back(std::forward<Params>(params)...); - return InstanceProxy {this, index.size() - 1}; + return InstanceProxy {this, static_cast<IndexT>(index.size() - 1)}; } - using base::bufferName; + [[nodiscard]] GLuint + bufferName() const + { + return base::begin().base().bufferName(); + } - [[nodiscard]] auto - size() const + [[nodiscard]] GLuint + indexBufferName() const { - base::unmap(); - return base::size(); + return index.begin().base().bufferName(); } + using typename base::value_type; + + using base::at; + using base::begin; + using base::cbegin; + using base::cend; + using base::crbegin; + using base::crend; + using base::end; + using base::rbegin; + using base::rend; + using base::size; + using base::operator[]; + using base::back; + using base::capacity; + using base::data; + using base::empty; + using base::front; + using base::reserve; + using base::shrink_to_fit; + template<typename Pred> - glContainer<T>::iterator + base::size_type partition(Pred pred) { - return partition(base::begin(), base::end(), pred); + return indexOf(partition(base::begin(), base::end(), pred)); + } + + using PartitionResult + = std::pair<typename base::size_type, std::pair<typename base::size_type, typename base::size_type>>; + + template<typename Pred1, typename Pred2> + PartitionResult + partition(Pred1 pred1, Pred2 pred2) + { + return partition(pred1, std::not_fn(pred2), pred2); + } + + template<typename Pred1, typename Pred2, typename Pred3> + PartitionResult + partition(Pred1 pred1, Pred2 pred2, Pred3 pred3) + { + auto boundary1 = partition(base::begin(), base::end(), pred1); + auto begin2 = partition(base::begin(), boundary1, pred2); + auto end2 = partition(boundary1, base::end(), pred3); + return {indexOf(boundary1), {indexOf(begin2), indexOf(end2)}}; } protected: - static constexpr auto npos = static_cast<size_t>(-1); + static constexpr auto npos = static_cast<IndexT>(-1); friend InstanceProxy; + base::size_type + indexOf(base::iterator iter) + { + return static_cast<base::size_type>(iter - base::begin()); + } + void - release(const size_t pidx) + release(const IndexT pidx) { - if (const size_t last = base::size() - 1; last != index[pidx]) { + if (const auto last = static_cast<IndexT>(base::size() - 1); last != index[pidx]) { lookup(pidx) = std::move(base::back()); const auto movedKey = reverseIndex[last]; index[movedKey] = std::exchange(index[pidx], npos); @@ -159,14 +214,14 @@ protected: } [[nodiscard]] T & - lookup(size_t pindex) + lookup(IndexT pindex) { return base::data()[index[pindex]]; } template<typename Pred> - glContainer<T>::iterator - partition(glContainer<T>::iterator first, glContainer<T>::iterator last, Pred pred) + base::iterator + partition(base::iterator first, base::iterator last, Pred pred) { while (first < last) { first = std::find_if_not(first, last, pred); @@ -183,8 +238,8 @@ protected: } // Index into buffer given to nth proxy - std::vector<size_t> index; - std::vector<size_t> reverseIndex; + glVector<IndexT> index; + std::vector<IndexT> reverseIndex; // List of free spaces in index - std::vector<size_t> unused; + std::vector<IndexT> unused; }; |
