From 783376c6fc5f43fbd962c889aba97bac5e088eb3 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 10 Apr 2019 03:56:30 +0700 Subject: [PATCH] return component reference from assign. rename alive to valid. fix entity component_count function. --- ecs.hpp | 104 +++++++++++++++++++++++--------------------------- ecs_tests.cpp | 102 ++++++++++++++++++------------------------------- 2 files changed, 85 insertions(+), 121 deletions(-) diff --git a/ecs.hpp b/ecs.hpp index 8f9e4b8..cd30ce9 100644 --- a/ecs.hpp +++ b/ecs.hpp @@ -597,7 +597,7 @@ namespace ecs_hpp component_storage(registry& owner); template < typename... Args > - void assign(entity_id id, Args&&... args); + T& assign(entity_id id, Args&&... args); bool exists(entity_id id) const noexcept; bool remove(entity_id id) noexcept override; @@ -623,8 +623,9 @@ namespace ecs_hpp template < typename T > template < typename... Args > - void component_storage::assign(entity_id id, Args&&... args) { + T& component_storage::assign(entity_id id, Args&&... args) { components_.insert_or_assign(id, T(std::forward(args)...)); + return components_.get(id); } template < typename T > @@ -708,11 +709,11 @@ namespace ecs_hpp entity_id id() const noexcept; bool destroy(); - bool alive() const noexcept; entity clone() const; + bool valid() const noexcept; template < typename T, typename... Args > - bool assign_component(Args&&... args); + T& assign_component(Args&&... args); template < typename T > bool remove_component(); @@ -743,6 +744,8 @@ namespace ecs_hpp std::tuple find_components() noexcept; template < typename... Ts > std::tuple find_components() const noexcept; + + std::size_t component_count() const noexcept; private: registry* owner_{nullptr}; entity_id id_{0u}; @@ -795,7 +798,7 @@ namespace ecs_hpp const registry& owner() const noexcept; entity_id id() const noexcept; - bool alive() const noexcept; + bool valid() const noexcept; template < typename T > bool exists_component() const noexcept; @@ -811,6 +814,8 @@ namespace ecs_hpp template < typename... Ts > std::tuple find_components() const noexcept; + + std::size_t component_count() const noexcept; private: const registry* owner_{nullptr}; entity_id id_{0u}; @@ -865,7 +870,7 @@ namespace ecs_hpp bool exists() const noexcept; template < typename... Args > - bool assign(Args&&... args); + T& assign(Args&&... args); T& get(); const T& get() const; @@ -1046,10 +1051,10 @@ namespace ecs_hpp entity create_entity(const const_uentity& prototype); bool destroy_entity(const uentity& ent); - bool alive_entity(const const_uentity& ent) const noexcept; + bool valid_entity(const const_uentity& ent) const noexcept; template < typename T, typename... Args > - bool assign_component(const uentity& ent, Args&&... args); + T& assign_component(const uentity& ent, Args&&... args); template < typename T > bool remove_component(const uentity& ent); @@ -1081,7 +1086,6 @@ namespace ecs_hpp template < typename T > std::size_t component_count() const noexcept; - template < typename T > std::size_t entity_component_count(const const_uentity& ent) const noexcept; template < typename F > @@ -1252,16 +1256,16 @@ namespace ecs_hpp return (*owner_).destroy_entity(id_); } - inline bool entity::alive() const noexcept { - return detail::as_const(*owner_).alive_entity(id_); - } - inline entity entity::clone() const { return (*owner_).create_entity(id_); } + inline bool entity::valid() const noexcept { + return detail::as_const(*owner_).valid_entity(id_); + } + template < typename T, typename... Args > - bool entity::assign_component(Args&&... args) { + T& entity::assign_component(Args&&... args) { return (*owner_).assign_component( id_, std::forward(args)...); @@ -1321,6 +1325,10 @@ namespace ecs_hpp return detail::as_const(*owner_).find_components(id_); } + inline std::size_t entity::component_count() const noexcept { + return detail::as_const(*owner_).entity_component_count(id_); + } + inline bool operator<(const entity& l, const entity& r) noexcept { return (&l.owner() < &r.owner()) || (&l.owner() == &r.owner() && l.id() < r.id()); @@ -1372,8 +1380,8 @@ namespace ecs_hpp return id_; } - inline bool const_entity::alive() const noexcept { - return (*owner_).alive_entity(id_); + inline bool const_entity::valid() const noexcept { + return (*owner_).valid_entity(id_); } template < typename T > @@ -1401,6 +1409,10 @@ namespace ecs_hpp return (*owner_).find_components(id_); } + inline std::size_t const_entity::component_count() const noexcept { + return (*owner_).entity_component_count(id_); + } + inline bool operator<(const const_entity& l, const const_entity& r) noexcept { return (&l.owner() < &r.owner()) || (&l.owner() == &r.owner() && l.id() < r.id()); @@ -1459,7 +1471,7 @@ namespace ecs_hpp template < typename T > template < typename... Args > - bool component::assign(Args&&... args) { + T& component::assign(Args&&... args) { return owner_.assign_component( std::forward(args)...); } @@ -1708,11 +1720,8 @@ namespace ecs_hpp } inline entity registry::create_entity(const const_uentity& prototype) { - assert(prototype.check_owner(this)); + assert(valid_entity(prototype)); entity ent = create_entity(); - if ( !alive_entity(prototype) ) { - return ent; - } try { for ( const auto family_id : storages_ ) { storages_.get(family_id)->clone(prototype, ent.id()); @@ -1725,7 +1734,7 @@ namespace ecs_hpp } inline bool registry::destroy_entity(const uentity& ent) { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); remove_all_components(ent); if ( entity_ids_.unordered_erase(ent) ) { free_entity_ids_.push_back(ent); @@ -1734,29 +1743,22 @@ namespace ecs_hpp return false; } - inline bool registry::alive_entity(const const_uentity& ent) const noexcept { + inline bool registry::valid_entity(const const_uentity& ent) const noexcept { assert(ent.check_owner(this)); return entity_ids_.has(ent); } template < typename T, typename... Args > - bool registry::assign_component(const uentity& ent, Args&&... args) { - assert(ent.check_owner(this)); - if ( !alive_entity(ent) ) { - return false; - } - get_or_create_storage_().assign( + T& registry::assign_component(const uentity& ent, Args&&... args) { + assert(valid_entity(ent)); + return get_or_create_storage_().assign( ent, std::forward(args)...); - return true; } template < typename T > bool registry::remove_component(const uentity& ent) { - assert(ent.check_owner(this)); - if ( !alive_entity(ent) ) { - return false; - } + assert(valid_entity(ent)); detail::component_storage* storage = find_storage_(); return storage ? storage->remove(ent) @@ -1765,10 +1767,7 @@ namespace ecs_hpp template < typename T > bool registry::exists_component(const const_uentity& ent) const noexcept { - assert(ent.check_owner(this)); - if ( !alive_entity(ent) ) { - return false; - } + assert(valid_entity(ent)); const detail::component_storage* storage = find_storage_(); return storage ? storage->exists(ent) @@ -1776,10 +1775,7 @@ namespace ecs_hpp } inline std::size_t registry::remove_all_components(const uentity& ent) noexcept { - assert(ent.check_owner(this)); - if ( !alive_entity(ent) ) { - return 0u; - } + assert(valid_entity(ent)); std::size_t removed_count = 0u; for ( const auto family_id : storages_ ) { if ( storages_.get(family_id)->remove(ent) ) { @@ -1791,7 +1787,7 @@ namespace ecs_hpp template < typename T > T& registry::get_component(const uentity& ent) { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); T* component = find_component(ent); if ( component ) { return *component; @@ -1801,7 +1797,7 @@ namespace ecs_hpp template < typename T > const T& registry::get_component(const const_uentity& ent) const { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); const T* component = find_component(ent); if ( component ) { return *component; @@ -1811,7 +1807,7 @@ namespace ecs_hpp template < typename T > T* registry::find_component(const uentity& ent) noexcept { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); detail::component_storage* storage = find_storage_(); return storage ? storage->find(ent) @@ -1820,7 +1816,7 @@ namespace ecs_hpp template < typename T > const T* registry::find_component(const const_uentity& ent) const noexcept { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); const detail::component_storage* storage = find_storage_(); return storage ? storage->find(ent) @@ -1829,25 +1825,25 @@ namespace ecs_hpp template < typename... Ts > std::tuple registry::get_components(const uentity& ent) { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); return std::make_tuple(std::ref(get_component(ent))...); } template < typename... Ts > std::tuple registry::get_components(const const_uentity& ent) const { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); return std::make_tuple(std::cref(get_component(ent))...); } template < typename... Ts > std::tuple registry::find_components(const uentity& ent) noexcept { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); return std::make_tuple(find_component(ent)...); } template < typename... Ts > std::tuple registry::find_components(const const_uentity& ent) const noexcept { - assert(ent.check_owner(this)); + assert(valid_entity(ent)); return std::make_tuple(find_component(ent)...); } @@ -1859,12 +1855,8 @@ namespace ecs_hpp : 0u; } - template < typename T > - std::size_t registry::entity_component_count(const const_uentity& ent) const noexcept { - assert(ent.check_owner(this)); - if ( !alive_entity(ent) ) { - return 0u; - } + inline std::size_t registry::entity_component_count(const const_uentity& ent) const noexcept { + assert(valid_entity(ent)); std::size_t component_count = 0u; for ( const auto family_id : storages_ ) { if ( storages_.get(family_id)->has(ent) ) { diff --git a/ecs_tests.cpp b/ecs_tests.cpp index 072968a..53f3df6 100644 --- a/ecs_tests.cpp +++ b/ecs_tests.cpp @@ -330,12 +330,9 @@ TEST_CASE("registry") { REQUIRE_FALSE(e1 != e2); REQUIRE_FALSE(e2 != e3); - REQUIRE_FALSE(w.alive_entity(e1)); - REQUIRE_FALSE(w.alive_entity(e2)); - REQUIRE_FALSE(w.alive_entity(e3)); - - REQUIRE_FALSE(w.destroy_entity(e1)); - REQUIRE_FALSE(w.destroy_entity(e2)); + REQUIRE_FALSE(w.valid_entity(e1)); + REQUIRE_FALSE(w.valid_entity(e2)); + REQUIRE_FALSE(w.valid_entity(e3)); } { ecs::registry w; @@ -353,26 +350,22 @@ TEST_CASE("registry") { REQUIRE_FALSE(e2 == e3); REQUIRE(e3 == ee3); - REQUIRE(w.alive_entity(e1)); - REQUIRE(w.alive_entity(e2)); - REQUIRE(w.alive_entity(e3)); - REQUIRE(w.alive_entity(ee3)); + REQUIRE(w.valid_entity(e1)); + REQUIRE(w.valid_entity(e2)); + REQUIRE(w.valid_entity(e3)); + REQUIRE(w.valid_entity(ee3)); REQUIRE(w.destroy_entity(e1)); - REQUIRE_FALSE(w.alive_entity(e1)); - REQUIRE(w.alive_entity(e2)); + REQUIRE_FALSE(w.valid_entity(e1)); + REQUIRE(w.valid_entity(e2)); REQUIRE(w.destroy_entity(e2)); - REQUIRE_FALSE(w.alive_entity(e1)); - REQUIRE_FALSE(w.alive_entity(e2)); + REQUIRE_FALSE(w.valid_entity(e1)); + REQUIRE_FALSE(w.valid_entity(e2)); REQUIRE(w.destroy_entity(ee3)); - REQUIRE_FALSE(w.alive_entity(e3)); - REQUIRE_FALSE(w.alive_entity(ee3)); - - REQUIRE_FALSE(w.destroy_entity(e1)); - REQUIRE_FALSE(w.destroy_entity(e2)); - REQUIRE_FALSE(w.destroy_entity(ee3)); + REQUIRE_FALSE(w.valid_entity(e3)); + REQUIRE_FALSE(w.valid_entity(ee3)); } { ecs::registry w; @@ -469,7 +462,7 @@ TEST_CASE("registry") { REQUIRE_THROWS_AS(c1.get(), std::logic_error); REQUIRE_THROWS_AS(c2.get(), std::logic_error); - REQUIRE(c1.assign(4,2)); + REQUIRE(c1.assign(4,2) == position_c(4,2)); REQUIRE(c1.exists()); REQUIRE(c2.exists()); @@ -482,7 +475,7 @@ TEST_CASE("registry") { REQUIRE(c2.get().x == 4); REQUIRE(c2.get().y == 2); - REQUIRE(c1.assign(2,4)); + REQUIRE(&c1.assign(2,4) == &c1.get()); REQUIRE(c1.find()->x == 2); REQUIRE(c1.find()->y == 4); @@ -514,20 +507,23 @@ TEST_CASE("registry") { REQUIRE_FALSE(w.exists_component(e1)); REQUIRE_FALSE(w.exists_component(e1)); REQUIRE_FALSE(w.component_count()); - REQUIRE_FALSE(w.entity_component_count(e1)); + REQUIRE_FALSE(w.entity_component_count(e1)); + REQUIRE_FALSE(e1.component_count()); - REQUIRE(w.assign_component(e1)); + REQUIRE(w.assign_component(e1) == position_c()); REQUIRE(w.exists_component(e1)); REQUIRE_FALSE(w.exists_component(e1)); REQUIRE(w.component_count() == 1u); REQUIRE(w.component_count() == 0u); - REQUIRE(w.entity_component_count(e1) == 1u); + REQUIRE(w.entity_component_count(e1) == 1u); + REQUIRE(e1.component_count() == 1u); - REQUIRE(w.assign_component(e1)); + REQUIRE(w.assign_component(e1) == velocity_c()); REQUIRE(w.component_count() == 1u); REQUIRE(w.component_count() == 1u); - REQUIRE(w.entity_component_count(e1) == 2u); + REQUIRE(w.entity_component_count(e1) == 2u); + REQUIRE(e1.component_count() == 2u); REQUIRE(w.exists_component(e1)); REQUIRE(w.exists_component(e1)); @@ -538,30 +534,28 @@ TEST_CASE("registry") { REQUIRE_FALSE(w.exists_component(e1)); REQUIRE_FALSE(w.component_count()); REQUIRE_FALSE(w.component_count()); - REQUIRE_FALSE(w.entity_component_count(e1)); + REQUIRE_FALSE(w.entity_component_count(e1)); + REQUIRE_FALSE(e1.component_count()); } { REQUIRE_FALSE(e1.exists_component()); REQUIRE_FALSE(e1.exists_component()); - REQUIRE(e1.assign_component()); + REQUIRE(e1.assign_component() == position_c()); REQUIRE(e1.exists_component()); REQUIRE_FALSE(e1.exists_component()); - REQUIRE(e1.assign_component()); + REQUIRE(e1.assign_component() == velocity_c()); REQUIRE(e1.exists_component()); REQUIRE(e1.exists_component()); REQUIRE(e1.destroy()); - REQUIRE_FALSE(e1.exists_component()); - REQUIRE_FALSE(e1.exists_component()); REQUIRE_FALSE(w.component_count()); REQUIRE_FALSE(w.component_count()); - REQUIRE_FALSE(w.entity_component_count(e1)); } } { @@ -570,37 +564,30 @@ TEST_CASE("registry") { auto e1 = w.create_entity(); auto e2 = w.create_entity(); - REQUIRE(w.assign_component(e1)); - REQUIRE(w.assign_component(e1)); + w.assign_component(e1); + w.assign_component(e1); - REQUIRE(w.assign_component(e2)); - REQUIRE(w.assign_component(e2)); + w.assign_component(e2); + w.assign_component(e2); REQUIRE(w.destroy_entity(e1)); - REQUIRE_FALSE(w.exists_component(e1)); - REQUIRE_FALSE(w.exists_component(e1)); - REQUIRE(w.exists_component(e2)); REQUIRE(w.exists_component(e2)); } - { - ecs::registry w; - auto e1 = w.create_entity(); - REQUIRE(e1.destroy()); - REQUIRE_FALSE(e1.assign_component()); - REQUIRE_FALSE(w.exists_component(e1)); - } { ecs::registry w; auto e1 = w.create_entity(); auto e2 = w.create_entity(); - REQUIRE(w.assign_component(e1)); + const position_c& e1_pos = w.assign_component(e1); + REQUIRE(&e1_pos == &w.get_component(e1)); - REQUIRE(w.assign_component(e2)); - REQUIRE(w.assign_component(e2)); + const position_c& e2_pos = w.assign_component(e2); + const velocity_c& e2_vel = w.assign_component(e2); + REQUIRE(&e2_pos == &w.get_component(e2)); + REQUIRE(&e2_vel == &w.get_component(e2)); REQUIRE(e1.destroy()); } @@ -759,21 +746,6 @@ TEST_CASE("registry") { REQUIRE_FALSE(e3.exists_component()); REQUIRE(e3.get_component() == position_c(1, 2)); } - { - ecs::registry w; - - auto e1 = w.create_entity(); - ecs::entity_filler(e1) - .component(1, 2) - .component(3, 4); - e1.destroy(); - - auto e2 = e1.clone(); - REQUIRE_FALSE(e2.exists_component()); - REQUIRE_FALSE(e2.exists_component()); - REQUIRE(w.component_count() == 0); - REQUIRE(w.component_count() == 0); - } } SECTION("for_each_entity") { {