mirror of
https://github.com/BlackMATov/ecs.hpp.git
synced 2025-12-15 03:05:25 +07:00
273
ecs.hpp
273
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,98 +656,145 @@ 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, bool E = std::is_empty<T>::value >
|
||||||
class component_storage final : public component_storage_base {
|
class component_storage final : public component_storage_base {
|
||||||
public:
|
public:
|
||||||
component_storage(registry& owner);
|
component_storage(registry& owner)
|
||||||
|
: owner_(owner) {}
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
T& assign(entity_id id, Args&&... args);
|
T& assign(entity_id id, Args&&... args) {
|
||||||
bool exists(entity_id id) const noexcept;
|
components_.insert_or_assign(id, T(std::forward<Args>(args)...));
|
||||||
bool remove(entity_id id) noexcept override;
|
return components_.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
T* find(entity_id id) noexcept;
|
bool exists(entity_id id) const noexcept {
|
||||||
const T* find(entity_id id) const noexcept;
|
return components_.has(id);
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t count() const noexcept;
|
bool remove(entity_id id) noexcept override {
|
||||||
bool has(entity_id id) const noexcept override;
|
return components_.unordered_erase(id);
|
||||||
void clone(entity_id from, entity_id to) override;
|
}
|
||||||
|
|
||||||
|
T* find(entity_id id) noexcept {
|
||||||
|
return components_.find(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* find(entity_id id) const noexcept {
|
||||||
|
return components_.find(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t count() const noexcept {
|
||||||
|
return components_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(entity_id id) const noexcept override {
|
||||||
|
return components_.has(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clone(entity_id from, entity_id to) override {
|
||||||
|
const T* c = components_.find(from);
|
||||||
|
if ( c ) {
|
||||||
|
components_.insert_or_assign(to, *c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_component(F&& f);
|
void for_each_component(F&& f) {
|
||||||
|
for ( const entity_id id : components_ ) {
|
||||||
|
f(id, components_.get(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_component(F&& f) const;
|
void for_each_component(F&& f) const {
|
||||||
|
for ( const entity_id id : components_ ) {
|
||||||
|
f(id, components_.get(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t memory_usage() const noexcept override {
|
||||||
|
return components_.memory_usage();
|
||||||
|
}
|
||||||
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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
component_storage<T>::component_storage(registry& owner)
|
class component_storage<T, true> final : public component_storage_base {
|
||||||
: owner_(owner) {}
|
public:
|
||||||
|
component_storage(registry& owner)
|
||||||
|
: owner_(owner) {}
|
||||||
|
|
||||||
template < typename T >
|
template < typename... Args >
|
||||||
template < typename... Args >
|
T& assign(entity_id id, Args&&... args) {
|
||||||
T& component_storage<T>::assign(entity_id id, Args&&... args) {
|
components_.insert(id);
|
||||||
components_.insert_or_assign(id, T(std::forward<Args>(args)...));
|
return empty_value_;
|
||||||
return components_.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
bool component_storage<T>::exists(entity_id id) const noexcept {
|
|
||||||
return components_.has(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
bool component_storage<T>::remove(entity_id id) noexcept {
|
|
||||||
return components_.unordered_erase(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
T* component_storage<T>::find(entity_id id) noexcept {
|
|
||||||
return components_.find(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
const T* component_storage<T>::find(entity_id id) const noexcept {
|
|
||||||
return components_.find(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
std::size_t component_storage<T>::count() const noexcept {
|
|
||||||
return components_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
bool component_storage<T>::has(entity_id id) const noexcept {
|
|
||||||
return components_.has(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
void component_storage<T>::clone(entity_id from, entity_id to) {
|
|
||||||
const T* c = components_.find(from);
|
|
||||||
if ( c ) {
|
|
||||||
components_.insert_or_assign(to, *c);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
bool exists(entity_id id) const noexcept {
|
||||||
|
return components_.has(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool remove(entity_id id) noexcept override {
|
||||||
|
return components_.unordered_erase(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
T* find(entity_id id) noexcept {
|
||||||
|
return components_.has(id)
|
||||||
|
? &empty_value_
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* find(entity_id id) const noexcept {
|
||||||
|
return components_.has(id)
|
||||||
|
? &empty_value_
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t count() const noexcept {
|
||||||
|
return components_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(entity_id id) const noexcept override {
|
||||||
|
return components_.has(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clone(entity_id from, entity_id to) override {
|
||||||
|
if ( components_.has(from) ) {
|
||||||
|
components_.insert(to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename F >
|
||||||
|
void for_each_component(F&& f) {
|
||||||
|
for ( const entity_id id : components_ ) {
|
||||||
|
f(id, empty_value_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename F >
|
||||||
|
void for_each_component(F&& f) const {
|
||||||
|
for ( const entity_id id : components_ ) {
|
||||||
|
f(id, empty_value_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t memory_usage() const noexcept override {
|
||||||
|
return components_.memory_usage();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
registry& owner_;
|
||||||
|
static T empty_value_;
|
||||||
|
detail::sparse_set<entity_id, entity_id_indexer> components_;
|
||||||
|
};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
template < typename F >
|
T component_storage<T, true>::empty_value_;
|
||||||
void component_storage<T>::for_each_component(F&& f) {
|
|
||||||
for ( const entity_id id : components_ ) {
|
|
||||||
f(id, components_.get(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
template < typename F >
|
|
||||||
void component_storage<T>::for_each_component(F&& f) const {
|
|
||||||
for ( const entity_id id : components_ ) {
|
|
||||||
f(id, components_.get(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,7 +1094,7 @@ namespace ecs_hpp
|
|||||||
public:
|
public:
|
||||||
virtual ~component_applier_base() = default;
|
virtual ~component_applier_base() = default;
|
||||||
virtual component_applier_uptr clone() const = 0;
|
virtual component_applier_uptr clone() const = 0;
|
||||||
virtual void apply(entity& ent, bool override) const = 0;
|
virtual void apply_to(entity& ent, bool override) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
@@ -1046,7 +1103,7 @@ namespace ecs_hpp
|
|||||||
component_applier(std::tuple<Args...>&& args);
|
component_applier(std::tuple<Args...>&& args);
|
||||||
component_applier(const std::tuple<Args...>& args);
|
component_applier(const std::tuple<Args...>& args);
|
||||||
component_applier_uptr clone() const override;
|
component_applier_uptr clone() const override;
|
||||||
void apply(entity& ent, bool override) const override;
|
void apply_to(entity& ent, bool override) const override;
|
||||||
private:
|
private:
|
||||||
std::tuple<Args...> args_;
|
std::tuple<Args...> args_;
|
||||||
};
|
};
|
||||||
@@ -1067,15 +1124,18 @@ namespace ecs_hpp
|
|||||||
bool empty() const noexcept;
|
bool empty() const noexcept;
|
||||||
void swap(prototype& other) noexcept;
|
void swap(prototype& other) noexcept;
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T >
|
||||||
prototype& assign_component(Args&&... args) &;
|
bool has_component() const noexcept;
|
||||||
template < typename T, typename... Args >
|
|
||||||
prototype&& assign_component(Args&&... args) &&;
|
|
||||||
|
|
||||||
prototype& merge(const prototype& other, bool override) &;
|
template < typename T, typename... Args >
|
||||||
prototype&& merge(const prototype& other, bool override) &&;
|
prototype& component(Args&&... args) &;
|
||||||
|
template < typename T, typename... Args >
|
||||||
|
prototype&& component(Args&&... args) &&;
|
||||||
|
|
||||||
void apply(entity& ent, bool override) const;
|
prototype& merge_with(const prototype& other, bool override) &;
|
||||||
|
prototype&& merge_with(const prototype& other, bool override) &&;
|
||||||
|
|
||||||
|
void apply_to(entity& ent, bool override) const;
|
||||||
private:
|
private:
|
||||||
detail::sparse_map<
|
detail::sparse_map<
|
||||||
family_id,
|
family_id,
|
||||||
@@ -1234,6 +1294,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;
|
||||||
@@ -1732,7 +1801,7 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
void component_applier<T,Args...>::apply(entity& ent, bool override) const {
|
void component_applier<T,Args...>::apply_to(entity& ent, bool override) const {
|
||||||
detail::tiny_tuple_apply([&ent, override](const Args&... args){
|
detail::tiny_tuple_apply([&ent, override](const Args&... args){
|
||||||
if ( override || !ent.exists_component<T>() ) {
|
if ( override || !ent.exists_component<T>() ) {
|
||||||
ent.assign_component<T>(args...);
|
ent.assign_component<T>(args...);
|
||||||
@@ -1779,8 +1848,14 @@ namespace ecs_hpp
|
|||||||
swap(appliers_, other.appliers_);
|
swap(appliers_, other.appliers_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
bool prototype::has_component() const noexcept {
|
||||||
|
const auto family = detail::type_family<T>::id();
|
||||||
|
return appliers_.has(family);
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
prototype& prototype::assign_component(Args&&... args) & {
|
prototype& prototype::component(Args&&... args) & {
|
||||||
using applier_t = detail::component_applier<
|
using applier_t = detail::component_applier<
|
||||||
T,
|
T,
|
||||||
std::decay_t<Args>...>;
|
std::decay_t<Args>...>;
|
||||||
@@ -1792,12 +1867,12 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
prototype&& prototype::assign_component(Args&&... args) && {
|
prototype&& prototype::component(Args&&... args) && {
|
||||||
assign_component<T>(std::forward<Args>(args)...);
|
component<T>(std::forward<Args>(args)...);
|
||||||
return std::move(*this);
|
return std::move(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline prototype& prototype::merge(const prototype& other, bool override) & {
|
inline prototype& prototype::merge_with(const prototype& other, bool override) & {
|
||||||
for ( const auto family_id : other.appliers_ ) {
|
for ( const auto family_id : other.appliers_ ) {
|
||||||
if ( override || !appliers_.has(family_id) ) {
|
if ( override || !appliers_.has(family_id) ) {
|
||||||
appliers_.insert_or_assign(
|
appliers_.insert_or_assign(
|
||||||
@@ -1808,14 +1883,14 @@ namespace ecs_hpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline prototype&& prototype::merge(const prototype& other, bool override) && {
|
inline prototype&& prototype::merge_with(const prototype& other, bool override) && {
|
||||||
merge(other, override);
|
merge_with(other, override);
|
||||||
return std::move(*this);
|
return std::move(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void prototype::apply(entity& ent, bool override) const {
|
inline void prototype::apply_to(entity& ent, bool override) const {
|
||||||
for ( const auto family_id : appliers_ ) {
|
for ( const auto family_id : appliers_ ) {
|
||||||
appliers_.get(family_id)->apply(ent, override);
|
appliers_.get(family_id)->apply_to(ent, override);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1969,7 +2044,7 @@ namespace ecs_hpp
|
|||||||
inline entity registry::create_entity(const prototype& proto) {
|
inline entity registry::create_entity(const prototype& proto) {
|
||||||
auto ent = create_entity();
|
auto ent = create_entity();
|
||||||
try {
|
try {
|
||||||
proto.apply(ent, true);
|
proto.apply_to(ent, true);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
destroy_entity(ent);
|
destroy_entity(ent);
|
||||||
throw;
|
throw;
|
||||||
@@ -2217,6 +2292,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();
|
||||||
|
|||||||
126
ecs_tests.cpp
126
ecs_tests.cpp
@@ -28,6 +28,10 @@ namespace
|
|||||||
velocity_c(int nx, int ny) : x(nx), y(ny) {}
|
velocity_c(int nx, int ny) : x(nx), y(ny) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct movable_c {
|
||||||
|
};
|
||||||
|
static_assert(std::is_empty<movable_c>::value, "!!!");
|
||||||
|
|
||||||
bool operator==(const position_c& l, const position_c& r) noexcept {
|
bool operator==(const position_c& l, const position_c& r) noexcept {
|
||||||
return l.x == r.x
|
return l.x == r.x
|
||||||
&& l.y == r.y;
|
&& l.y == r.y;
|
||||||
@@ -518,7 +522,7 @@ TEST_CASE("registry") {
|
|||||||
SECTION("prototypes") {
|
SECTION("prototypes") {
|
||||||
{
|
{
|
||||||
ecs::prototype p;
|
ecs::prototype p;
|
||||||
p.assign_component<position_c>(1, 2);
|
p.component<position_c>(1, 2);
|
||||||
|
|
||||||
ecs::registry w;
|
ecs::registry w;
|
||||||
const auto e1 = w.create_entity(p);
|
const auto e1 = w.create_entity(p);
|
||||||
@@ -536,8 +540,8 @@ TEST_CASE("registry") {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
const auto p = ecs::prototype()
|
const auto p = ecs::prototype()
|
||||||
.assign_component<position_c>(1,2)
|
.component<position_c>(1,2)
|
||||||
.assign_component<velocity_c>(3,4);
|
.component<velocity_c>(3,4);
|
||||||
|
|
||||||
ecs::registry w;
|
ecs::registry w;
|
||||||
const auto e1 = w.create_entity(p);
|
const auto e1 = w.create_entity(p);
|
||||||
@@ -557,8 +561,8 @@ TEST_CASE("registry") {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
const auto p1 = ecs::prototype()
|
const auto p1 = ecs::prototype()
|
||||||
.assign_component<position_c>(1,2)
|
.component<position_c>(1,2)
|
||||||
.assign_component<velocity_c>(3,4);
|
.component<velocity_c>(3,4);
|
||||||
|
|
||||||
ecs::prototype p2 = p1;
|
ecs::prototype p2 = p1;
|
||||||
ecs::prototype p3;
|
ecs::prototype p3;
|
||||||
@@ -571,20 +575,20 @@ TEST_CASE("registry") {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
const auto p1 = ecs::prototype()
|
const auto p1 = ecs::prototype()
|
||||||
.assign_component<position_c>(1,2)
|
.component<position_c>(1,2)
|
||||||
.merge(ecs::prototype().assign_component<position_c>(3,4), false);
|
.merge_with(ecs::prototype().component<position_c>(3,4), false);
|
||||||
|
|
||||||
const auto p2 = ecs::prototype()
|
const auto p2 = ecs::prototype()
|
||||||
.assign_component<position_c>(1,2)
|
.component<position_c>(1,2)
|
||||||
.merge(ecs::prototype().assign_component<position_c>(3,4), true);
|
.merge_with(ecs::prototype().component<position_c>(3,4), true);
|
||||||
|
|
||||||
const auto p3 = ecs::prototype()
|
const auto p3 = ecs::prototype()
|
||||||
.assign_component<position_c>(1,2)
|
.component<position_c>(1,2)
|
||||||
.merge(ecs::prototype().assign_component<velocity_c>(3,4), false);
|
.merge_with(ecs::prototype().component<velocity_c>(3,4), false);
|
||||||
|
|
||||||
const auto p4 = ecs::prototype()
|
const auto p4 = ecs::prototype()
|
||||||
.assign_component<position_c>(1,2)
|
.component<position_c>(1,2)
|
||||||
.merge(ecs::prototype().assign_component<velocity_c>(3,4), true);
|
.merge_with(ecs::prototype().component<velocity_c>(3,4), true);
|
||||||
|
|
||||||
ecs::registry w;
|
ecs::registry w;
|
||||||
|
|
||||||
@@ -1154,6 +1158,102 @@ 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));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ecs::registry w;
|
||||||
|
auto e1 = w.create_entity();
|
||||||
|
auto e2 = w.create_entity();
|
||||||
|
e1.assign_component<movable_c>();
|
||||||
|
e2.assign_component<movable_c>();
|
||||||
|
REQUIRE(w.component_memory_usage<movable_c>() ==
|
||||||
|
4 * sizeof(std::size_t) +
|
||||||
|
2 * sizeof(ecs::entity_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SECTION("empty_component") {
|
||||||
|
ecs::registry w;
|
||||||
|
auto e1 = w.create_entity();
|
||||||
|
ecs::entity_filler(e1)
|
||||||
|
.component<movable_c>()
|
||||||
|
.component<position_c>(1, 2)
|
||||||
|
.component<velocity_c>(3, 4);
|
||||||
|
REQUIRE(w.exists_component<movable_c>(e1));
|
||||||
|
REQUIRE(w.find_component<movable_c>(e1));
|
||||||
|
w.for_joined_components<movable_c, position_c>([
|
||||||
|
](const ecs::const_entity&, movable_c&, position_c&){
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("example") {
|
TEST_CASE("example") {
|
||||||
|
|||||||
Reference in New Issue
Block a user