diff --git a/ecs.hpp b/ecs.hpp index 336958e..ac46daf 100644 --- a/ecs.hpp +++ b/ecs.hpp @@ -142,7 +142,7 @@ namespace ecs_hpp bool is_alive() const noexcept; template < typename T, typename... Args > - void assign_component(Args&&... args); + bool assign_component(Args&&... args); template < typename T > bool remove_component(); @@ -190,7 +190,7 @@ namespace ecs_hpp bool is_entity_alive(const entity& ent) const noexcept; template < typename T, typename... Args > - void assign_component(const entity& ent, Args&&... args); + bool assign_component(const entity& ent, Args&&... args); template < typename T > bool remove_component(const entity& ent); @@ -206,6 +206,7 @@ namespace ecs_hpp template < typename T > detail::component_storage& get_or_create_storage_(); + bool is_entity_alive_impl_(const entity& ent) const noexcept; std::size_t remove_all_components_impl_(const entity& ent) const noexcept; private: mutable std::mutex mutex_; @@ -250,8 +251,8 @@ namespace ecs_hpp } template < typename T, typename... Args > - void entity::assign_component(Args&&... args) { - owner_.assign_component( + bool entity::assign_component(Args&&... args) { + return owner_.assign_component( *this, std::forward(args)...); } @@ -271,7 +272,8 @@ namespace ecs_hpp } inline bool operator==(const entity& l, const entity& r) noexcept { - return l.id() == r.id(); + return &l.owner() == &r.owner() + && l.id() == r.id(); } inline bool operator!=(const entity& l, const entity& r) noexcept { @@ -306,20 +308,27 @@ namespace ecs_hpp inline bool world::is_entity_alive(const entity& ent) const noexcept { std::lock_guard guard(mutex_); - return entities_.count(ent) > 0u; + return is_entity_alive_impl_(ent); } template < typename T, typename... Args > - void world::assign_component(const entity& ent, Args&&... args) { + bool world::assign_component(const entity& ent, Args&&... args) { std::lock_guard guard(mutex_); + if ( !is_entity_alive_impl_(ent) ) { + return false; + } get_or_create_storage_().assign( ent.id(), std::forward(args)...); + return true; } template < typename T > bool world::remove_component(const entity& ent) { std::lock_guard guard(mutex_); + if ( !is_entity_alive_impl_(ent) ) { + return false; + } const detail::component_storage* storage = find_storage_(); return storage ? storage->remove(ent.id()) @@ -329,6 +338,9 @@ namespace ecs_hpp template < typename T > bool world::exists_component(const entity& ent) const noexcept { std::lock_guard guard(mutex_); + if ( !is_entity_alive_impl_(ent) ) { + return false; + } const detail::component_storage* storage = find_storage_(); return storage ? storage->exists(ent.id()) @@ -365,7 +377,14 @@ namespace ecs_hpp emplace_r.first->second.get()); } + inline bool world::is_entity_alive_impl_(const entity& ent) const noexcept { + return entities_.count(ent) > 0u; + } + inline std::size_t world::remove_all_components_impl_(const entity& ent) const noexcept { + if ( !is_entity_alive_impl_(ent) ) { + return 0u; + } std::size_t removed_components = 0u; for ( auto& storage_p : storages_ ) { if ( storage_p.second->remove(ent.id()) ) { diff --git a/ecs_tests.cpp b/ecs_tests.cpp index 851c72c..f5bc2dd 100644 --- a/ecs_tests.cpp +++ b/ecs_tests.cpp @@ -82,18 +82,18 @@ TEST_CASE("world") { SECTION("components") { { ecs::world w; - ecs::entity e1{w}; + ecs::entity e1 = w.create_entity(); { REQUIRE_FALSE(w.exists_component(e1)); REQUIRE_FALSE(w.exists_component(e1)); - w.assign_component(e1); + REQUIRE(w.assign_component(e1)); REQUIRE(w.exists_component(e1)); REQUIRE_FALSE(w.exists_component(e1)); - w.assign_component(e1); + REQUIRE(w.assign_component(e1)); REQUIRE(w.exists_component(e1)); REQUIRE(w.exists_component(e1)); @@ -108,12 +108,12 @@ TEST_CASE("world") { REQUIRE_FALSE(e1.exists_component()); REQUIRE_FALSE(e1.exists_component()); - e1.assign_component(); + REQUIRE(e1.assign_component()); REQUIRE(e1.exists_component()); REQUIRE_FALSE(e1.exists_component()); - e1.assign_component(); + REQUIRE(e1.assign_component()); REQUIRE(e1.exists_component()); REQUIRE(e1.exists_component()); @@ -125,13 +125,13 @@ TEST_CASE("world") { auto e1 = w.create_entity(); auto e2 = w.create_entity(); - w.assign_component(e1); - w.assign_component(e1); + REQUIRE(w.assign_component(e1)); + REQUIRE(w.assign_component(e1)); - w.assign_component(e2); - w.assign_component(e2); + REQUIRE(w.assign_component(e2)); + REQUIRE(w.assign_component(e2)); - w.destroy_entity(e1); + REQUIRE(w.destroy_entity(e1)); REQUIRE_FALSE(w.exists_component(e1)); REQUIRE_FALSE(w.exists_component(e1)); @@ -139,5 +139,12 @@ TEST_CASE("world") { REQUIRE(w.exists_component(e2)); REQUIRE(w.exists_component(e2)); } + { + ecs::world w; + auto e1 = w.create_entity(); + REQUIRE(e1.destroy()); + REQUIRE_FALSE(e1.assign_component()); + REQUIRE_FALSE(w.exists_component(e1)); + } } }