#ifndef SPACE_H #define SPACE_H struct space_cell_bin; struct space_entry { b32 valid; struct space_entry_handle handle; struct space_cell_node *first_node; struct space_cell_node *last_node; struct aabb aabb; struct sim_ent_id ent; struct space_entry *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. */ struct space_cell_node { struct space_entry *entry; struct space_cell *cell; /* For list of all entries contained by cell */ struct space_cell_node *prev_in_cell; struct space_cell_node *next_in_cell; /* For list of all cells containing entry */ struct space_cell_node *prev_in_entry; struct space_cell_node *next_in_entry; struct space_cell_node *next_free; }; struct space_cell { b32 valid; struct v2i32 pos; struct space_cell_node *first_node; struct space_cell_node *last_node; struct space_cell_bin *bin; struct space_cell *prev_in_bin; struct space_cell *next_in_bin; struct space_cell *next_free; }; struct space_cell_bin { struct space_cell *first_cell; struct space_cell *last_cell; }; struct space { b32 valid; f32 cell_size; struct arena *cell_arena; struct space_cell_bin *bins; i32 num_bins; i32 num_bins_sqrt; struct space_cell *first_free_cell; struct space_cell_node *first_free_cell_node; struct arena *entry_arena; u64 num_entries_reserved; struct space_entry *entries; struct space_entry *first_free_entry; }; struct space_iter { struct aabb aabb; struct space *space; struct v2i32 cell_start; struct v2i32 cell_end; struct v2i32 cell_cur; struct space_cell_node *prev; }; /* ========================== * * Nil * ========================== */ INLINE struct space_entry *space_entry_nil(void) { extern READONLY struct space_entry _g_space_entry_nil; return &_g_space_entry_nil; } INLINE struct space_cell *space_cell_nil(void) { extern READONLY struct space_cell _g_space_cell_nil; return &_g_space_cell_nil; } INLINE struct space *space_nil(void) { extern READONLY struct space _g_space_nil; return &_g_space_nil; } /* ========================== * * Space * ========================== */ struct space *space_alloc(f32 cell_size, u32 num_bins_sqrt); void space_release(struct space *space); void space_reset(struct space *space); struct space *space_from_entry(struct space_entry *entry); /* ========================== * * Cell * ========================== */ struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos); /* ========================== * * Entry * ========================== */ struct space_entry *space_entry_from_handle(struct space *space, struct space_entry_handle handle); struct space_entry *space_entry_alloc(struct space *space, struct sim_ent_id entity); void space_entry_release(struct space_entry *entry); void space_entry_update_aabb(struct space_entry *entry, struct aabb new_aabb); /* ========================== * * Iter * ========================== */ struct space_iter space_iter_begin_aabb(struct space *space, struct aabb aabb); struct space_entry *space_iter_next(struct space_iter *iter); #define space_iter_end(i) #endif