Farewell, my zecsy_bits 😭

This commit is contained in:
NukeBird 2025-02-15 17:52:33 +03:00
parent 379973a224
commit 11ff925149
2 changed files with 28 additions and 38 deletions

View file

@ -39,16 +39,18 @@ TEST_CASE("Entity #0 should be reserved and never used")
REQUIRE_FALSE(entity().is_alive()); REQUIRE_FALSE(entity().is_alive());
} }
//TODO: doesn't make sense anymore? (I stopped limitting amount of entities)
TEST_CASE("World should throw on id overflow") TEST_CASE("World should throw on id overflow")
{ {
world w; /*world w;*/
/**/
for(int i = 0; i < MAX_ZECSY_ENTITIES; ++i) /*for(int i = 0; i < MAX_ZECSY_ENTITIES; ++i)*/
{ /*{*/
w.make_entity(); /* w.make_entity();*/
} /*}*/
/**/
REQUIRE_THROWS(w.make_entity()); /*REQUIRE_THROWS(w.make_entity());*/
REQUIRE(true);
} }
struct ChoosenOne struct ChoosenOne

View file

@ -1,21 +1,17 @@
#pragma once #pragma once
#include <catch2/internal/catch_console_colour.hpp> #include <catch2/internal/catch_console_colour.hpp>
#include <cstdint> #include <cstdint>
#include <bitset>
#include <format> #include <format>
#include <queue> #include <queue>
#include <stdexcept> #include <stdexcept>
#include <typeindex> #include <typeindex>
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#ifndef MAX_ZECSY_ENTITIES
#define MAX_ZECSY_ENTITIES 65536
#endif // !MAX_ZECSY_ENTITIES
namespace zecsy namespace zecsy
{ {
using entity_id = uint64_t; using entity_id = uint64_t;
using entities_set = std::unordered_set<entity_id>;
class entity final class entity final
{ {
@ -46,8 +42,6 @@ namespace zecsy
class world* w = nullptr; class world* w = nullptr;
}; };
using zecsy_bits = std::bitset<MAX_ZECSY_ENTITIES + 1>;
class component_storage class component_storage
{ {
public: public:
@ -80,7 +74,7 @@ namespace zecsy
void remove(entity_id e); void remove(entity_id e);
private: private:
using comp_index = std::type_index; using comp_index = std::type_index;
using comp_to_bitset = std::unordered_map<comp_index, zecsy_bits>; using comp_to_entities_set = std::unordered_map<comp_index, entities_set>;
using entity_to_index = std::unordered_map<entity_id, size_t>; using entity_to_index = std::unordered_map<entity_id, size_t>;
using comp_to_entity_dict = std::unordered_map<comp_index, using comp_to_entity_dict = std::unordered_map<comp_index,
@ -92,8 +86,8 @@ namespace zecsy
using comp_to_reusable_ids = std::unordered_map<comp_index, using comp_to_reusable_ids = std::unordered_map<comp_index,
std::queue<size_t>>; std::queue<size_t>>;
comp_to_bitset bitset_dict; comp_to_entities_set entities_dict;
comp_to_entity_dict entity_dict; comp_to_entity_dict indices_dict;
comp_to_storage storage_dict; comp_to_storage storage_dict;
comp_to_reusable_ids reusable_id_queues; comp_to_reusable_ids reusable_id_queues;
}; };
@ -120,7 +114,7 @@ namespace zecsy
template<typename... T> template<typename... T>
void remove(entity_id e); void remove(entity_id e);
private: private:
zecsy_bits entities_bitset; entities_set alive_entities;
entity_id entity_counter = 0; entity_id entity_counter = 0;
component_storage storage; component_storage storage;
}; };
@ -143,33 +137,27 @@ namespace zecsy
inline entity world::make_entity() inline entity world::make_entity()
{ {
auto id = ++entity_counter; auto id = ++entity_counter;
alive_entities.emplace(id);
if(id > MAX_ZECSY_ENTITIES)
{
throw std::runtime_error(std::format("Entity id {} exceeds "
"MAX_ZECSY_ENTITIES ({})", id, MAX_ZECSY_ENTITIES));
}
entities_bitset.set(id);
return entity(this, id); return entity(this, id);
} }
inline void world::destroy_entity(entity_id e) inline void world::destroy_entity(entity_id e)
{ {
entities_bitset.reset(e); alive_entities.erase(e);
} }
inline bool world::is_alive(entity_id e) const inline bool world::is_alive(entity_id e) const
{ {
return entities_bitset.test(e); return alive_entities.contains(e);
} }
template<typename T> template<typename T>
inline bool component_storage::has(entity_id e) const inline bool component_storage::has(entity_id e) const
{ {
if(bitset_dict.contains(typeid(T))) if(entities_dict.contains(typeid(T)))
{ {
return bitset_dict.at(typeid(T)).test(e); return entities_dict.at(typeid(T)).contains(e);
} }
return false; return false;
} }
@ -183,7 +171,7 @@ namespace zecsy
e, typeid(T).name())); e, typeid(T).name()));
} }
auto index = entity_dict[typeid(T)].at(e); auto index = indices_dict[typeid(T)].at(e);
auto* ptr = reinterpret_cast<T*>(&storage_dict[typeid(T)][0]); auto* ptr = reinterpret_cast<T*>(&storage_dict[typeid(T)][0]);
ptr += index; ptr += index;
@ -218,7 +206,7 @@ namespace zecsy
template<typename T> template<typename T>
inline void component_storage::set(entity_id e, const T& comp) inline void component_storage::set(entity_id e, const T& comp)
{ {
bitset_dict[typeid(T)].set(e); entities_dict[typeid(T)].emplace(e);
auto& storage = storage_dict[typeid(T)]; auto& storage = storage_dict[typeid(T)];
@ -233,7 +221,7 @@ namespace zecsy
void* ptr = &storage[0] + old_size; void* ptr = &storage[0] + old_size;
new(ptr) T(comp); new(ptr) T(comp);
entity_dict[typeid(T)][e] = old_size / T_size; indices_dict[typeid(T)][e] = old_size / T_size;
return; return;
} }
@ -243,7 +231,7 @@ namespace zecsy
auto ptr = reinterpret_cast<T*>(&storage[0]); auto ptr = reinterpret_cast<T*>(&storage[0]);
new(ptr + index) T(comp); new(ptr + index) T(comp);
entity_dict[typeid(T)][e] = index; indices_dict[typeid(T)][e] = index;
} }
template<typename... T> template<typename... T>
@ -272,9 +260,9 @@ namespace zecsy
return; return;
} }
bitset_dict[typeid(T)].reset(e); entities_dict[typeid(T)].erase(e);
reusable_id_queues[typeid(T)].push(entity_dict[typeid(T)][e]); reusable_id_queues[typeid(T)].push(indices_dict[typeid(T)][e]);
entity_dict[typeid(T)].erase(e); indices_dict[typeid(T)].erase(e);
} }
template<typename... T> template<typename... T>