372 GAIA_PROF_SCOPE(cmdbuf::commit);
375 if (m_nextTemp > 0) {
376 GAIA_PROF_SCOPE(cmdbuf::alloc);
382 m_tmpFlags.resize(m_nextTemp * 3);
385 if (m_temp2real.size() < m_nextTemp) {
386 const auto from = m_temp2real.size();
387 m_temp2real.resize(m_nextTemp);
388 GAIA_FOR2(from, m_nextTemp) m_temp2real[i] = EntityBad;
392 for (
const Op& o: m_ops) {
394 if (is_tmp(o.target)) {
395 const uint32_t ti = o.target.id();
397 if (o.type == OpType::DEL_ENTITY)
398 m_tmpFlags.set((ti * 3) + 0,
true);
399 else if (is_rel(o.type))
400 m_tmpFlags.set((ti * 3) + 1,
true);
403 if (is_tmp(o.other) && o.other.id() < m_tmpFlags.size())
404 m_tmpFlags.set((o.other.id() * 3) + 2,
true);
408 for (
const Op& o: m_ops) {
409 if (!is_tmp(o.target))
412 const uint32_t ti = o.target.id();
413 if (is_canceled_temp(ti))
416 if (o.type == OpType::ADD_ENTITY) {
417 if (m_temp2real[ti] == EntityBad)
418 m_temp2real[ti] = m_world.
add(o.target.kind());
419 }
else if (o.type == OpType::CPY_ENTITY) {
420 if (m_temp2real[ti] == EntityBad) {
421 const Entity src = resolve(o.other);
422 if (src != EntityBad)
423 m_temp2real[ti] = m_world.
copy(src);
432 GAIA_PROF_SCOPE(cmdbuf::sort);
435 core::sort(m_ops.begin(), m_ops.end(), [](
const Op& a,
const Op& b) {
436 if (a.target != b.target)
437 return a.target < b.target;
438 if (a.other != b.other)
439 return a.other < b.other;
445 Entity lastKey = EntityBad;
446 Entity lastResolved = EntityBad;
447 auto resolve_cached = [&](
Entity e) {
451 return lastResolved = resolve(e);
455 GAIA_PROF_SCOPE(cmdbuf::merges);
456 for (uint32_t p = 0; p < m_ops.size();) {
457 GAIA_PROF_SCOPE(cmdbuf::merge);
459 const Entity tgtKey = m_ops[p].target;
461 const bool tgtIsTemp = is_tmp(tgtKey);
462 const uint32_t ti = tgtIsTemp ? tgtKey.id() : 0u;
464 tgtIsTemp ? (ti < m_temp2real.size() ? m_temp2real[ti] : EntityBad) : resolve_cached(tgtKey);
468 bool hasDelEntity =
false;
469 while (q < m_ops.size() && m_ops[q].target == tgtKey) {
470 if (m_ops[q].type == OpType::DEL_ENTITY)
476 if (tgtReal == EntityBad) {
480 if (tgtIsTemp && is_canceled_temp(ti)) {
485 enum : uint8_t { F_ADD = 1 << 0, F_ADD_DATA = 1 << 1, F_SET = 1 << 2, F_DEL = 1 << 3 };
490 for (uint32_t i = p; i < q;) {
491 const Entity othKey = m_ops[i].other;
492 const Entity othReal = resolve_cached(othKey);
496 while (j < q && m_ops[j].other == othKey)
499 if (tgtReal != EntityBad) {
500 const uint32_t groupSize = j - i;
502 if (groupSize == 1) {
503 const Op& op = m_ops[i];
505 case OpType::DEL_COMPONENT:
506 replay_del(tgtReal, othReal);
508 case OpType::ADD_COMPONENT:
509 replay_add(tgtReal, othReal);
511 case OpType::ADD_COMPONENT_DATA:
512 replay_add(tgtReal, othReal);
514 case OpType::SET_COMPONENT: {
515 const auto& ec = m_world.m_recs.
entities[tgtReal.id()];
516 const auto row = tgtReal.kind() == EntityKind::EK_Uni ? 0U : ec.row;
517 const auto compIdx = ec.pChunk->comp_idx(othReal);
518 auto* pComponentData = (
void*)ec.pChunk->comp_ptr_mut(compIdx, 0);
521 auto serializer = ser::make_serializer(m_data);
522 serializer.seek(op.off);
524 item.load(serializer, pComponentData, row, row + 1, ec.pChunk->capacity());
533 uint32_t dataPos = 0;
535 for (uint32_t k = i; k < j; ++k) {
536 const Op& op = m_ops[k];
538 case OpType::ADD_COMPONENT:
541 case OpType::ADD_COMPONENT_DATA:
545 case OpType::SET_COMPONENT:
549 case OpType::DEL_COMPONENT:
557 const bool hasAdd = mask & F_ADD;
558 const bool hasAddData = mask & F_ADD_DATA;
559 const bool hasSet = mask & F_SET;
560 const bool hasDel = mask & F_DEL;
563 if (hasDel && (hasAdd || hasAddData)) {
567 replay_del(tgtReal, othReal);
570 else if (hasAddData || (hasAdd && hasSet)) {
571 replay_add(tgtReal, othReal);
573 const auto& ec = m_world.m_recs.
entities[tgtReal.id()];
574 const auto row = tgtReal.kind() == EntityKind::EK_Uni ? 0U : ec.row;
575 const auto compIdx = ec.pChunk->comp_idx(othReal);
576 auto* pComponentData = (
void*)ec.pChunk->comp_ptr_mut(compIdx, 0);
579 auto serializer = ser::make_serializer(m_data);
580 serializer.seek(dataPos);
582 item.load(serializer, pComponentData, row, row + 1, ec.pChunk->capacity());
586 replay_add(tgtReal, othReal);
590 const auto& ec = m_world.m_recs.
entities[tgtReal.id()];
591 const auto row = tgtReal.kind() == EntityKind::EK_Uni ? 0U : ec.row;
592 const auto compIdx = ec.pChunk->comp_idx(othReal);
593 auto* pComponentData = (
void*)ec.pChunk->comp_ptr_mut(compIdx, 0);
596 auto serializer = ser::make_serializer(m_data);
597 serializer.seek(dataPos);
599 item.load(serializer, pComponentData, row, row + 1, ec.pChunk->capacity());
610 m_world.
del(tgtReal);