observer: derive from storage rather than using one internally
This commit is contained in:
1
TODO
1
TODO
@@ -13,6 +13,7 @@ DOC:
|
||||
* update entity doc when the storage based model is in place
|
||||
|
||||
WIP:
|
||||
* sparse set/storage support for move-only types, internal rework required
|
||||
* get rid of observers, storage based views made them pointless - document alternatives
|
||||
* dense_map/set and registry: move ctor/op should be noexcept (op is conditionally noexcept though)
|
||||
* add storage getter for filters to views and groups
|
||||
|
||||
@@ -158,8 +158,8 @@ inline constexpr basic_collector<> collector{};
|
||||
* @tparam Registry Basic registry type.
|
||||
*/
|
||||
template<typename Registry>
|
||||
class basic_observer {
|
||||
using payload_type = std::uint32_t;
|
||||
class basic_observer: private basic_storage<std::uint32_t, typename Registry::entity_type> {
|
||||
using base_type = basic_storage<std::uint32_t, typename Registry::entity_type>;
|
||||
|
||||
template<typename>
|
||||
struct matcher_handler;
|
||||
@@ -169,18 +169,18 @@ class basic_observer {
|
||||
template<std::size_t Index>
|
||||
static void maybe_valid_if(basic_observer &obs, Registry ®, const typename Registry::entity_type entt) {
|
||||
if(reg.template all_of<Require...>(entt) && !reg.template any_of<Reject...>(entt)) {
|
||||
if(!obs.storage.contains(entt)) {
|
||||
obs.storage.emplace(entt);
|
||||
if(!obs.contains(entt)) {
|
||||
obs.emplace(entt);
|
||||
}
|
||||
|
||||
obs.storage.get(entt) |= (1 << Index);
|
||||
obs.get(entt) |= (1 << Index);
|
||||
}
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void discard_if(basic_observer &obs, Registry &, const typename Registry::entity_type entt) {
|
||||
if(obs.storage.contains(entt) && !(obs.storage.get(entt) &= (~(1 << Index)))) {
|
||||
obs.storage.erase(entt);
|
||||
if(obs.contains(entt) && !(obs.get(entt) &= (~(1 << Index)))) {
|
||||
obs.erase(entt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,18 +213,18 @@ class basic_observer {
|
||||
};
|
||||
|
||||
if(condition()) {
|
||||
if(!obs.storage.contains(entt)) {
|
||||
obs.storage.emplace(entt);
|
||||
if(!obs.contains(entt)) {
|
||||
obs.emplace(entt);
|
||||
}
|
||||
|
||||
obs.storage.get(entt) |= (1 << Index);
|
||||
obs.get(entt) |= (1 << Index);
|
||||
}
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void discard_if(basic_observer &obs, Registry &, const typename Registry::entity_type entt) {
|
||||
if(obs.storage.contains(entt) && !(obs.storage.get(entt) &= (~(1 << Index)))) {
|
||||
obs.storage.erase(entt);
|
||||
if(obs.contains(entt) && !(obs.get(entt) &= (~(1 << Index)))) {
|
||||
obs.erase(entt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ class basic_observer {
|
||||
|
||||
template<typename... Matcher, std::size_t... Index>
|
||||
void connect(Registry ®, std::index_sequence<Index...>) {
|
||||
static_assert(sizeof...(Matcher) < std::numeric_limits<payload_type>::digits, "Too many matchers");
|
||||
static_assert(sizeof...(Matcher) < std::numeric_limits<typename base_type::value_type>::digits, "Too many matchers");
|
||||
(matcher_handler<Matcher>::template connect<Index>(*this, reg), ...);
|
||||
release.template connect<&basic_observer::disconnect<Matcher...>>(reg);
|
||||
}
|
||||
@@ -272,8 +272,7 @@ public:
|
||||
|
||||
/*! @brief Default constructor. */
|
||||
basic_observer()
|
||||
: release{},
|
||||
storage{} {}
|
||||
: release{} {}
|
||||
|
||||
/*! @brief Default copy constructor, deleted on purpose. */
|
||||
basic_observer(const basic_observer &) = delete;
|
||||
@@ -315,7 +314,7 @@ public:
|
||||
void connect(registry_type ®, basic_collector<Matcher...>) {
|
||||
disconnect();
|
||||
connect<Matcher...>(reg, std::index_sequence_for<Matcher...>{});
|
||||
storage.clear();
|
||||
base_type::clear();
|
||||
}
|
||||
|
||||
/*! @brief Disconnects an observer from the registry it keeps track of. */
|
||||
@@ -331,7 +330,7 @@ public:
|
||||
* @return Number of elements.
|
||||
*/
|
||||
[[nodiscard]] size_type size() const noexcept {
|
||||
return storage.size();
|
||||
return base_type::size();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,7 +338,7 @@ public:
|
||||
* @return True if the observer is empty, false otherwise.
|
||||
*/
|
||||
[[nodiscard]] bool empty() const noexcept {
|
||||
return storage.empty();
|
||||
return base_type::empty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,7 +354,7 @@ public:
|
||||
* @return A pointer to the array of entities.
|
||||
*/
|
||||
[[nodiscard]] const entity_type *data() const noexcept {
|
||||
return storage.data();
|
||||
return base_type::data();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,7 +366,7 @@ public:
|
||||
* @return An iterator to the first entity of the observer.
|
||||
*/
|
||||
[[nodiscard]] iterator begin() const noexcept {
|
||||
return storage.registry_type::base_type::begin();
|
||||
return base_type::base_type::begin();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,12 +380,12 @@ public:
|
||||
* observer.
|
||||
*/
|
||||
[[nodiscard]] iterator end() const noexcept {
|
||||
return storage.registry_type::base_type::end();
|
||||
return base_type::base_type::end();
|
||||
}
|
||||
|
||||
/*! @brief Clears the underlying container. */
|
||||
void clear() noexcept {
|
||||
storage.clear();
|
||||
base_type::clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -426,7 +425,6 @@ public:
|
||||
|
||||
private:
|
||||
delegate<void(basic_observer &)> release;
|
||||
basic_storage<payload_type, entity_type> storage;
|
||||
};
|
||||
|
||||
} // namespace entt
|
||||
|
||||
Reference in New Issue
Block a user