From 26aebfdb92eb6780b1eb7195670b042b97948b0f Mon Sep 17 00:00:00 2001 From: quou Date: Thu, 1 May 2025 20:45:12 +1000 Subject: fixing bugs in the entity system --- world.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 16 deletions(-) (limited to 'world.cpp') diff --git a/world.cpp b/world.cpp index bdd0e5a..a08c024 100644 --- a/world.cpp +++ b/world.cpp @@ -32,17 +32,6 @@ void* Slinky::get(Entity_Id eid, int mapping, int size) { return e; } -void Slinky::remove(Entity_Id eid, int mapping, int size) { - int end = (--count) * size; - assert(eid == entities[mapping]); - (void)eid; - memmove( - (char*)data + mapping * size, - (char*)data + end * size, - size - ); -} - void Pool::init(Arena* a, Component_Mask m) { int i, coff; mask = m; @@ -59,9 +48,11 @@ void Pool::init(Arena* a, Component_Mask m) { } Slinky& Pool::get_slinky(Arena* a) { - int idx = slinky_count - 1; - if (slinkies[idx].count < slinky_size) { - return slinkies[idx]; + int i, e = slinky_count; + for (i = 0; i < e; i++) { + Slinky& s = slinkies[i]; + if (s.count < slinky_size) + return s; } assert(slinky_count < max_slinkies); Slinky& s = slinkies[slinky_count++]; @@ -78,9 +69,34 @@ void* Pool::add(Arena* a, Entity_Id eid) { } void Pool::remove(Entity_Id eid) { - Mapping m = mapping[entity_index(eid)]; + Mapping& m = mapping[entity_index(eid)]; Slinky& s = slinkies[m.slinky]; - s.remove(eid, m.mapping, size); + assert(m.slinky >= 0); + if (count > 1) { + int idx = slinky_count - 1; + Entity_Id le; + void* last; +#ifdef DEBUG + last = 0; +#endif + for (; idx >= 0; idx--) { + Slinky& s = slinkies[idx]; + int& c = s.count; + if (c) { + c--; + last = (char*)s.data + c * size; + le = s.entities[c]; + s.entities[c] = 0; + break; + } + } + assert(last != 0); + memcpy((char*)s.data + m.mapping * size, last, size); + s.entities[m.mapping] = le; + mapping[entity_index(le)] = m; + m = Mapping { -1, -1 }; + } else + s.count--; count--; } @@ -122,6 +138,7 @@ void World::init(Arena* a) { arena = a; count = 0; free_count = 0; + dq_count = 0; for (i = 0; i < max_entities; i++) versions[i] = 1; for (i = 0; i < max_pools; i++) @@ -232,3 +249,16 @@ void World::destroy(Entity_Id e) { versions[entity_index(e)]++; } +void World::qdestroy(Entity_Id e) { + assert(e); + assert(dq_count < max_entities); + dq[dq_count++] = e; +} + +void World::update() { + int i, e = dq_count; + Entity_Id* d = dq; + for (i = 0; i < e; i++, d++) + destroy(*d); + dq_count = 0; +} -- cgit v1.2.3-54-g00ecf