25 static constexpr uint32_t MaxNameLength = 256;
29 using FuncCtor = void(
void*, uint32_t);
30 using FuncDtor = void(
void*, uint32_t);
31 using FuncFrom = void(
void*,
void*, uint32_t, uint32_t, uint32_t, uint32_t);
32 using FuncCopy = void(
void*,
const void*, uint32_t, uint32_t, uint32_t, uint32_t);
33 using FuncMove = void(
void*,
void*, uint32_t, uint32_t, uint32_t, uint32_t);
34 using FuncSwap = void(
void*,
void*, uint32_t, uint32_t, uint32_t, uint32_t);
35 using FuncCmp = bool(
const void*,
const void*);
37 using FuncSave = void(
ser::ISerializer*,
const void*, uint32_t, uint32_t, uint32_t);
38 using FuncLoad = void(
ser::ISerializer*,
void*, uint32_t, uint32_t, uint32_t);
51 uint8_t soaSizes[meta::StructToTupleMaxTypes];
56 FuncCtor* func_ctor{};
58 FuncMove* func_move_ctor{};
60 FuncCopy* func_copy_ctor{};
62 FuncDtor* func_dtor{};
64 FuncCopy* func_copy{};
66 FuncMove* func_move{};
68 FuncSwap* func_swap{};
72 FuncSave* func_save{};
74 FuncLoad* func_load{};
78 #if GAIA_ENABLE_ADD_DEL_HOOKS
80 FuncOnAdd* func_add{};
82 FuncOnDel* func_del{};
84 #if GAIA_ENABLE_SET_HOOKS
86 FuncOnSet* func_set{};
93 ComponentCacheItem() =
default;
94 ~ComponentCacheItem() =
default;
97 ComponentCacheItem(
const ComponentCacheItem&) =
delete;
98 ComponentCacheItem(ComponentCacheItem&&) =
delete;
99 ComponentCacheItem& operator=(
const ComponentCacheItem&) =
delete;
100 ComponentCacheItem& operator=(ComponentCacheItem&&) =
delete;
103 ctor_move(
void* pDst,
void* pSrc, uint32_t idxDst, uint32_t idxSrc, uint32_t sizeDst, uint32_t sizeSrc)
const {
104 GAIA_ASSERT(func_move_ctor !=
nullptr && (pSrc != pDst || idxSrc != idxDst));
105 func_move_ctor(pDst, pSrc, idxDst, idxSrc, sizeDst, sizeSrc);
109 void* pDst,
const void* pSrc, uint32_t idxDst, uint32_t idxSrc, uint32_t sizeDst, uint32_t sizeSrc)
const {
110 GAIA_ASSERT(func_copy_ctor !=
nullptr && (pSrc != pDst || idxSrc != idxDst));
111 func_copy_ctor(pDst, pSrc, idxDst, idxSrc, sizeDst, sizeSrc);
114 void dtor(
void* pSrc)
const {
115 if (func_dtor !=
nullptr)
120 copy(
void* pDst,
const void* pSrc, uint32_t idxDst, uint32_t idxSrc, uint32_t sizeDst, uint32_t sizeSrc)
const {
121 GAIA_ASSERT(func_copy !=
nullptr && (pSrc != pDst || idxSrc != idxDst));
122 func_copy(pDst, pSrc, idxDst, idxSrc, sizeDst, sizeSrc);
125 void move(
void* pDst,
void* pSrc, uint32_t idxDst, uint32_t idxSrc, uint32_t sizeDst, uint32_t sizeSrc)
const {
126 GAIA_ASSERT(func_move !=
nullptr && (pSrc != pDst || idxSrc != idxDst));
127 func_move(pDst, pSrc, idxDst, idxSrc, sizeDst, sizeSrc);
131 swap(
void* pLeft,
void* pRight, uint32_t idxLeft, uint32_t idxRight, uint32_t sizeDst, uint32_t sizeSrc)
const {
132 GAIA_ASSERT(func_swap !=
nullptr);
133 func_swap(pLeft, pRight, idxLeft, idxRight, sizeDst, sizeSrc);
136 bool cmp(
const void* pLeft,
const void* pRight)
const {
137 GAIA_ASSERT(pLeft != pRight);
138 GAIA_ASSERT(func_cmp !=
nullptr);
139 return func_cmp(pLeft, pRight);
142 void save(ser::ISerializer* pSerializer,
const void* pSrc, uint32_t from, uint32_t to, uint32_t cap)
const {
143 GAIA_ASSERT(func_save !=
nullptr && pSrc !=
nullptr && from < to && to <= cap);
144 func_save(pSerializer, pSrc, from, to, cap);
147 void load(ser::ISerializer* pSerializer,
void* pDst, uint32_t from, uint32_t to, uint32_t cap)
const {
148 GAIA_ASSERT(func_load !=
nullptr && pDst !=
nullptr && from < to && to <= cap);
149 func_load(pSerializer, pDst, from, to, cap);
157 const Hooks& hooks()
const {
163 GAIA_NODISCARD uint32_t calc_new_mem_offset(uint32_t addr,
size_t cnt)
const noexcept {
164 if (comp.soa() == 0) {
165 addr = (uint32_t)mem::detail::get_aligned_byte_offset(addr, comp.alig(), comp.size(), cnt);
167 GAIA_FOR(comp.soa()) {
168 addr = (uint32_t)mem::detail::get_aligned_byte_offset(addr, comp.alig(), soaSizes[i], cnt);
173 addr += comp.soa() * 12;
178 template <
typename T>
179 GAIA_NODISCARD
static ComponentCacheItem* create(Entity entity) {
180 static_assert(core::is_raw_v<T>);
182 constexpr auto componentSize = detail::ComponentDesc<T>::size();
184 componentSize < Component::MaxComponentSizeInBytes,
185 "Trying to register a component larger than the maximum allowed component size! In the future this "
186 "restriction won't apply to components not stored inside archetype chunks.");
188 auto* cci = mem::AllocHelper::alloc<ComponentCacheItem>(
"ComponentCacheItem");
189 (void)
new (cci) ComponentCacheItem();
190 cci->entity = entity;
191 cci->comp = Component(
193 detail::ComponentDesc<T>::id(),
195 detail::ComponentDesc<T>::soa(cci->soaSizes),
199 detail::ComponentDesc<T>::alig());
200 cci->hashLookup = detail::ComponentDesc<T>::hash_lookup();
202 auto ct_name = detail::ComponentDesc<T>::name();
211 char nameTmp[MaxNameLength];
212 auto nameTmpLen = (uint32_t)ct_name.size();
213 GAIA_ASSERT(nameTmpLen < MaxNameLength);
214 memcpy((
void*)nameTmp, (
const void*)ct_name.data(), nameTmpLen + 1);
215 nameTmp[ct_name.size()] = 0;
218 const uint32_t NSubstrings = 2;
219 const char* to_remove[NSubstrings] = {
"class ",
"struct "};
220 const uint32_t to_remove_len[NSubstrings] = {6, 7};
221 GAIA_FOR(NSubstrings) {
222 const auto& str = to_remove[i];
223 const auto len = to_remove_len[i];
226 while ((pos = strstr(pos, str)) !=
nullptr) {
227 memmove(pos, pos + len, strlen(pos + len) + 1);
233 char* name = mem::AllocHelper::alloc<char>(nameTmpLen + 1);
234 memcpy((
void*)name, (
const void*)nameTmp, nameTmpLen + 1);
235 name[nameTmpLen] = 0;
237 cci->name = SymbolLookupKey(name, nameTmpLen, 1);
239 cci->func_ctor = detail::ComponentDesc<T>::func_ctor();
240 cci->func_move_ctor = detail::ComponentDesc<T>::func_move_ctor();
241 cci->func_copy_ctor = detail::ComponentDesc<T>::func_copy_ctor();
242 cci->func_dtor = detail::ComponentDesc<T>::func_dtor();
243 cci->func_copy = detail::ComponentDesc<T>::func_copy();
244 cci->func_move = detail::ComponentDesc<T>::func_move();
245 cci->func_swap = detail::ComponentDesc<T>::func_swap();
246 cci->func_cmp = detail::ComponentDesc<T>::func_cmp();
247 cci->func_save = detail::ComponentDesc<T>::func_save();
248 cci->func_load = detail::ComponentDesc<T>::func_load();
253 static void destroy(ComponentCacheItem* pItem) {
254 if (pItem ==
nullptr)
257 if (pItem->name.str() !=
nullptr && pItem->name.owned()) {
258 mem::AllocHelper::free((
void*)pItem->name.str());
262 pItem->~ComponentCacheItem();
263 mem::AllocHelper::free(
"ComponentCacheItem", pItem);