Ability to remove components
This commit is contained in:
parent
a0f09710b0
commit
84b132f853
2 changed files with 75 additions and 7 deletions
|
@ -113,3 +113,19 @@ TEST_CASE("Retrieve a component from an entity and verify its data matches what
|
||||||
|
|
||||||
REQUIRE(e.get<Name>().value == "super-zecsy!");
|
REQUIRE(e.get<Name>().value == "super-zecsy!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Remove a component from an entity and verify it is no longer attached")
|
||||||
|
{
|
||||||
|
world w;
|
||||||
|
|
||||||
|
auto e = w.make_entity();
|
||||||
|
e.set(ChoosenOne{});
|
||||||
|
REQUIRE_NOTHROW(e.remove<ChoosenOne>());
|
||||||
|
|
||||||
|
REQUIRE_FALSE(e.has<ChoosenOne>());
|
||||||
|
|
||||||
|
e.set(ChoosenOne{});
|
||||||
|
REQUIRE_NOTHROW(w.remove<ChoosenOne>(e));
|
||||||
|
|
||||||
|
REQUIRE_FALSE(w.has<ChoosenOne>(e));
|
||||||
|
}
|
||||||
|
|
66
zecsy.hpp
66
zecsy.hpp
|
@ -2,10 +2,10 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
#include <queue>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#ifndef MAX_ZECSY_ENTITIES
|
#ifndef MAX_ZECSY_ENTITIES
|
||||||
#define MAX_ZECSY_ENTITIES 65536
|
#define MAX_ZECSY_ENTITIES 65536
|
||||||
|
@ -38,6 +38,9 @@ namespace zecsy
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void set(const T& comp = T{});
|
void set(const T& comp = T{});
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void remove();
|
||||||
private:
|
private:
|
||||||
entity_id id = 0;
|
entity_id id = 0;
|
||||||
class world* w = nullptr;
|
class world* w = nullptr;
|
||||||
|
@ -56,6 +59,9 @@ namespace zecsy
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void set(entity_id e, const T& comp = T{});
|
void set(entity_id e, const T& comp = T{});
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
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_bitset = std::unordered_map<comp_index, zecsy_bits>;
|
||||||
|
@ -67,9 +73,13 @@ namespace zecsy
|
||||||
using comp_to_storage = std::unordered_map<comp_index,
|
using comp_to_storage = std::unordered_map<comp_index,
|
||||||
std::vector<uint8_t>>;
|
std::vector<uint8_t>>;
|
||||||
|
|
||||||
|
using comp_to_reusable_ids = std::unordered_map<comp_index,
|
||||||
|
std::queue<size_t>>;
|
||||||
|
|
||||||
comp_to_bitset bitset_dict;
|
comp_to_bitset bitset_dict;
|
||||||
comp_to_entity_dict entity_dict;
|
comp_to_entity_dict entity_dict;
|
||||||
comp_to_storage storage_dict;
|
comp_to_storage storage_dict;
|
||||||
|
comp_to_reusable_ids reusable_id_queues;
|
||||||
};
|
};
|
||||||
|
|
||||||
class world final
|
class world final
|
||||||
|
@ -93,6 +103,9 @@ namespace zecsy
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void set(entity_id e, const T& comp = T{});
|
void set(entity_id e, const T& comp = T{});
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void remove(entity_id e);
|
||||||
private:
|
private:
|
||||||
zecsy_bits entities_bitset;
|
zecsy_bits entities_bitset;
|
||||||
entity_id entity_counter = 0;
|
entity_id entity_counter = 0;
|
||||||
|
@ -196,14 +209,28 @@ namespace zecsy
|
||||||
|
|
||||||
auto& storage = storage_dict[typeid(T)];
|
auto& storage = storage_dict[typeid(T)];
|
||||||
|
|
||||||
size_t T_size = sizeof(T);
|
auto& reusable_ids = reusable_id_queues[typeid(T)];
|
||||||
size_t old_size = storage.size();
|
|
||||||
|
|
||||||
storage.resize(old_size + T_size);
|
if(reusable_ids.empty())
|
||||||
void* ptr = &storage[0] + old_size;
|
{
|
||||||
new(ptr) T(comp);
|
size_t T_size = sizeof(T);
|
||||||
|
size_t old_size = storage.size();
|
||||||
|
|
||||||
entity_dict[typeid(T)][e] = old_size / T_size;
|
storage.resize(old_size + T_size);
|
||||||
|
void* ptr = &storage[0] + old_size;
|
||||||
|
new(ptr) T(comp);
|
||||||
|
|
||||||
|
entity_dict[typeid(T)][e] = old_size / T_size;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto index = reusable_ids.front();
|
||||||
|
reusable_ids.pop();
|
||||||
|
|
||||||
|
auto ptr = reinterpret_cast<T*>(&storage[0]);
|
||||||
|
new(ptr + index) T(comp);
|
||||||
|
|
||||||
|
entity_dict[typeid(T)][e] = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -217,4 +244,29 @@ namespace zecsy
|
||||||
{
|
{
|
||||||
w->set(id, comp);
|
w->set(id, comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void component_storage::remove(entity_id e)
|
||||||
|
{
|
||||||
|
if(!has<T>(e))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitset_dict[typeid(T)].reset(e);
|
||||||
|
reusable_id_queues[typeid(T)].push(entity_dict[typeid(T)][e]);
|
||||||
|
entity_dict[typeid(T)].erase(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void world::remove(entity_id e)
|
||||||
|
{
|
||||||
|
storage.remove<T>(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline void entity::remove()
|
||||||
|
{
|
||||||
|
w->remove<T>(id);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue