Now have a 'destroy' method that removes everything related to an entity. Closes #18.

master
Zed A. Shaw 19 hours ago
parent 7602fb0b31
commit 6437bd3b54
  1. 28
      dinkyecs.hpp
  2. 6
      tests/dinkyecs.cpp

@ -19,7 +19,6 @@ namespace DinkyECS
template <typename T> template <typename T>
struct ComponentStorage { struct ComponentStorage {
std::vector<T> data; std::vector<T> data;
std::queue<size_t> free_indices;
}; };
struct Event { struct Event {
@ -36,12 +35,23 @@ namespace DinkyECS
std::unordered_map<std::type_index, std::any> $facts; std::unordered_map<std::type_index, std::any> $facts;
std::unordered_map<std::type_index, EventQueue> $events; std::unordered_map<std::type_index, EventQueue> $events;
std::unordered_map<std::type_index, std::any> $component_storages; std::unordered_map<std::type_index, std::any> $component_storages;
std::unordered_map<std::type_index, std::queue<size_t>> $free_indices;
std::unordered_map<Entity, bool> $constants; std::unordered_map<Entity, bool> $constants;
Entity entity() { return ++entity_count; } Entity entity() { return ++entity_count; }
void destroy(DinkyECS::Entity entity) { 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) { void clone_into(DinkyECS::World &to_world) {
@ -76,11 +86,12 @@ namespace DinkyECS
template <typename Comp> template <typename Comp>
size_t make_component() { size_t make_component() {
auto &storage = component_storage_for<Comp>(); auto &storage = component_storage_for<Comp>();
auto &free_queue = $free_indices.at(std::type_index(typeid(Comp)));
size_t index; size_t index;
if(!storage.free_indices.empty()) { if(!free_queue.empty()) {
index = storage.free_indices.front(); index = free_queue.front();
storage.free_indices.pop(); free_queue.pop();
} else { } else {
storage.data.emplace_back(); storage.data.emplace_back();
index = storage.data.size() - 1; index = storage.data.size() - 1;
@ -93,6 +104,7 @@ namespace DinkyECS
ComponentStorage<Comp> &component_storage_for() { ComponentStorage<Comp> &component_storage_for() {
auto type_index = std::type_index(typeid(Comp)); auto type_index = std::type_index(typeid(Comp));
$component_storages.try_emplace(type_index, ComponentStorage<Comp>{}); $component_storages.try_emplace(type_index, ComponentStorage<Comp>{});
$free_indices.try_emplace(type_index, std::queue<size_t>{});
return std::any_cast<ComponentStorage<Comp> &>( return std::any_cast<ComponentStorage<Comp> &>(
$component_storages.at(type_index)); $component_storages.at(type_index));
} }
@ -113,10 +125,10 @@ namespace DinkyECS
if(map.contains(ent)) { if(map.contains(ent)) {
size_t index = map.at(ent); size_t index = map.at(ent);
component_storage_for<Comp>().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 <typename Comp> template <typename Comp>

@ -199,4 +199,10 @@ TEST_CASE("can destroy all entity", "[ecs-destroy]") {
world.set<Velocity>(entity, {10,10}); world.set<Velocity>(entity, {10,10});
world.set<Gravity>(entity, {1}); world.set<Gravity>(entity, {1});
world.set<Motion>(entity, {0,0}); world.set<Motion>(entity, {0,0});
world.destroy(entity);
REQUIRE(!world.has<Velocity>(entity));
REQUIRE(!world.has<Gravity>(entity));
REQUIRE(!world.has<Motion>(entity));
} }

Loading…
Cancel
Save