2#include "gaia/config/config.h"
6#include "gaia/cnt/map.h"
7#include "gaia/ecs/api.h"
8#include "gaia/ecs/archetype_common.h"
9#include "gaia/ecs/component.h"
10#include "gaia/ecs/id.h"
11#include "gaia/util/logging.h"
18 using ArchetypeGraphEdge = ArchetypeIdHashPair;
20 class ArchetypeGraph {
21 using EdgeMap = cnt::map<EntityLookupKey, ArchetypeGraphEdge>;
29 void add_edge(EdgeMap& edges, Entity entity, ArchetypeId archetypeId, ArchetypeIdHash hash) {
30#if GAIA_ASSERT_ENABLED
33 edges.try_emplace(EntityLookupKey(entity), ArchetypeGraphEdge{archetypeId, hash});
34#if GAIA_ASSERT_ENABLED
37 const auto it = edges.find(EntityLookupKey(entity));
38 GAIA_ASSERT(it != edges.end());
39 GAIA_ASSERT(it->second.id == archetypeId);
40 GAIA_ASSERT(it->second.hash == hash);
45 void del_edge(EdgeMap& edges, Entity entity) {
46 edges.erase(EntityLookupKey(entity));
49 GAIA_NODISCARD ArchetypeGraphEdge find_edge(
const EdgeMap& edges, Entity entity)
const {
50 const auto it = edges.find(EntityLookupKey(entity));
51 return it != edges.end() ? it->second : ArchetypeIdHashPairBad;
59 void add_edge_right(Entity entity, ArchetypeId archetypeId, ArchetypeIdHash hash) {
60 add_edge(m_edgesAdd, entity, archetypeId, hash);
67 void add_edge_left(Entity entity, ArchetypeId archetypeId, ArchetypeIdHash hash) {
68 add_edge(m_edgesDel, entity, archetypeId, hash);
73 void del_edge_right(Entity entity) {
74 del_edge(m_edgesAdd, entity);
79 void del_edge_left(Entity entity) {
80 del_edge(m_edgesDel, entity);
86 GAIA_NODISCARD ArchetypeGraphEdge find_edge_right(Entity entity)
const {
87 return find_edge(m_edgesAdd, entity);
93 GAIA_NODISCARD ArchetypeGraphEdge find_edge_left(Entity entity)
const {
94 return find_edge(m_edgesDel, entity);
97 GAIA_NODISCARD
auto& right_edges() {
101 GAIA_NODISCARD
const auto& right_edges()
const {
105 GAIA_NODISCARD
auto& left_edges() {
109 GAIA_NODISCARD
const auto& left_edges()
const {
113 void diag(
const World& world)
const {
114 auto diagEdge = [&](
const auto& edges) {
115 for (
const auto& edge: edges) {
116 const auto entity = edge.first.entity();
118 const auto name0 = entity_name(world, entity.id());
119 const auto name1 = entity_name(world, entity.gen());
121 " pair [%u:%u], %.*s -> %.*s, aid:%u",
123 entity.id(), entity.gen(), (
int)name0.size(), name0.empty() ?
"" : name0.data(), (int)name1.size(),
124 name1.empty() ?
"" : name1.data(), edge.second.id);
126 const auto name = entity_name(world, entity);
128 " ent [%u:%u], %.*s [%s], aid:%u",
130 entity.id(), entity.gen(), (
int)name.size(), name.empty() ?
"" : name.data(),
131 EntityKindString[entity.kind()], edge.second.id);
137 if (!m_edgesAdd.empty()) {
138 GAIA_LOG_N(
" Add edges - count:%u", (uint32_t)m_edgesAdd.size());
139 diagEdge(m_edgesAdd);
143 if (!m_edgesDel.empty()) {
144 GAIA_LOG_N(
" Del edges - count:%u", (uint32_t)m_edgesDel.size());
145 diagEdge(m_edgesDel);