summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--entity.hpp8
-rw-r--r--world.cpp62
-rw-r--r--world.hpp17
3 files changed, 66 insertions, 21 deletions
diff --git a/entity.hpp b/entity.hpp
new file mode 100644
index 0000000..34cc84d
--- /dev/null
+++ b/entity.hpp
@@ -0,0 +1,8 @@
+#ifndef entity_hpp
+#define entity_hpp
+
+#include <stdint.h>
+
+using Entity_Id = uint32_t;
+
+#endif
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;
+}
diff --git a/world.hpp b/world.hpp
index f486ba1..c944b12 100644
--- a/world.hpp
+++ b/world.hpp
@@ -3,16 +3,20 @@
struct Arena;
+#include "entity.hpp"
+
#include <stdint.h>
#include <new>
+#include <tuple>
#include <utility>
-
+extern "C" {
+#include "plat.h"
+}
using Component_Mask = uint64_t;
-using Entity_Id = uint32_t;
#define max_entities 1024
-#define slinky_size 128
+#define slinky_size 1
#define max_components 64
#define max_slinkies (max_entities / slinky_size)
@@ -36,7 +40,6 @@ struct Slinky {
void init(Arena* a, int size);
void* add(Entity_Id eid, int size, int& mapping);
void* get(Entity_Id eid, int mapping, int size);
- void remove(Entity_Id eid, int mapping, int size);
};
struct Pool {
@@ -71,8 +74,9 @@ struct World {
uint8_t versions[max_entities];
Entity_Id entities[max_entities];
Entity_Id freelist[max_entities];
+ Entity_Id dq[max_entities];
Arena* arena;
- int count, free_count;
+ int count, dq_count, free_count;
void init(Arena* a);
uint64_t hash_mask(Component_Mask m);
@@ -122,6 +126,8 @@ struct World {
void* get(Entity_Id eid, int cid);
void remove(Entity_Id eid, int cid);
void destroy(Entity_Id e);
+ void qdestroy(Entity_Id e);
+ void update();
struct View {
World* w;
@@ -172,6 +178,7 @@ struct World {
Slinky& s = p->slinkies[ptr >> slinky_size_bit];
int si = &s - p->slinkies;
int off = ptr - (si << slinky_size_bit);
+ assert(s.entities[off]);
return s.entities[off];
}
};