From 61e5bcef2629e2d68b805a956a96fff264d4f74d Mon Sep 17 00:00:00 2001 From: untodesu Date: Sat, 28 Jun 2025 01:59:49 +0500 Subject: Restructure dependencies and update to C++20 - Nuked static_assert from almost everywhere in the project - Nuked binary dependency support. Might add one later though - Separated dependency headers into a separate include subdirectory - Grafted a thirdpartylegalnotices.txt generator from RITEG - Pushed development snapshot version to 2126 (26th week of 2025) --- deps/include/entt/entity/observer.hpp | 438 ---------------------------------- 1 file changed, 438 deletions(-) delete mode 100644 deps/include/entt/entity/observer.hpp (limited to 'deps/include/entt/entity/observer.hpp') diff --git a/deps/include/entt/entity/observer.hpp b/deps/include/entt/entity/observer.hpp deleted file mode 100644 index 5698723..0000000 --- a/deps/include/entt/entity/observer.hpp +++ /dev/null @@ -1,438 +0,0 @@ -#ifndef ENTT_ENTITY_OBSERVER_HPP -#define ENTT_ENTITY_OBSERVER_HPP - -#include -#include -#include -#include -#include -#include "../core/type_traits.hpp" -#include "fwd.hpp" -#include "storage.hpp" - -namespace entt { - -/*! @brief Grouping matcher. */ -template -struct matcher {}; - -/** - * @brief Collector. - * - * Primary template isn't defined on purpose. All the specializations give a - * compile-time error, but for a few reasonable cases. - */ -template -struct basic_collector; - -/** - * @brief Collector. - * - * A collector contains a set of rules (literally, matchers) to use to track - * entities.
- * Its main purpose is to generate a descriptor that allows an observer to know - * how to connect to a registry. - */ -template<> -struct basic_collector<> { - /** - * @brief Adds a grouping matcher to the collector. - * @tparam AllOf Types of elements tracked by the matcher. - * @tparam NoneOf Types of elements used to filter out entities. - * @return The updated collector. - */ - template - static constexpr auto group(exclude_t = exclude_t{}) noexcept { - return basic_collector, type_list<>, type_list, AllOf...>>{}; - } - - /** - * @brief Adds an observing matcher to the collector. - * @tparam AnyOf Type of element for which changes should be detected. - * @return The updated collector. - */ - template - static constexpr auto update() noexcept { - return basic_collector, type_list<>, AnyOf>>{}; - } -}; - -/** - * @brief Collector. - * @copydetails basic_collector<> - * @tparam Reject Untracked types used to filter out entities. - * @tparam Require Untracked types required by the matcher. - * @tparam Rule Specific details of the current matcher. - * @tparam Other Other matchers. - */ -template -struct basic_collector, type_list, Rule...>, Other...> { - /*! @brief Current matcher. */ - using current_type = matcher, type_list, Rule...>; - - /** - * @brief Adds a grouping matcher to the collector. - * @tparam AllOf Types of elements tracked by the matcher. - * @tparam NoneOf Types of elements used to filter out entities. - * @return The updated collector. - */ - template - static constexpr auto group(exclude_t = exclude_t{}) noexcept { - return basic_collector, type_list<>, type_list, AllOf...>, current_type, Other...>{}; - } - - /** - * @brief Adds an observing matcher to the collector. - * @tparam AnyOf Type of element for which changes should be detected. - * @return The updated collector. - */ - template - static constexpr auto update() noexcept { - return basic_collector, type_list<>, AnyOf>, current_type, Other...>{}; - } - - /** - * @brief Updates the filter of the last added matcher. - * @tparam AllOf Types of elements required by the matcher. - * @tparam NoneOf Types of elements used to filter out entities. - * @return The updated collector. - */ - template - static constexpr auto where(exclude_t = exclude_t{}) noexcept { - using extended_type = matcher, type_list, Rule...>; - return basic_collector{}; - } -}; - -/*! @brief Variable template used to ease the definition of collectors. */ -inline constexpr basic_collector<> collector{}; - -/** - * @brief Observer. - * - * An observer returns all the entities and only the entities that fit the - * requirements of at least one matcher. Moreover, it's guaranteed that the - * entity list is tightly packed in memory for fast iterations.
- * In general, observers don't stay true to the order of any set of elements. - * - * Observers work mainly with two types of matchers, provided through a - * collector: - * - * * Observing matcher: an observer will return at least all the living entities - * for which one or more of the given elements have been updated and not yet - * destroyed. - * * Grouping matcher: an observer will return at least all the living entities - * that would have entered the given group if it existed and that would have - * not yet left it. - * - * If an entity respects the requirements of multiple matchers, it will be - * returned once and only once by the observer in any case. - * - * Matchers support also filtering by means of a _where_ clause that accepts - * both a list of types and an exclusion list.
- * Whenever a matcher finds that an entity matches its requirements, the - * condition of the filter is verified before to register the entity itself. - * Moreover, a registered entity isn't returned by the observer if the condition - * set by the filter is broken in the meantime. - * - * @b Important - * - * Iterators aren't invalidated if: - * - * * New instances of the given elements are created and assigned to entities. - * * The entity currently pointed is modified (as an example, if one of the - * given elements is removed from the entity to which the iterator points). - * * The entity currently pointed is destroyed. - * - * In all the other cases, modifying the pools of the given elements in any way - * invalidates all the iterators. - * - * @warning - * Lifetime of an observer doesn't necessarily have to overcome that of the - * registry to which it is connected. However, the observer must be disconnected - * from the registry before being destroyed to avoid crashes due to dangling - * pointers. - * - * @tparam Registry Basic registry type. - * @tparam Allocator Type of allocator used to manage memory and elements. - */ -template -class basic_observer { - using mask_type = std::uint64_t; - using storage_type = basic_storage::template rebind_alloc>; - - template - static void discard_if(storage_type &storage, Registry &, const typename Registry::entity_type entt) { - if(storage.contains(entt) && !(storage.get(entt) &= (~(1 << Index)))) { - storage.erase(entt); - } - } - - template - struct matcher_handler; - - template - struct matcher_handler, type_list, AnyOf>> { - template - static void maybe_valid_if(storage_type &storage, Registry &parent, const typename Registry::entity_type entt) { - if(parent.template all_of(entt) && !parent.template any_of(entt)) { - if(!storage.contains(entt)) { - storage.emplace(entt); - } - - storage.get(entt) |= (1 << Index); - } - } - - template - static void connect(storage_type &storage, Registry &parent) { - (parent.template on_destroy().template connect<&discard_if>(storage), ...); - (parent.template on_construct().template connect<&discard_if>(storage), ...); - parent.template on_update().template connect<&maybe_valid_if>(storage); - parent.template on_destroy().template connect<&discard_if>(storage); - } - - static void disconnect(storage_type &storage, Registry &parent) { - (parent.template on_destroy().disconnect(&storage), ...); - (parent.template on_construct().disconnect(&storage), ...); - parent.template on_update().disconnect(&storage); - parent.template on_destroy().disconnect(&storage); - } - }; - - template - struct matcher_handler, type_list, type_list, AllOf...>> { - template - static void maybe_valid_if(storage_type &storage, Registry &parent, const typename Registry::entity_type entt) { - bool guard{}; - - if constexpr(sizeof...(Ignore) == 0) { - guard = parent.template all_of(entt) && !parent.template any_of(entt); - } else { - guard = parent.template all_of(entt) && ((std::is_same_v || !parent.template any_of(entt)) && ...) && !parent.template any_of(entt); - } - - if(guard) { - if(!storage.contains(entt)) { - storage.emplace(entt); - } - - storage.get(entt) |= (1 << Index); - } - } - - template - static void connect(storage_type &storage, Registry &parent) { - (parent.template on_destroy().template connect<&discard_if>(storage), ...); - (parent.template on_construct().template connect<&discard_if>(storage), ...); - (parent.template on_construct().template connect<&maybe_valid_if>(storage), ...); - (parent.template on_destroy().template connect<&maybe_valid_if>(storage), ...); - (parent.template on_destroy().template connect<&discard_if>(storage), ...); - (parent.template on_construct().template connect<&discard_if>(storage), ...); - } - - static void disconnect(storage_type &storage, Registry &parent) { - (parent.template on_destroy().disconnect(&storage), ...); - (parent.template on_construct().disconnect(&storage), ...); - (parent.template on_construct().disconnect(&storage), ...); - (parent.template on_destroy().disconnect(&storage), ...); - (parent.template on_destroy().disconnect(&storage), ...); - (parent.template on_construct().disconnect(&storage), ...); - } - }; - - template - static void disconnect(Registry &parent, storage_type &storage) { - (matcher_handler::disconnect(storage, parent), ...); - } - - template - static void connect(Registry &parent, storage_type &storage, std::index_sequence) { - static_assert(sizeof...(Matcher) < std::numeric_limits::digits, "Too many matchers"); - (matcher_handler::template connect(storage, parent), ...); - } - -public: - /*! @brief Allocator type. */ - using allocator_type = Allocator; - /*! Basic registry type. */ - using registry_type = Registry; - /*! @brief Underlying entity identifier. */ - using entity_type = typename registry_type::entity_type; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Random access iterator type. */ - using iterator = typename registry_type::common_type::iterator; - - /*! @brief Default constructor. */ - basic_observer() - : basic_observer{allocator_type{}} {} - - /** - * @brief Constructs an empty storage with a given allocator. - * @param allocator The allocator to use. - */ - explicit basic_observer(const allocator_type &allocator) - : release{}, - parent{}, - storage{allocator} {} - - /*! @brief Default copy constructor, deleted on purpose. */ - basic_observer(const basic_observer &) = delete; - - /*! @brief Default move constructor, deleted on purpose. */ - basic_observer(basic_observer &&) = delete; - - /** - * @brief Creates an observer and connects it to a given registry. - * @tparam Matcher Types of matchers to use to initialize the observer. - * @param reg A valid reference to a registry. - * @param allocator The allocator to use. - */ - template - basic_observer(registry_type ®, basic_collector, const allocator_type &allocator = allocator_type{}) - : release{&basic_observer::disconnect}, - parent{®}, - storage{allocator} { - connect(reg, storage, std::index_sequence_for{}); - } - - /*! @brief Default destructor. */ - ~basic_observer() noexcept = default; - - /** - * @brief Default copy assignment operator, deleted on purpose. - * @return This observer. - */ - basic_observer &operator=(const basic_observer &) = delete; - - /** - * @brief Default move assignment operator, deleted on purpose. - * @return This observer. - */ - basic_observer &operator=(basic_observer &&) = delete; - - /** - * @brief Connects an observer to a given registry. - * @tparam Matcher Types of matchers to use to initialize the observer. - * @param reg A valid reference to a registry. - */ - template - void connect(registry_type ®, basic_collector) { - disconnect(); - storage.clear(); - - parent = ® - release = &basic_observer::disconnect; - connect(reg, storage, std::index_sequence_for{}); - } - - /*! @brief Disconnects an observer from the registry it keeps track of. */ - void disconnect() { - if(release) { - release(*parent, storage); - release = nullptr; - } - } - - /** - * @brief Returns the number of elements in an observer. - * @return Number of elements. - */ - [[nodiscard]] size_type size() const noexcept { - return storage.size(); - } - - /** - * @brief Checks whether an observer is empty. - * @return True if the observer is empty, false otherwise. - */ - [[nodiscard]] bool empty() const noexcept { - return storage.empty(); - } - - /** - * @brief Direct access to the list of entities of the observer. - * - * The returned pointer is such that range `[data(), data() + size())` is - * always a valid range, even if the container is empty. - * - * @note - * Entities are in the reverse order as returned by the `begin`/`end` - * iterators. - * - * @return A pointer to the array of entities. - */ - [[nodiscard]] const entity_type *data() const noexcept { - return storage.data(); - } - - /** - * @brief Returns an iterator to the first entity of the observer. - * - * If the observer is empty, the returned iterator will be equal to `end()`. - * - * @return An iterator to the first entity of the observer. - */ - [[nodiscard]] iterator begin() const noexcept { - return storage.storage_type::base_type::begin(); - } - - /** - * @brief Returns an iterator that is past the last entity of the observer. - * @return An iterator to the entity following the last entity of the - * observer. - */ - [[nodiscard]] iterator end() const noexcept { - return storage.storage_type::base_type::end(); - } - - /*! @brief Clears the underlying container. */ - void clear() noexcept { - storage.clear(); - } - - /** - * @brief Iterates entities and applies the given function object to them. - * - * The function object is invoked for each entity.
- * The signature of the function must be equivalent to the following form: - * - * @code{.cpp} - * void(const entity_type); - * @endcode - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) const { - for(const auto entity: *this) { - func(entity); - } - } - - /** - * @brief Iterates entities and applies the given function object to them, - * then clears the observer. - * - * @sa each - * - * @tparam Func Type of the function object to invoke. - * @param func A valid function object. - */ - template - void each(Func func) { - std::as_const(*this).each(std::move(func)); - clear(); - } - -private: - void (*release)(registry_type &, storage_type &); - registry_type *parent; - storage_type storage; -}; - -} // namespace entt - -#endif -- cgit