Skip to content

Commit

Permalink
potential fix2
Browse files Browse the repository at this point in the history
  • Loading branch information
RiscadoA committed Nov 17, 2024
1 parent f786423 commit 6a68ec3
Showing 1 changed file with 26 additions and 21 deletions.
47 changes: 26 additions & 21 deletions core/src/ecs/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ void World::destroy(Entity entity)
mEntityPool.destroy(entity.index);
mTables.dense().at(archetype).swapErase(entity.index);

std::vector<std::pair<DataTypeId, SparseRelationTable*>> delayedPropagateDepth{};
for (const auto& [type, index] : mTables.sparseRelation())
{
// For each table where the entity's archetype is the 'from' archetype.
Expand All @@ -184,11 +185,6 @@ void World::destroy(Entity entity)
for (const auto& tableId : index.from().at(archetype))
{
// Erase all occurrences of the entity in the 'from' column.
CUBOS_ASSERT(mTables.sparseRelation().contains(tableId),
"Sparse relation table {} {} {} {} in index does not exist. Obtained through relation "
"type {} for a 'from' archetype {} of entity {}",
tableId.from.inner, tableId.to.inner, tableId.dataType.inner, tableId.depth, type.inner,
archetype.inner, entity);
mTables.sparseRelation().at(tableId).eraseFrom(entity.index);
}
}
Expand All @@ -198,32 +194,41 @@ void World::destroy(Entity entity)
{
for (const auto& tableId : index.to().at(archetype))
{
CUBOS_ASSERT(mTables.sparseRelation().contains(tableId),
"Sparse relation table {} {} {} {} in index does not exist. Obtained through relation "
"type {} for a 'to' archetype {} of entity {}",
tableId.from.inner, tableId.to.inner, tableId.dataType.inner, tableId.depth, type.inner,
archetype.inner, entity);
auto& table = mTables.sparseRelation().at(tableId);

if (mTypes.isTreeRelation(type))
{
// If the relation is tree-like, then we need to update the depth of the corresponding 'from'
// entities.
for (auto row = table.firstTo(entity.index); row != table.size(); row = table.nextTo(row))
{
uint32_t fromIndex;
uint32_t toIndex;
table.indices(row, fromIndex, toIndex);
this->propagateDepth(fromIndex, type, 0);
}
// entities. We delay this to after the loop has finished, as we're iterating over all tables and
// propagateDepth() may create new tables, which can lead to UB.
//
// We won't erase the relation here, as we'll need to iterate over the table below.
delayedPropagateDepth.push_back(std::make_pair(type, &table));
}
else
{
// Erase all occurrences of the entity in the 'to' column.
table.eraseTo(entity.index);
}

// Erase all occurrences of the entity in the 'to' column.
table.eraseTo(entity.index);
}
}
}

// Process the delayed depth propagation.
for (auto [type, table] : delayedPropagateDepth)
{
for (auto row = table->firstTo(entity.index); row != table->size(); row = table->nextTo(row))
{
uint32_t fromIndex;
uint32_t toIndex;
table->indices(row, fromIndex, toIndex);
this->propagateDepth(fromIndex, type, 0);
}

// Now it's safe to erase the relations.
table->eraseTo(entity.index);
}

// Run commands from observers after entity is destroyed
if (observed)
{
Expand Down

0 comments on commit 6a68ec3

Please sign in to comment.