mirror of
https://github.com/BlackMATov/ecs.hpp.git
synced 2025-12-16 22:19:21 +07:00
memory usage stats
This commit is contained in:
45
ecs.hpp
45
ecs.hpp
@@ -426,6 +426,11 @@ namespace ecs_hpp
|
|||||||
std::size_t size() const noexcept {
|
std::size_t size() const noexcept {
|
||||||
return dense_.size();
|
return dense_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t memory_usage() const noexcept {
|
||||||
|
return dense_.capacity() * sizeof(dense_[0])
|
||||||
|
+ sparse_.capacity() * sizeof(sparse_[0]);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
Indexer indexer_;
|
Indexer indexer_;
|
||||||
std::vector<T> dense_;
|
std::vector<T> dense_;
|
||||||
@@ -595,6 +600,11 @@ namespace ecs_hpp
|
|||||||
std::size_t size() const noexcept {
|
std::size_t size() const noexcept {
|
||||||
return values_.size();
|
return values_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t memory_usage() const noexcept {
|
||||||
|
return keys_.memory_usage()
|
||||||
|
+ values_.capacity() * sizeof(values_[0]);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
sparse_set<K, Indexer> keys_;
|
sparse_set<K, Indexer> keys_;
|
||||||
std::vector<T> values_;
|
std::vector<T> values_;
|
||||||
@@ -646,6 +656,7 @@ namespace ecs_hpp
|
|||||||
virtual bool remove(entity_id id) noexcept = 0;
|
virtual bool remove(entity_id id) noexcept = 0;
|
||||||
virtual bool has(entity_id id) const noexcept = 0;
|
virtual bool has(entity_id id) const noexcept = 0;
|
||||||
virtual void clone(entity_id from, entity_id to) = 0;
|
virtual void clone(entity_id from, entity_id to) = 0;
|
||||||
|
virtual std::size_t memory_usage() const noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -669,6 +680,8 @@ namespace ecs_hpp
|
|||||||
void for_each_component(F&& f);
|
void for_each_component(F&& f);
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_component(F&& f) const;
|
void for_each_component(F&& f) const;
|
||||||
|
|
||||||
|
std::size_t memory_usage() const noexcept override;
|
||||||
private:
|
private:
|
||||||
registry& owner_;
|
registry& owner_;
|
||||||
detail::sparse_map<entity_id, T, entity_id_indexer> components_;
|
detail::sparse_map<entity_id, T, entity_id_indexer> components_;
|
||||||
@@ -738,6 +751,11 @@ namespace ecs_hpp
|
|||||||
f(id, components_.get(id));
|
f(id, components_.get(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
std::size_t component_storage<T>::memory_usage() const noexcept {
|
||||||
|
return components_.memory_usage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1234,6 +1252,15 @@ namespace ecs_hpp
|
|||||||
void process_systems_above(priority_t min);
|
void process_systems_above(priority_t min);
|
||||||
void process_systems_below(priority_t max);
|
void process_systems_below(priority_t max);
|
||||||
void process_systems_in_range(priority_t min, priority_t max);
|
void process_systems_in_range(priority_t min, priority_t max);
|
||||||
|
|
||||||
|
struct memory_usage_info {
|
||||||
|
std::size_t entities{0u};
|
||||||
|
std::size_t components{0u};
|
||||||
|
};
|
||||||
|
memory_usage_info memory_usage() const noexcept;
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
std::size_t component_memory_usage() const noexcept;
|
||||||
private:
|
private:
|
||||||
template < typename T >
|
template < typename T >
|
||||||
detail::component_storage<T>* find_storage_() noexcept;
|
detail::component_storage<T>* find_storage_() noexcept;
|
||||||
@@ -2217,6 +2244,24 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline registry::memory_usage_info registry::memory_usage() const noexcept {
|
||||||
|
memory_usage_info info;
|
||||||
|
info.entities += free_entity_ids_.capacity() * sizeof(free_entity_ids_[0]);
|
||||||
|
info.entities += entity_ids_.memory_usage();
|
||||||
|
for ( const auto family_id : storages_ ) {
|
||||||
|
info.components += storages_.get(family_id)->memory_usage();
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
std::size_t registry::component_memory_usage() const noexcept {
|
||||||
|
const detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
|
return storage
|
||||||
|
? storage->memory_usage()
|
||||||
|
: 0u;
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
detail::component_storage<T>* registry::find_storage_() noexcept {
|
detail::component_storage<T>* registry::find_storage_() noexcept {
|
||||||
const auto family = detail::type_family<T>::id();
|
const auto family = detail::type_family<T>::id();
|
||||||
|
|||||||
@@ -1154,6 +1154,79 @@ TEST_CASE("registry") {
|
|||||||
REQUIRE(e2.get_component<component_n>().i == 5);
|
REQUIRE(e2.get_component<component_n>().i == 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SECTION("memory_usage") {
|
||||||
|
{
|
||||||
|
ecs::registry w;
|
||||||
|
REQUIRE(w.memory_usage().entities == 0u);
|
||||||
|
|
||||||
|
auto e1 = w.create_entity();
|
||||||
|
auto e2 = w.create_entity();
|
||||||
|
|
||||||
|
const std::size_t expected_usage =
|
||||||
|
2 * sizeof(ecs::entity_id) + // vector free entity ids
|
||||||
|
4 * sizeof(std::size_t) + // sparse entity ids (keys)
|
||||||
|
2 * sizeof(ecs::entity_id); // sparse entity ids (values)
|
||||||
|
REQUIRE(w.memory_usage().entities == expected_usage);
|
||||||
|
|
||||||
|
e1.destroy();
|
||||||
|
e2.destroy();
|
||||||
|
REQUIRE(w.memory_usage().entities == expected_usage);
|
||||||
|
|
||||||
|
e1 = w.create_entity();
|
||||||
|
e2 = w.create_entity();
|
||||||
|
REQUIRE(w.memory_usage().entities == expected_usage);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ecs::registry w;
|
||||||
|
|
||||||
|
auto e1 = w.create_entity();
|
||||||
|
e1.assign_component<position_c>(1, 2);
|
||||||
|
|
||||||
|
auto e2 = w.create_entity();
|
||||||
|
e2.assign_component<position_c>(1, 2);
|
||||||
|
|
||||||
|
const std::size_t expected_usage =
|
||||||
|
2 * sizeof(position_c) + // vector values
|
||||||
|
4 * sizeof(std::size_t) + // sparse keys (keys)
|
||||||
|
2 * sizeof(ecs::entity_id); // sparse keys (values)
|
||||||
|
REQUIRE(w.memory_usage().components == expected_usage);
|
||||||
|
|
||||||
|
REQUIRE(w.component_memory_usage<position_c>() ==
|
||||||
|
2 * sizeof(position_c) +
|
||||||
|
4 * sizeof(std::size_t) +
|
||||||
|
2 * sizeof(ecs::entity_id));
|
||||||
|
|
||||||
|
REQUIRE_FALSE(w.component_memory_usage<velocity_c>());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ecs::registry w;
|
||||||
|
|
||||||
|
auto e1 = w.create_entity();
|
||||||
|
e1.assign_component<position_c>(1, 2);
|
||||||
|
|
||||||
|
auto e2 = w.create_entity();
|
||||||
|
e2.assign_component<velocity_c>(3, 4);
|
||||||
|
|
||||||
|
const std::size_t expected_usage =
|
||||||
|
sizeof(position_c) +
|
||||||
|
2 * sizeof(std::size_t) +
|
||||||
|
1 * sizeof(ecs::entity_id) +
|
||||||
|
sizeof(velocity_c) +
|
||||||
|
3 * sizeof(std::size_t) +
|
||||||
|
1 * sizeof(ecs::entity_id);
|
||||||
|
REQUIRE(w.memory_usage().components == expected_usage);
|
||||||
|
|
||||||
|
REQUIRE(w.component_memory_usage<position_c>() ==
|
||||||
|
sizeof(position_c) +
|
||||||
|
2 * sizeof(std::size_t) +
|
||||||
|
1 * sizeof(ecs::entity_id));
|
||||||
|
|
||||||
|
REQUIRE(w.component_memory_usage<velocity_c>() ==
|
||||||
|
sizeof(velocity_c) +
|
||||||
|
3 * sizeof(std::size_t) +
|
||||||
|
1 * sizeof(ecs::entity_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("example") {
|
TEST_CASE("example") {
|
||||||
|
|||||||
Reference in New Issue
Block a user