From b6cf1d104da53ec9c30dc45c35d9de48812f0afc Mon Sep 17 00:00:00 2001 From: Xander Swan Date: Wed, 3 Dec 2025 09:52:13 -0500 Subject: Initial commit --- src/entity_list.odin | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/entity_list.odin (limited to 'src/entity_list.odin') 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 +} -- cgit v1.3-2-g0d8e