Skip to content

Commit

Permalink
Tweaked: Entity creation
Browse files Browse the repository at this point in the history
  • Loading branch information
richardbiely committed Feb 22, 2024
1 parent d344cb5 commit df5d73b
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 124 deletions.
118 changes: 55 additions & 63 deletions include/gaia/ecs/world.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ namespace gaia {

if (entity.pair()) {
// Make sure the entity container record exists if it is a pair
m_world.assign<false>(entity, *m_world.m_pEntityArchetype);
m_world.assign_pair(entity, *m_world.m_pEntityArchetype);
}

if (!handle_add_deps(entity))
Expand Down Expand Up @@ -2019,77 +2019,69 @@ namespace gaia {
GAIA_NODISCARD Entity add(Archetype& archetype, bool isEntity, bool isPair, EntityKind kind) {
EntityContainerCtx ctx{isEntity, isPair, kind};
const auto entity = m_recs.entities.alloc(&ctx);
assign<true>(entity, archetype);
assign_entity(entity, archetype);
return entity;
}

//! Assigns an entity to a given archetype
//! Assigns an entity to a given archetype.
//! \param archetype Archetype the entity should inherit
//! \param entity Entity
template <bool IsNewEntity>
void assign(Entity entity, Archetype& archetype) {
if (entity.pair()) {
// Pairs are always added to m_pEntityArchetype initially and this can't change.
GAIA_ASSERT(&archetype == m_pEntityArchetype);

auto assingNewEntity = [&]() {
// Update the container record
EntityContainer ec{};
ec.idx = entity.id();
ec.gen = entity.gen();
ec.pair = 1;
ec.ent = 1;
ec.kind = EntityKind::EK_Gen;

auto* pChunk = archetype.foc_free_chunk();
store_entity(ec, entity, &archetype, pChunk);
m_recs.pairs.emplace(EntityLookupKey(entity), GAIA_MOV(ec));

// Update pair mappings
const auto rel = get(entity.id());
const auto tgt = get(entity.gen());

auto addPair = [](PairMap& map, Entity source, Entity add) {
auto& ents = map[EntityLookupKey(source)];
ents.insert(EntityLookupKey(add));
};

addPair(m_relationsToTargets, rel, tgt);
addPair(m_relationsToTargets, All, tgt);
addPair(m_targetsToRelations, tgt, rel);
addPair(m_targetsToRelations, All, rel);
};

if constexpr (IsNewEntity) {
// No need to make a lookup if this is a new entity
#if GAIA_ASSERT_ENABLED
// Just make sure no such record exists.
// The only way for this to happen is if the entity id overflew in which
// case everything falls apart anyway.
const auto it = m_recs.pairs.find(EntityLookupKey(entity));
GAIA_ASSERT(it == m_recs.pairs.end());
#endif
assingNewEntity();
} else {
const auto it = m_recs.pairs.find(EntityLookupKey(entity));
if (it == m_recs.pairs.end())
assingNewEntity();
}
} else {
auto* pChunk = archetype.foc_free_chunk();
store_entity(m_recs.entities[entity.id()], entity, &archetype, pChunk);
void assign_entity(Entity entity, Archetype& archetype) {
GAIA_ASSERT(!entity.pair());

auto* pChunk = archetype.foc_free_chunk();
store_entity(m_recs.entities[entity.id()], entity, &archetype, pChunk);

// Call constructors for the generic components on the newly added entity if necessary
if (pChunk->has_custom_gen_ctor())
pChunk->call_gen_ctors(pChunk->size() - 1, 1);
// Call constructors for the generic components on the newly added entity if necessary
if (pChunk->has_custom_gen_ctor())
pChunk->call_gen_ctors(pChunk->size() - 1, 1);

#if GAIA_ASSERT_ENABLED
const auto& ec = m_recs.entities[entity.id()];
GAIA_ASSERT(ec.pChunk == pChunk);
auto entityExpected = pChunk->entity_view()[ec.row];
GAIA_ASSERT(entityExpected == entity);
const auto& ec = m_recs.entities[entity.id()];
GAIA_ASSERT(ec.pChunk == pChunk);
auto entityExpected = pChunk->entity_view()[ec.row];
GAIA_ASSERT(entityExpected == entity);
#endif
}
}

//! Assigns a pair entity to a given archetype.
//! \param archetype Archetype the pair should inherit
//! \param entity Pair entity
void assign_pair(Entity entity, Archetype& archetype) {
GAIA_ASSERT(entity.pair());

// Pairs are always added to m_pEntityArchetype initially and this can't change.
GAIA_ASSERT(&archetype == m_pEntityArchetype);

const auto it = m_recs.pairs.find(EntityLookupKey(entity));
if (it != m_recs.pairs.end())
return;

// Update the container record
EntityContainer ec{};
ec.idx = entity.id();
ec.gen = entity.gen();
ec.pair = 1;
ec.ent = 1;
ec.kind = EntityKind::EK_Gen;

auto* pChunk = archetype.foc_free_chunk();
store_entity(ec, entity, &archetype, pChunk);
m_recs.pairs.emplace(EntityLookupKey(entity), GAIA_MOV(ec));

// Update pair mappings
const auto rel = get(entity.id());
const auto tgt = get(entity.gen());

auto addPair = [](PairMap& map, Entity source, Entity add) {
auto& ents = map[EntityLookupKey(source)];
ents.insert(EntityLookupKey(add));
};

addPair(m_relationsToTargets, rel, tgt);
addPair(m_relationsToTargets, All, tgt);
addPair(m_targetsToRelations, tgt, rel);
addPair(m_targetsToRelations, All, rel);
}

//! Garbage collection
Expand Down
114 changes: 53 additions & 61 deletions single_include/gaia.h
Original file line number Diff line number Diff line change
Expand Up @@ -21719,7 +21719,7 @@ namespace gaia {

if (entity.pair()) {
// Make sure the entity container record exists if it is a pair
m_world.assign<false>(entity, *m_world.m_pEntityArchetype);
m_world.assign_pair(entity, *m_world.m_pEntityArchetype);
}

if (!handle_add_deps(entity))
Expand Down Expand Up @@ -23277,77 +23277,69 @@ namespace gaia {
GAIA_NODISCARD Entity add(Archetype& archetype, bool isEntity, bool isPair, EntityKind kind) {
EntityContainerCtx ctx{isEntity, isPair, kind};
const auto entity = m_recs.entities.alloc(&ctx);
assign<true>(entity, archetype);
assign_entity(entity, archetype);
return entity;
}

//! Assigns an entity to a given archetype
//! Assigns an entity to a given archetype.
//! \param archetype Archetype the entity should inherit
//! \param entity Entity
template <bool IsNewEntity>
void assign(Entity entity, Archetype& archetype) {
if (entity.pair()) {
// Pairs are always added to m_pEntityArchetype initially and this can't change.
GAIA_ASSERT(&archetype == m_pEntityArchetype);

auto assingNewEntity = [&]() {
// Update the container record
EntityContainer ec{};
ec.idx = entity.id();
ec.gen = entity.gen();
ec.pair = 1;
ec.ent = 1;
ec.kind = EntityKind::EK_Gen;

auto* pChunk = archetype.foc_free_chunk();
store_entity(ec, entity, &archetype, pChunk);
m_recs.pairs.emplace(EntityLookupKey(entity), GAIA_MOV(ec));

// Update pair mappings
const auto rel = get(entity.id());
const auto tgt = get(entity.gen());

auto addPair = [](PairMap& map, Entity source, Entity add) {
auto& ents = map[EntityLookupKey(source)];
ents.insert(EntityLookupKey(add));
};
void assign_entity(Entity entity, Archetype& archetype) {
GAIA_ASSERT(!entity.pair());

addPair(m_relationsToTargets, rel, tgt);
addPair(m_relationsToTargets, All, tgt);
addPair(m_targetsToRelations, tgt, rel);
addPair(m_targetsToRelations, All, rel);
};
auto* pChunk = archetype.foc_free_chunk();
store_entity(m_recs.entities[entity.id()], entity, &archetype, pChunk);

// Call constructors for the generic components on the newly added entity if necessary
if (pChunk->has_custom_gen_ctor())
pChunk->call_gen_ctors(pChunk->size() - 1, 1);

if constexpr (IsNewEntity) {
// No need to make a lookup if this is a new entity
#if GAIA_ASSERT_ENABLED
// Just make sure no such record exists.
// The only way for this to happen is if the entity id overflew in which
// case everything falls apart anyway.
const auto it = m_recs.pairs.find(EntityLookupKey(entity));
GAIA_ASSERT(it == m_recs.pairs.end());
const auto& ec = m_recs.entities[entity.id()];
GAIA_ASSERT(ec.pChunk == pChunk);
auto entityExpected = pChunk->entity_view()[ec.row];
GAIA_ASSERT(entityExpected == entity);
#endif
assingNewEntity();
} else {
const auto it = m_recs.pairs.find(EntityLookupKey(entity));
if (it == m_recs.pairs.end())
assingNewEntity();
}
} else {
auto* pChunk = archetype.foc_free_chunk();
store_entity(m_recs.entities[entity.id()], entity, &archetype, pChunk);
}

//! Assigns a pair entity to a given archetype.
//! \param archetype Archetype the pair should inherit
//! \param entity Pair entity
void assign_pair(Entity entity, Archetype& archetype) {
GAIA_ASSERT(entity.pair());

// Call constructors for the generic components on the newly added entity if necessary
if (pChunk->has_custom_gen_ctor())
pChunk->call_gen_ctors(pChunk->size() - 1, 1);
// Pairs are always added to m_pEntityArchetype initially and this can't change.
GAIA_ASSERT(&archetype == m_pEntityArchetype);

#if GAIA_ASSERT_ENABLED
const auto& ec = m_recs.entities[entity.id()];
GAIA_ASSERT(ec.pChunk == pChunk);
auto entityExpected = pChunk->entity_view()[ec.row];
GAIA_ASSERT(entityExpected == entity);
#endif
}
const auto it = m_recs.pairs.find(EntityLookupKey(entity));
if (it != m_recs.pairs.end())
return;

// Update the container record
EntityContainer ec{};
ec.idx = entity.id();
ec.gen = entity.gen();
ec.pair = 1;
ec.ent = 1;
ec.kind = EntityKind::EK_Gen;

auto* pChunk = archetype.foc_free_chunk();
store_entity(ec, entity, &archetype, pChunk);
m_recs.pairs.emplace(EntityLookupKey(entity), GAIA_MOV(ec));

// Update pair mappings
const auto rel = get(entity.id());
const auto tgt = get(entity.gen());

auto addPair = [](PairMap& map, Entity source, Entity add) {
auto& ents = map[EntityLookupKey(source)];
ents.insert(EntityLookupKey(add));
};

addPair(m_relationsToTargets, rel, tgt);
addPair(m_relationsToTargets, All, tgt);
addPair(m_targetsToRelations, tgt, rel);
addPair(m_targetsToRelations, All, rel);
}

//! Garbage collection
Expand Down

0 comments on commit df5d73b

Please sign in to comment.