Farewell, my zecsy_bits 😭
This commit is contained in:
parent
379973a224
commit
11ff925149
2 changed files with 28 additions and 38 deletions
|
@ -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
|
||||||
|
|
48
zecsy.hpp
48
zecsy.hpp
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue