calculate store offset at compile time

This commit is contained in:
jacob 2024-08-06 14:25:46 -05:00
parent c7ee34037a
commit 3776c2fab0
2 changed files with 20 additions and 31 deletions

View File

@ -1,6 +1,9 @@
#include "entity.h" #include "entity.h"
#include "math.h" #include "math.h"
/* Offset in bytes from start of entities array to start of store struct */
#define STORE_ENTITIES_OFFSET (sizeof(struct entity_store) + (sizeof(struct entity_store) % alignof(struct entity)))
/* Accessed via entity_store_nil() */ /* Accessed via entity_store_nil() */
READONLY struct entity_store _g_entity_store_nil = { READONLY struct entity_store _g_entity_store_nil = {
0 0
@ -25,13 +28,7 @@ struct entity_store *entity_store_alloc(void)
struct entity_store *store = arena_push_zero(&arena, struct entity_store); struct entity_store *store = arena_push_zero(&arena, struct entity_store);
store->arena = arena; store->arena = arena;
store->entities = arena_dry_push(&arena, struct entity); store->entities = arena_dry_push(&arena, struct entity);
ASSERT((u64)store->entities - (u64)store == STORE_ENTITIES_OFFSET); /* Offset must be correct */
/* Special entity for keeping track of store offset */
struct entity *offset_entity = entity_alloc(store);
offset_entity->valid = false;
offset_entity->store_offset = (u64)store->entities - (u64)store;
ASSERT(offset_entity->handle.idx == 0); /* Must be first entity in array */
return store; return store;
} }
@ -44,12 +41,10 @@ void entity_store_copy_replace(struct entity_store *dest, struct entity_store *s
{ {
struct arena dest_arena = dest->arena; struct arena dest_arena = dest->arena;
struct entity *dest_entities = dest->entities; struct entity *dest_entities = dest->entities;
u64 dest_store_offset = dest_entities[0].store_offset;
MEMCPY_STRUCT(dest, src); MEMCPY_STRUCT(dest, src);
arena_copy_replace(&dest_arena, &src->arena); arena_copy_replace(&dest_arena, &src->arena);
dest->arena = dest_arena; dest->arena = dest_arena;
dest->entities = dest_entities; dest->entities = dest_entities;
dest->entities[0].store_offset = dest_store_offset;
} }
/* ========================== * /* ========================== *
@ -89,6 +84,17 @@ void entity_release(struct entity_store *store, struct entity *entity)
* Query * Query
* ========================== */ * ========================== */
struct entity_store *entity_get_store(struct entity *ent)
{
struct entity_store *store = entity_store_nil();
if (ent->valid) {
u64 first_entity_addr = (u64)(ent - ent->handle.idx);
store = (struct entity_store *)(first_entity_addr - STORE_ENTITIES_OFFSET);
ASSERT(store->entities == (struct entity *)first_entity_addr);
}
return store;
}
/* Returns a valid entity or nil entity. Always safe to read result, need to check `valid` to write. */ /* Returns a valid entity or nil entity. Always safe to read result, need to check `valid` to write. */
struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle) struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle)
{ {
@ -140,26 +146,6 @@ struct entity *entity_find_first_match_all(struct entity_store *store, struct en
* Xform * Xform
* ========================== */ * ========================== */
/* TODO: Move this */
INTERNAL struct entity_store *entity_get_store(struct entity *ent)
{
struct entity_store *store = entity_store_nil();
if (ent->valid) {
struct entity *first_entity = ent - ent->handle.idx;
u64 store_offset = first_entity->store_offset;
store = (struct entity_store *)((u64)first_entity - store_offset);
ASSERT(store->entities == first_entity);
}
return store;
}
struct xform entity_get_local_xform(struct entity *ent) struct xform entity_get_local_xform(struct entity *ent)
{ {
return ent->xform; return ent->xform;
@ -196,8 +182,10 @@ void entity_set_global_xform(struct entity *ent, struct xform xf)
* Tree * Tree
* ========================== */ * ========================== */
void entity_link(struct entity_store *store, struct entity *parent, struct entity *child) void entity_link(struct entity *parent, struct entity *child)
{ {
struct entity_store *store = entity_get_store(parent);
struct entity *first_child = entity_from_handle(store, parent->first); struct entity *first_child = entity_from_handle(store, parent->first);
struct entity *last_child = entity_from_handle(store, parent->last); struct entity *last_child = entity_from_handle(store, parent->last);

View File

@ -181,11 +181,12 @@ struct xform entity_get_global_xform(struct entity *ent);
void entity_set_global_xform(struct entity *ent, struct xform xf); void entity_set_global_xform(struct entity *ent, struct xform xf);
/* Query */ /* Query */
struct entity_store *entity_get_store(struct entity *ent);
struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle); struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle);
struct entity *entity_find_first_match_one(struct entity_store *store, enum entity_prop prop); struct entity *entity_find_first_match_one(struct entity_store *store, enum entity_prop prop);
struct entity *entity_find_first_match_all(struct entity_store *store, struct entity_prop_array props); struct entity *entity_find_first_match_all(struct entity_store *store, struct entity_prop_array props);
/* Tree */ /* Tree */
void entity_link(struct entity_store *store, struct entity *parent, struct entity *child); void entity_link(struct entity *parent, struct entity *child);
#endif #endif