From 93586919013c3b3e4d868fcd88e5015bd328aaf2 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Mon, 18 Dec 2017 14:08:38 +0100 Subject: [PATCH] added reserve --- src/entt/entity/registry.hpp | 41 +++++++++++++++++++++++++++++++--- src/entt/entity/sparse_set.hpp | 30 +++++++++++++++++++++++-- src/entt/process/scheduler.hpp | 4 ++-- src/entt/signal/sigh.hpp | 4 ++-- 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index c8bed1b4d..7e55964fc 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -154,6 +154,13 @@ class Registry { return *handlers[vtype]; } + Entity candidate() const noexcept { + auto entity = entity_type(entities.size()); + assert(entity < traits_type::entity_mask); + assert((entity >> traits_type::entity_shift) == entity_type{}); + return entity; + } + public: /*! @brief Underlying entity identifier. */ using entity_type = typename traits_type::entity_type; @@ -231,6 +238,36 @@ public: return entities.size() - available.size(); } + /** + * @brief Increases the capacity of the pool for a given component. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @tparam Component Type of component for which to reserve storage. + * @tparam cap Desired capacity. + */ + template + void reserve(size_type cap) { + ensure().reserve(cap); + } + + /** + * @brief Increases the capacity of a registry in terms of entities. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @tparam cap Desired capacity. + */ + void reserve(size_type cap) { + const auto last = entity_type(cap); + + for(auto entity = candidate(); entity < last; ++entity) { + available.push_back(entity); + } + } + /** * @brief Returns the number of entities ever created. * @return Number of entities ever created. @@ -380,9 +417,7 @@ public: entity_type entity; if(available.empty()) { - entity = entity_type(entities.size()); - assert(entity < traits_type::entity_mask); - assert((entity >> traits_type::entity_shift) == entity_type{}); + entity = candidate(); entities.push_back(entity); } else { entity = available.back(); diff --git a/src/entt/entity/sparse_set.hpp b/src/entt/entity/sparse_set.hpp index 2df07156d..d21899b82 100644 --- a/src/entt/entity/sparse_set.hpp +++ b/src/entt/entity/sparse_set.hpp @@ -117,6 +117,19 @@ public: /*! @brief Default move assignment operator. @return This sparse set. */ SparseSet & operator=(SparseSet &&) = default; + /** + * @brief Increases the capacity of a sparse set. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @tparam cap Desired capacity. + */ + void reserve(size_type cap) { + reverse.reserve(cap); + direct.reserve(cap); + } + /** * @brief Returns the number of elements in a sparse set. * @@ -400,6 +413,19 @@ public: /*! @brief Default move assignment operator. @return This sparse set. */ SparseSet & operator=(SparseSet &&) = default; + /** + * @brief Increases the capacity of a sparse set. + * + * If the new capacity is greater than the current capacity, new storage is + * allocated, otherwise the method does nothing. + * + * @tparam cap Desired capacity. + */ + void reserve(size_type cap) { + underlying_type::reserve(cap); + instances.reserve(cap); + } + /** * @brief Direct access to the array of objects. * @@ -541,8 +567,8 @@ public: return compare(const_cast(instances[rhs]), const_cast(instances[lhs])); }); - for(pos_type i = 0; i < copy.size(); ++i) { - auto curr = i; + for(pos_type pos = 0, last = copy.size(); pos < last; ++pos) { + auto curr = pos; auto next = copy[curr]; while(curr != next) { diff --git a/src/entt/process/scheduler.hpp b/src/entt/process/scheduler.hpp index 6c7d04f66..9087aebd6 100644 --- a/src/entt/process/scheduler.hpp +++ b/src/entt/process/scheduler.hpp @@ -273,8 +273,8 @@ public: void update(Delta delta) { bool clean = false; - for(auto i = handlers.size(); i > 0; --i) { - auto &handler = handlers[i-1]; + for(auto pos = handlers.size(); pos > 0; --pos) { + auto &handler = handlers[pos-1]; const bool dead = handler.update(handler, delta); clean = clean || dead; } diff --git a/src/entt/signal/sigh.hpp b/src/entt/signal/sigh.hpp index 6e2899c6a..36098d8fd 100644 --- a/src/entt/signal/sigh.hpp +++ b/src/entt/signal/sigh.hpp @@ -25,14 +25,14 @@ struct Invoker { virtual ~Invoker() = default; template - typename std::enable_if::value, bool>::type + typename std::enable_if_t::value, bool> invoke(Collector &, proto_type proto, void *instance, Args... args) { proto(instance, args...); return true; } template - typename std::enable_if::value, bool>::type + typename std::enable_if_t::value, bool> invoke(Collector &collector, proto_type proto, void *instance, Args... args) { return collector(proto(instance, args...)); }