typedef struct SpaceEntryHandle SpaceEntryHandle; struct SpaceEntryHandle { u64 idx; u64 gen; }; typedef struct SpaceCellNode SpaceCellNode; typedef struct SpaceEntry SpaceEntry; struct SpaceEntry { b32 valid; SpaceEntryHandle handle; SpaceCellNode *first_node; SpaceCellNode *last_node; Aabb aabb; EntId ent; SpaceEntry *next_free; }; /* Links a cell to a entry. * Acts as both a node in the list of entries contained by the cell, and a node in the list of cells containing the entry. */ typedef struct SpaceCell SpaceCell; typedef struct SpaceCellNode SpaceCellNode; struct SpaceCellNode { SpaceEntry *entry; SpaceCell *cell; /* For list of all entries contained by cell */ SpaceCellNode *prev_in_cell; SpaceCellNode *next_in_cell; /* For list of all cells containing entry */ SpaceCellNode *prev_in_entry; SpaceCellNode *next_in_entry; SpaceCellNode *next_free; }; typedef struct SpaceCellBin SpaceCellBin; typedef struct SpaceCell SpaceCell; struct SpaceCell { b32 valid; V2i32 pos; SpaceCellNode *first_node; SpaceCellNode *last_node; SpaceCellBin *bin; SpaceCell *prev_in_bin; SpaceCell *next_in_bin; SpaceCell *next_free; }; typedef struct SpaceCellBin SpaceCellBin; struct SpaceCellBin { SpaceCell *first_cell; SpaceCell *last_cell; }; typedef struct Space Space; struct Space { b32 valid; f32 cell_size; Arena *cell_arena; SpaceCellBin *bins; i32 num_bins; i32 num_bins_sqrt; SpaceCell *first_free_cell; SpaceCellNode *first_free_cell_node; Arena *entry_arena; u64 num_entries_reserved; SpaceEntry *entries; SpaceEntry *first_free_entry; }; typedef struct SpaceIter SpaceIter; struct SpaceIter { Aabb aabb; Space *space; V2i32 cell_start; V2i32 cell_end; V2i32 cell_cur; SpaceCellNode *prev; }; /* ========================== * * Nil * ========================== */ INLINE SpaceEntry *space_entry_nil(void) { extern READONLY SpaceEntry _g_space_entry_nil; return &_g_space_entry_nil; } INLINE SpaceCell *space_cell_nil(void) { extern READONLY SpaceCell _g_space_cell_nil; return &_g_space_cell_nil; } INLINE Space *space_nil(void) { extern READONLY Space _g_space_nil; return &_g_space_nil; } /* ========================== * * Space * ========================== */ Space *space_alloc(f32 cell_size, u32 num_bins_sqrt); void space_release(Space *space); void space_reset(Space *space); Space *space_from_entry(SpaceEntry *entry); /* ========================== * * Cell * ========================== */ SpaceCell *space_get_cell(Space *space, V2i32 cell_pos); /* ========================== * * Entry * ========================== */ SpaceEntry *space_entry_from_handle(Space *space, SpaceEntryHandle handle); SpaceEntry *space_entry_alloc(Space *space, EntId entity); void space_entry_release(SpaceEntry *entry); void space_entry_update_aabb(SpaceEntry *entry, Aabb new_aabb); /* ========================== * * Iter * ========================== */ SpaceIter space_iter_begin_aabb(Space *space, Aabb aabb); SpaceEntry *space_iter_next(SpaceIter *iter); #define space_iter_end(i)