From 6437bd3b549d9889cd9f5e2e2255fd68c7d4a69e Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Sat, 28 Jun 2025 12:47:17 -0400 Subject: [PATCH] Now have a 'destroy' method that removes everything related to an entity. Closes #18. --- dinkyecs.hpp | 28 ++++++++++++++++++++-------- tests/dinkyecs.cpp | 6 ++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/dinkyecs.hpp b/dinkyecs.hpp index b29ed63..99bbb89 100644 --- a/dinkyecs.hpp +++ b/dinkyecs.hpp @@ -19,7 +19,6 @@ namespace DinkyECS template struct ComponentStorage { std::vector data; - std::queue free_indices; }; struct Event { @@ -36,12 +35,23 @@ namespace DinkyECS std::unordered_map $facts; std::unordered_map $events; std::unordered_map $component_storages; + std::unordered_map> $free_indices; std::unordered_map $constants; Entity entity() { return ++entity_count; } void destroy(DinkyECS::Entity entity) { - (void)entity; + dbc::check(!$constants.contains(entity), "trying to destroy an entity in constants"); + + for(auto& [tid, map] : $components) { + + if(map.contains(entity)) { + size_t index = map.at(entity); + auto& free_queue = $free_indices.at(tid); + free_queue.push(index); + map.erase(entity); + } + } } void clone_into(DinkyECS::World &to_world) { @@ -76,11 +86,12 @@ namespace DinkyECS template size_t make_component() { auto &storage = component_storage_for(); + auto &free_queue = $free_indices.at(std::type_index(typeid(Comp))); size_t index; - if(!storage.free_indices.empty()) { - index = storage.free_indices.front(); - storage.free_indices.pop(); + if(!free_queue.empty()) { + index = free_queue.front(); + free_queue.pop(); } else { storage.data.emplace_back(); index = storage.data.size() - 1; @@ -93,6 +104,7 @@ namespace DinkyECS ComponentStorage &component_storage_for() { auto type_index = std::type_index(typeid(Comp)); $component_storages.try_emplace(type_index, ComponentStorage{}); + $free_indices.try_emplace(type_index, std::queue{}); return std::any_cast &>( $component_storages.at(type_index)); } @@ -113,10 +125,10 @@ namespace DinkyECS if(map.contains(ent)) { size_t index = map.at(ent); - component_storage_for().free_indices.push(index); + auto& free_queue = $free_indices.at(std::type_index(typeid(Comp))); + free_queue.push(index); + map.erase(ent); } - - map.erase(ent); } template diff --git a/tests/dinkyecs.cpp b/tests/dinkyecs.cpp index ccf6ba5..59d4978 100644 --- a/tests/dinkyecs.cpp +++ b/tests/dinkyecs.cpp @@ -199,4 +199,10 @@ TEST_CASE("can destroy all entity", "[ecs-destroy]") { world.set(entity, {10,10}); world.set(entity, {1}); world.set(entity, {0,0}); + + world.destroy(entity); + + REQUIRE(!world.has(entity)); + REQUIRE(!world.has(entity)); + REQUIRE(!world.has(entity)); }