WIP: swap/sort functionalities
This commit is contained in:
@@ -368,6 +368,23 @@ public:
|
||||
(void)accumulator;
|
||||
}
|
||||
|
||||
template<typename Comp>
|
||||
void swap(entity_type lhs, entity_type rhs) {
|
||||
std::get<ident<Component...>.template get<Comp>()>(pool).swap(lhs, rhs);
|
||||
}
|
||||
|
||||
template<typename Comp, typename Compare>
|
||||
void sort(Compare compare) {
|
||||
std::get<ident<Component...>.template get<Comp>()>(pool).sort(std::move(compare));
|
||||
}
|
||||
|
||||
template<typename To, typename From, typename Compare>
|
||||
void sort() {
|
||||
auto &&to = std::get<ident<Component...>.template get<To>()>(pool);
|
||||
auto &&from = std::get<ident<Component...>.template get<From>()>(pool);
|
||||
to.sort(from);
|
||||
}
|
||||
|
||||
template<typename Comp>
|
||||
void reset(entity_type entity) {
|
||||
assert(valid(entity));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define ENTT_COMPONENT_POOL_HPP
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
@@ -69,7 +70,7 @@ public:
|
||||
SparseSet(const SparseSet &) = delete;
|
||||
SparseSet(SparseSet &&) = default;
|
||||
|
||||
virtual ~SparseSet() noexcept {
|
||||
~SparseSet() noexcept {
|
||||
assert(empty());
|
||||
}
|
||||
|
||||
@@ -132,6 +133,14 @@ public:
|
||||
return pos;
|
||||
}
|
||||
|
||||
void swap(index_type lhs, index_type rhs) {
|
||||
assert(valid(lhs));
|
||||
assert(valid(rhs));
|
||||
|
||||
std::swap(direct[reverse[lhs]], direct[reverse[rhs]]);
|
||||
std::swap(reverse[lhs], reverse[rhs]);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
reverse.resize(0);
|
||||
direct.clear();
|
||||
@@ -145,6 +154,22 @@ private:
|
||||
|
||||
template<typename Index, typename Type>
|
||||
class SparseSet<Index, Type> final: public SparseSet<Index> {
|
||||
template<typename Compare>
|
||||
void arrange(Compare compare) {
|
||||
const auto *data = SparseSet<Index>::data();
|
||||
const auto size = SparseSet<Index>::size();
|
||||
std::vector<pos_type> copy(size);
|
||||
pos_type pos = 0;
|
||||
|
||||
std::generate(copy.begin(), copy.end(), [&pos]() { return pos++; });
|
||||
std::sort(copy.begin(), copy.end(), compare);
|
||||
|
||||
for(pos_type i = 0; i < copy.size(); ++i) {
|
||||
SparseSet<Index>::swap(data + copy[i], data + i);
|
||||
std::swap(instances[copy[i]], instances[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using type = Type;
|
||||
using index_type = typename SparseSet<Index>::index_type;
|
||||
@@ -189,6 +214,42 @@ public:
|
||||
instances.pop_back();
|
||||
}
|
||||
|
||||
void swap(index_type lhs, index_type rhs) {
|
||||
std::swap(SparseSet<Index>::get(lhs), SparseSet<Index>::get(rhs));
|
||||
SparseSet<Index>::swap(lhs, rhs);
|
||||
}
|
||||
|
||||
template<typename Compare>
|
||||
void sort(Compare compare) {
|
||||
arrange([this, compare = std::move(compare)](auto lhs, auto rhs) {
|
||||
return !compare(instances[lhs], instances[rhs]);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Idx>
|
||||
void sort(const SparseSet<Index> &other) {
|
||||
const auto *data = SparseSet<Index>::data();
|
||||
|
||||
arrange([data, &other](auto lhs, auto rhs) {
|
||||
auto eLhs = data + lhs;
|
||||
auto eRhs = data + rhs;
|
||||
|
||||
bool bLhs = other.has(eLhs);
|
||||
bool bRhs = other.has(eRhs);
|
||||
bool compare = false;
|
||||
|
||||
if(bLhs && bRhs) {
|
||||
compare = other.get(eLhs) < other.get(eRhs);
|
||||
} else if(!bLhs && !bRhs) {
|
||||
compare = eLhs < eRhs;
|
||||
} else {
|
||||
compare = bLhs;
|
||||
}
|
||||
|
||||
return !compare;
|
||||
});
|
||||
}
|
||||
|
||||
void reset() {
|
||||
SparseSet<Index>::reset();
|
||||
instances.clear();
|
||||
|
||||
Reference in New Issue
Block a user