aboutsummaryrefslogtreecommitdiff
path: root/src/entity_list.odin
diff options
context:
space:
mode:
authorXander Swan <email>2025-12-03 09:52:13 -0500
committerXander Swan <email>2025-12-03 09:52:13 -0500
commitb6cf1d104da53ec9c30dc45c35d9de48812f0afc (patch)
tree49421206d8d866e82a8a743cba5ced494cbfc785 /src/entity_list.odin
Initial commit
Diffstat (limited to 'src/entity_list.odin')
-rw-r--r--src/entity_list.odin81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/entity_list.odin b/src/entity_list.odin
new file mode 100644
index 0000000..4890d2c
--- /dev/null
+++ b/src/entity_list.odin
@@ -0,0 +1,81 @@
+package demonchime
+
+// import "core:math"
+
+Entity_Handle :: struct {
+ idx: u32,
+ uses: u32,
+}
+
+Entity_List :: struct($T: typeid) {
+ items: [dynamic]T,
+ holes: [dynamic]Entity_Handle,
+}
+
+delete_entity_list :: proc(list: Entity_List($T)) {
+ delete(list.items)
+ delete(list.holes)
+}
+
+make_entity :: proc(list: ^Entity_List($T), ent: T) -> (Entity_Handle, ^T) {
+ handle: Entity_Handle
+
+ if len(list.holes) > 0 {
+ handle = pop(&list.holes)
+ handle.uses += 1
+ } else {
+ // because index 0 in a handle is considered a null handle
+ resize(&list.items, math.max(2, len(list.items) + 1))
+ handle.idx = u32(len(list.items) - 1)
+ handle.uses = 1
+ }
+
+ list.items[handle.idx] = ent
+ list.items[handle.idx].handle = handle
+ return handle, &list.items[handle.idx]
+}
+
+delete_entity :: proc(list: ^Entity_List($T), handle: Entity_Handle) {
+ if handle.idx <= 0 || int(handle.idx) >= len(list.items) {
+ return
+ }
+ if list.items[handle.idx].handle != handle {
+ return
+ }
+
+ append(&list.holes, handle)
+ list.items[handle.idx] = {}
+}
+
+get_entity :: proc(list: Entity_List($T), h: Entity_Handle) -> ^T {
+ if h.idx < 1 || h.idx >= len(list.items) || list.items[h.idx].handle == h {
+ return nil
+ }
+ return &list.items[h.idx]
+}
+
+active_entity_count :: proc(list: Entity_List($T)) -> int {
+ // - 1 because there's an empty slot at the beginning
+ return len(list.items) - len(list.holes) - 1
+}
+
+Entity_List_Iter :: struct($T: typeid) {
+ list: Entity_List(T),
+ idx: int,
+}
+
+iter_entity_list :: proc(list: Entity_List($T)) -> Entity_List_Iter(T) {
+ return Entity_List_Iter(T) { list = list }
+}
+
+entity_list_iter :: proc(it: ^Entity_List_Iter($T)) -> (^T, bool) {
+ for it.idx < len(it.list.items) {
+ if it.list.items[it.idx].handle.idx > 0 {
+ entity := &it.list.items[it.idx]
+ it.idx += 1
+ return entity, true
+ }
+ it.idx += 1
+ }
+ return nil, false
+}