76 using FuncCtor = void(
void*, uint32_t);
77 using FuncDtor = void(
void*, uint32_t);
78 using FuncFrom = void(
void*,
void*, uint32_t, uint32_t, uint32_t, uint32_t);
79 using FuncCopy = void(
void*,
const void*, uint32_t, uint32_t, uint32_t, uint32_t);
80 using FuncMove = void(
void*,
void*, uint32_t, uint32_t, uint32_t, uint32_t);
81 using FuncSwap = void(
void*,
void*, uint32_t, uint32_t, uint32_t, uint32_t);
82 using FuncCmp = bool(
const void*,
const void*);
83 using FuncSave = void(
ser::serializer&,
const void*, uint32_t, uint32_t, uint32_t);
84 using FuncLoad = void(
ser::serializer&,
void*, uint32_t, uint32_t, uint32_t);
101 RuntimeTypeKind
typeKind = RuntimeTypeKind::Struct;
106 FuncMove* funcMoveCtor =
nullptr;
107 FuncCopy* funcCopyCtor =
nullptr;
108 FuncDtor* funcDtor =
nullptr;
109 FuncCopy* funcCopy =
nullptr;
110 FuncMove* funcMove =
nullptr;
111 FuncSwap* funcSwap =
nullptr;
112 FuncCmp* funcCmp =
nullptr;
113 FuncSave* funcSave =
nullptr;
114 FuncLoad* funcLoad =
nullptr;
120 using CT = component_type_t<T>;
121 using U =
typename component_type_t<T>::Type;
122 using DescU =
typename CT::TypeFull;
125 return {meta::type_info::hash<DescU>()};
128 static constexpr auto name() {
129 return meta::type_info::name<DescU>();
132 static constexpr uint32_t size() {
133 if constexpr (std::is_empty_v<U>)
136 return (uint32_t)
sizeof(U);
139 static constexpr uint32_t alig() {
141 static_assert(alig < Component::MaxAlignment,
"Maximum supported alignment for a component is MaxAlignment");
146 if constexpr (mem::is_soa_layout_v<U>) {
148 using TTuple =
decltype(meta::struct_to_tuple(std::declval<U>()));
150 constexpr auto TTupleSize = std::tuple_size_v<TTuple>;
151 static_assert(TTupleSize > 0);
152 static_assert(TTupleSize <= meta::StructToTupleMaxTypes);
153 core::each_tuple<TTuple>([&](
auto&& item) {
154 static_assert(
sizeof(item) <= 255,
"Each member of a SoA component can be at most 255 B long!");
155 soaSizes[i] = (uint8_t)
sizeof(item);
158 GAIA_ASSERT(i <= meta::StructToTupleMaxTypes);
165 static constexpr auto func_ctor() {
166 if constexpr (!mem::is_soa_layout_v<U> && !std::is_trivially_constructible_v<U>) {
167 return [](
void* ptr, uint32_t cnt) {
168 core::call_ctor_n((U*)ptr, cnt);
175 static constexpr auto func_dtor() {
176 if constexpr (!mem::is_soa_layout_v<U> && !std::is_trivially_destructible_v<U>) {
177 return [](
void* ptr, uint32_t cnt) {
178 core::call_dtor_n((U*)ptr, cnt);
185 static constexpr auto func_copy_ctor() {
186 return [](
void* GAIA_RESTRICT dst,
const void* GAIA_RESTRICT src, uint32_t idxDst, uint32_t idxSrc,
187 uint32_t sizeDst, uint32_t sizeSrc) {
188 mem::copy_ctor_element<U>((uint8_t*)dst, (
const uint8_t*)src, idxDst, idxSrc, sizeDst, sizeSrc);
192 static constexpr auto func_move_ctor() {
193 return [](
void* GAIA_RESTRICT dst,
void* GAIA_RESTRICT src, uint32_t idxDst, uint32_t idxSrc,
194 uint32_t sizeDst, uint32_t sizeSrc) {
195 mem::move_ctor_element<U>((uint8_t*)dst, (uint8_t*)src, idxDst, idxSrc, sizeDst, sizeSrc);
199 static constexpr auto func_copy() {
200 return [](
void* GAIA_RESTRICT dst,
const void* GAIA_RESTRICT src, uint32_t idxDst, uint32_t idxSrc,
201 uint32_t sizeDst, uint32_t sizeSrc) {
202 mem::copy_element<U>((uint8_t*)dst, (
const uint8_t*)src, idxDst, idxSrc, sizeDst, sizeSrc);
206 static constexpr auto func_move() {
207 return [](
void* GAIA_RESTRICT dst,
void* GAIA_RESTRICT src, uint32_t idxDst, uint32_t idxSrc,
208 uint32_t sizeDst, uint32_t sizeSrc) {
209 mem::move_element<U>((uint8_t*)dst, (uint8_t*)src, idxDst, idxSrc, sizeDst, sizeSrc);
213 static constexpr auto func_swap() {
214 return [](
void* GAIA_RESTRICT left,
void* GAIA_RESTRICT right, uint32_t idxLeft, uint32_t idxRight,
215 uint32_t sizeLeft, uint32_t sizeRight) {
216 mem::swap_elements<U>((uint8_t*)left, (uint8_t*)right, idxLeft, idxRight, sizeLeft, sizeRight);
220 static constexpr auto func_cmp() {
221 if constexpr (mem::is_soa_layout_v<U>) {
222 return []([[maybe_unused]]
const void* left, [[maybe_unused]]
const void* right) {
223 GAIA_ASSERT(
false &&
"func_cmp for SoA not implemented yet");
229 if constexpr (hasGlobalCmp || hasMemberCmp) {
230 return [](
const void* left,
const void* right) {
231 const auto* l = (
const U*)left;
232 const auto* r = (
const U*)right;
237 return [](
const void* left,
const void* right) {
238 const auto* l = (
const U*)left;
239 const auto* r = (
const U*)right;
240 return memcmp(l, r,
sizeof(U)) == 0;
246 static constexpr auto func_save() {
247 return [](
ser::serializer& s,
const void* pSrc, uint32_t from, uint32_t to, uint32_t cap) {
248 const auto* pComponent = (
const U*)pSrc;
250#if GAIA_ASSERT_ENABLED
252 s.check(*pComponent);
255 if constexpr (mem::is_soa_layout_v<U>) {
257 GAIA_FOR2(from, to) {
263 GAIA_FOR2(from, to) {
271 static constexpr auto func_load() {
272 return [](
ser::serializer& s,
void* pDst, uint32_t from, uint32_t to, uint32_t cap) {
273 if constexpr (mem::is_soa_layout_v<U>) {
275 GAIA_FOR2(from, to) {
281 auto* pComponent = (U*)pDst + from;
282 GAIA_FOR2(from, to) {
298 desc.
name = descName;
301 desc.storageType = DataStorageType::Table;
302 desc.soa = soa(soaSizes);
303 desc.pSoaSizes = soaSizes.data();
304 desc.hashLookup = hash_lookup();
305 desc.funcCtor = func_ctor();
306 desc.funcMoveCtor = func_move_ctor();
307 desc.funcCopyCtor = func_copy_ctor();
308 desc.funcDtor = func_dtor();
309 desc.funcCopy = func_copy();
310 desc.funcMove = func_move();
311 desc.funcSwap = func_swap();
312 desc.funcCmp = func_cmp();
313 desc.funcSave = func_save();
314 desc.funcLoad = func_load();