WIP: swap/sort functionalities

This commit is contained in:
Michele Caini
2017-09-04 14:59:59 +02:00
parent aeaf1632c8
commit b35737b5d7
2 changed files with 79 additions and 1 deletions

View File

@@ -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));

View File

@@ -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();