mirror of
https://github.com/BlackMATov/ecs.hpp.git
synced 2025-12-16 14:11:14 +07:00
don’t assign components to dead entities
This commit is contained in:
33
ecs.hpp
33
ecs.hpp
@@ -142,7 +142,7 @@ namespace ecs_hpp
|
|||||||
bool is_alive() const noexcept;
|
bool is_alive() const noexcept;
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
void assign_component(Args&&... args);
|
bool assign_component(Args&&... args);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool remove_component();
|
bool remove_component();
|
||||||
@@ -190,7 +190,7 @@ namespace ecs_hpp
|
|||||||
bool is_entity_alive(const entity& ent) const noexcept;
|
bool is_entity_alive(const entity& ent) const noexcept;
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
void assign_component(const entity& ent, Args&&... args);
|
bool assign_component(const entity& ent, Args&&... args);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool remove_component(const entity& ent);
|
bool remove_component(const entity& ent);
|
||||||
@@ -206,6 +206,7 @@ namespace ecs_hpp
|
|||||||
template < typename T >
|
template < typename T >
|
||||||
detail::component_storage<T>& get_or_create_storage_();
|
detail::component_storage<T>& 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;
|
std::size_t remove_all_components_impl_(const entity& ent) const noexcept;
|
||||||
private:
|
private:
|
||||||
mutable std::mutex mutex_;
|
mutable std::mutex mutex_;
|
||||||
@@ -250,8 +251,8 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
void entity::assign_component(Args&&... args) {
|
bool entity::assign_component(Args&&... args) {
|
||||||
owner_.assign_component<T>(
|
return owner_.assign_component<T>(
|
||||||
*this,
|
*this,
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
@@ -271,7 +272,8 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const entity& l, const entity& r) noexcept {
|
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 {
|
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 {
|
inline bool world::is_entity_alive(const entity& ent) const noexcept {
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
return entities_.count(ent) > 0u;
|
return is_entity_alive_impl_(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
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<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
if ( !is_entity_alive_impl_(ent) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
get_or_create_storage_<T>().assign(
|
get_or_create_storage_<T>().assign(
|
||||||
ent.id(),
|
ent.id(),
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool world::remove_component(const entity& ent) {
|
bool world::remove_component(const entity& ent) {
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
if ( !is_entity_alive_impl_(ent) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const detail::component_storage<T>* storage = find_storage_<T>();
|
const detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
return storage
|
return storage
|
||||||
? storage->remove(ent.id())
|
? storage->remove(ent.id())
|
||||||
@@ -329,6 +338,9 @@ namespace ecs_hpp
|
|||||||
template < typename T >
|
template < typename T >
|
||||||
bool world::exists_component(const entity& ent) const noexcept {
|
bool world::exists_component(const entity& ent) const noexcept {
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
if ( !is_entity_alive_impl_(ent) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const detail::component_storage<T>* storage = find_storage_<T>();
|
const detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
return storage
|
return storage
|
||||||
? storage->exists(ent.id())
|
? storage->exists(ent.id())
|
||||||
@@ -365,7 +377,14 @@ namespace ecs_hpp
|
|||||||
emplace_r.first->second.get());
|
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 {
|
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;
|
std::size_t removed_components = 0u;
|
||||||
for ( auto& storage_p : storages_ ) {
|
for ( auto& storage_p : storages_ ) {
|
||||||
if ( storage_p.second->remove(ent.id()) ) {
|
if ( storage_p.second->remove(ent.id()) ) {
|
||||||
|
|||||||
@@ -82,18 +82,18 @@ TEST_CASE("world") {
|
|||||||
SECTION("components") {
|
SECTION("components") {
|
||||||
{
|
{
|
||||||
ecs::world w;
|
ecs::world w;
|
||||||
ecs::entity e1{w};
|
ecs::entity e1 = w.create_entity();
|
||||||
|
|
||||||
{
|
{
|
||||||
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
||||||
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
||||||
|
|
||||||
w.assign_component<position_c>(e1);
|
REQUIRE(w.assign_component<position_c>(e1));
|
||||||
|
|
||||||
REQUIRE(w.exists_component<position_c>(e1));
|
REQUIRE(w.exists_component<position_c>(e1));
|
||||||
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
||||||
|
|
||||||
w.assign_component<velocity_c>(e1);
|
REQUIRE(w.assign_component<velocity_c>(e1));
|
||||||
|
|
||||||
REQUIRE(w.exists_component<position_c>(e1));
|
REQUIRE(w.exists_component<position_c>(e1));
|
||||||
REQUIRE(w.exists_component<velocity_c>(e1));
|
REQUIRE(w.exists_component<velocity_c>(e1));
|
||||||
@@ -108,12 +108,12 @@ TEST_CASE("world") {
|
|||||||
REQUIRE_FALSE(e1.exists_component<position_c>());
|
REQUIRE_FALSE(e1.exists_component<position_c>());
|
||||||
REQUIRE_FALSE(e1.exists_component<velocity_c>());
|
REQUIRE_FALSE(e1.exists_component<velocity_c>());
|
||||||
|
|
||||||
e1.assign_component<position_c>();
|
REQUIRE(e1.assign_component<position_c>());
|
||||||
|
|
||||||
REQUIRE(e1.exists_component<position_c>());
|
REQUIRE(e1.exists_component<position_c>());
|
||||||
REQUIRE_FALSE(e1.exists_component<velocity_c>());
|
REQUIRE_FALSE(e1.exists_component<velocity_c>());
|
||||||
|
|
||||||
e1.assign_component<velocity_c>();
|
REQUIRE(e1.assign_component<velocity_c>());
|
||||||
|
|
||||||
REQUIRE(e1.exists_component<position_c>());
|
REQUIRE(e1.exists_component<position_c>());
|
||||||
REQUIRE(e1.exists_component<velocity_c>());
|
REQUIRE(e1.exists_component<velocity_c>());
|
||||||
@@ -125,13 +125,13 @@ TEST_CASE("world") {
|
|||||||
auto e1 = w.create_entity();
|
auto e1 = w.create_entity();
|
||||||
auto e2 = w.create_entity();
|
auto e2 = w.create_entity();
|
||||||
|
|
||||||
w.assign_component<position_c>(e1);
|
REQUIRE(w.assign_component<position_c>(e1));
|
||||||
w.assign_component<velocity_c>(e1);
|
REQUIRE(w.assign_component<velocity_c>(e1));
|
||||||
|
|
||||||
w.assign_component<position_c>(e2);
|
REQUIRE(w.assign_component<position_c>(e2));
|
||||||
w.assign_component<velocity_c>(e2);
|
REQUIRE(w.assign_component<velocity_c>(e2));
|
||||||
|
|
||||||
w.destroy_entity(e1);
|
REQUIRE(w.destroy_entity(e1));
|
||||||
|
|
||||||
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
||||||
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
||||||
@@ -139,5 +139,12 @@ TEST_CASE("world") {
|
|||||||
REQUIRE(w.exists_component<position_c>(e2));
|
REQUIRE(w.exists_component<position_c>(e2));
|
||||||
REQUIRE(w.exists_component<velocity_c>(e2));
|
REQUIRE(w.exists_component<velocity_c>(e2));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
ecs::world w;
|
||||||
|
auto e1 = w.create_entity();
|
||||||
|
REQUIRE(e1.destroy());
|
||||||
|
REQUIRE_FALSE(e1.assign_component<position_c>());
|
||||||
|
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user