package demonchime 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 { resize(&list.items, 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), h: Entity_Handle) { if int(h.idx) >= len(list.items) || list.items[h.idx].handle != h { return } append(&list.holes, h) list.items[h.idx] = {} } get_entity :: proc(list: Entity_List($T), h: Entity_Handle) -> ^T { if h.idx >= u32(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 { return len(list.items) - len(list.holes) } 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.uses > 0 { entity := &it.list.items[it.idx] it.idx += 1 return entity, true } it.idx += 1 } return nil, false }