327 GAIA_PROF_SCOPE(cmdbuf::commit);
330 if (m_nextTemp > 0) {
331 GAIA_PROF_SCOPE(cmdbuf::alloc);
337 m_tmpFlags.resize(m_nextTemp * 3);
340 if (m_temp2real.size() < m_nextTemp) {
341 const auto from = m_temp2real.size();
342 m_temp2real.resize(m_nextTemp);
343 GAIA_FOR2(from, m_nextTemp) m_temp2real[i] = EntityBad;
347 for (
const Op& o: m_ops) {
349 if (is_tmp(o.target)) {
350 const uint32_t ti = o.target.id();
352 if (o.type == OpType::DEL_ENTITY)
353 m_tmpFlags.
set((ti * 3) + 0,
true);
354 else if (is_rel(o.type))
355 m_tmpFlags.
set((ti * 3) + 1,
true);
358 if (is_tmp(o.other) && o.other.id() < m_tmpFlags.
size())
359 m_tmpFlags.
set((o.other.id() * 3) + 2,
true);
363 for (
const Op& o: m_ops) {
364 if (!is_tmp(o.target))
367 const uint32_t ti = o.target.id();
368 if (is_canceled_temp(ti))
371 if (o.type == OpType::ADD_ENTITY) {
372 if (m_temp2real[ti] == EntityBad)
373 m_temp2real[ti] = m_world.
add(o.target.kind());
374 }
else if (o.type == OpType::CPY_ENTITY) {
375 if (m_temp2real[ti] == EntityBad) {
376 const Entity src = resolve(o.other);
377 if (src != EntityBad)
378 m_temp2real[ti] = m_world.
copy(src);
387 GAIA_PROF_SCOPE(cmdbuf::sort);
390 core::sort(m_ops.begin(), m_ops.end(), [](
const Op& a,
const Op& b) {
391 if (a.target != b.target)
392 return a.target < b.target;
393 if (a.other != b.other)
394 return a.other < b.other;
400 Entity lastKey = EntityBad;
401 Entity lastResolved = EntityBad;
402 auto resolve_cached = [&](
Entity e) {
406 return lastResolved = resolve(e);
408 for (uint32_t p = 0; p < m_ops.size();) {
409 GAIA_PROF_SCOPE(cmdbuf::merge);
411 const Entity tgtKey = m_ops[p].target;
413 const bool tgtIsTemp = is_tmp(tgtKey);
414 const uint32_t ti = tgtIsTemp ? tgtKey.id() : 0u;
416 tgtIsTemp ? (ti < m_temp2real.size() ? m_temp2real[ti] : EntityBad) : resolve_cached(tgtKey);
420 bool hasDelEntity =
false;
421 while (q < m_ops.size() && m_ops[q].target == tgtKey) {
422 if (m_ops[q].type == OpType::DEL_ENTITY)
428 if (tgtReal == EntityBad) {
432 if (tgtIsTemp && is_canceled_temp(ti)) {
437 enum : uint8_t { F_ADD = 1 << 0, F_ADD_DATA = 1 << 1, F_SET = 1 << 2, F_DEL = 1 << 3 };
442 for (uint32_t i = p; i < q;) {
443 const Entity othKey = m_ops[i].other;
444 const Entity othReal = resolve_cached(othKey);
448 while (j < q && m_ops[j].other == othKey)
451 if (tgtReal != EntityBad) {
452 const uint32_t groupSize = j - i;
454 if (groupSize == 1) {
455 const Op& op = m_ops[i];
457 case OpType::DEL_COMPONENT:
460 case OpType::ADD_COMPONENT:
463 case OpType::ADD_COMPONENT_DATA:
466 case OpType::SET_COMPONENT: {
467 const auto& ec = m_world.m_recs.
entities[tgtReal.id()];
468 const auto row = tgtReal.kind() == EntityKind::EK_Uni ? 0U : ec.row;
469 const auto compIdx = ec.pChunk->comp_idx(othReal);
470 auto* pComponentData = (
void*)ec.pChunk->comp_ptr_mut(compIdx, 0);
474 const auto& item = m_world.comp_cache().
get(othReal);
475 item.load(&m_data, pComponentData, row, row + 1, ec.pChunk->capacity());
484 uint32_t dataPos = 0;
486 for (uint32_t k = i; k < j; ++k) {
487 const Op& op = m_ops[k];
489 case OpType::ADD_COMPONENT:
492 case OpType::ADD_COMPONENT_DATA:
496 case OpType::SET_COMPONENT:
500 case OpType::DEL_COMPONENT:
508 const bool hasAdd = mask & F_ADD;
509 const bool hasAddData = mask & F_ADD_DATA;
510 const bool hasSet = mask & F_SET;
511 const bool hasDel = mask & F_DEL;
514 if (hasDel && (hasAdd || hasAddData)) {
521 else if (hasAddData || (hasAdd && hasSet)) {
524 const auto& ec = m_world.m_recs.
entities[tgtReal.id()];
525 const auto row = tgtReal.kind() == EntityKind::EK_Uni ? 0U : ec.row;
526 const auto compIdx = ec.pChunk->comp_idx(othReal);
527 auto* pComponentData = (
void*)ec.pChunk->comp_ptr_mut(compIdx, 0);
530 m_data.seek(dataPos);
531 const auto& item = m_world.comp_cache().
get(othReal);
532 item.load(&m_data, pComponentData, row, row + 1, ec.pChunk->capacity());
540 const auto& ec = m_world.m_recs.
entities[tgtReal.id()];
541 const auto row = tgtReal.kind() == EntityKind::EK_Uni ? 0U : ec.row;
542 const auto compIdx = ec.pChunk->comp_idx(othReal);
543 auto* pComponentData = (
void*)ec.pChunk->comp_ptr_mut(compIdx, 0);
546 m_data.seek(dataPos);
547 const auto& item = m_world.comp_cache().
get(othReal);
548 item.load(&m_data, pComponentData, row, row + 1, ec.pChunk->capacity());
559 m_world.
del(tgtReal);