From 52db86b0128d3c23b06597b9c0adf8dc849f580a Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 13 Aug 2024 12:58:13 -0500 Subject: [PATCH] entity active field --- build.c | 2 +- src/arena.h | 6 +++--- src/entity.c | 34 ++++++++++++++++++++++++---------- src/entity.h | 11 +++++++++-- src/game.c | 41 +++++++++++++++++++++++++---------------- src/user.c | 5 ++--- 6 files changed, 64 insertions(+), 35 deletions(-) diff --git a/build.c b/build.c index 6573a0f4..ee44b95d 100644 --- a/build.c +++ b/build.c @@ -394,7 +394,7 @@ void OnBuild(StringList cli_args) } else { /* Enable UBSan */ StringListAppend(&perm, &compile_and_link_args, Lit("-fsanitize=undefined -fsanitize-trap=all")); - //StringListAppend(&arena, &compile_and_link_args, Lit("-fsanitize=undefined")); + //StringListAppend(&perm, &compile_and_link_args, Lit("-fsanitize=undefined")); } } diff --git a/src/arena.h b/src/arena.h index 36b84894..fd8f49e6 100644 --- a/src/arena.h +++ b/src/arena.h @@ -42,7 +42,7 @@ INLINE void *_arena_push_bytes_zero(struct arena *arena, u64 size, u64 align) return p; } -INLINE void _arena_pop_to(struct arena *arena, u64 pos) +INLINE void arena_pop_to(struct arena *arena, u64 pos) { ASSERT(arena->pos >= pos); ASSERT(!arena->readonly); @@ -94,12 +94,12 @@ INLINE struct temp_arena arena_temp_begin(struct arena *arena) INLINE void arena_temp_end(struct temp_arena temp) { - _arena_pop_to(temp.arena, temp.start_pos); + arena_pop_to(temp.arena, temp.start_pos); } INLINE void arena_reset(struct arena *arena) { - _arena_pop_to(arena, 0); + arena_pop_to(arena, 0); } INLINE struct buffer arena_to_buffer(struct arena *arena) diff --git a/src/entity.c b/src/entity.c index c0466c05..87f8c41a 100644 --- a/src/entity.c +++ b/src/entity.c @@ -12,6 +12,7 @@ READONLY struct entity_store _g_entity_store_nil = { /* Accessed via entity_nil() */ /* TODO: Allocate nil entity in nil store */ READONLY struct entity _g_entity_nil = { + .valid = false, .local_xform = XFORM_IDENT_NOCAST, .cached_global_xform = XFORM_IDENT_NOCAST, .sprite_local_xform = XFORM_IDENT_NOCAST, @@ -31,6 +32,17 @@ GLOBAL READONLY struct entity g_entity_default = { * Store allocation * ========================== */ +INTERNAL void store_make_root(struct entity_store *store) +{ + struct entity *root = entity_alloc_unlinked(store); + root->is_root = true; + root->active = true; + root->local_xform = XFORM_IDENT; + root->cached_global_xform = XFORM_IDENT; + root->cached_global_xform_dirty = false; + store->root = root->handle; +} + struct entity_store *entity_store_alloc(void) { struct arena arena = arena_alloc(GIGABYTE(64)); @@ -38,14 +50,7 @@ struct entity_store *entity_store_alloc(void) store->arena = arena; store->entities = arena_dry_push(&arena, struct entity); ASSERT((u64)store->entities - (u64)store == STORE_ENTITIES_OFFSET); /* Offset must be correct */ - - struct entity *root = entity_alloc_unlinked(store); - root->is_root = true; - root->local_xform = XFORM_IDENT; - root->cached_global_xform = XFORM_IDENT; - root->cached_global_xform_dirty = false; - store->root = root->handle; - + store_make_root(store); return store; } @@ -64,6 +69,14 @@ void entity_store_copy_replace(struct entity_store *dest, struct entity_store *s dest->entities = dest_entities; } +void entity_store_reset(struct entity_store *store) +{ + store->count = 0; + store->first_free = entity_nil_handle(); + arena_pop_to(&store->arena, STORE_ENTITIES_OFFSET); + store_make_root(store); +} + /* ========================== * * Allocation * ========================== */ @@ -117,6 +130,7 @@ INTERNAL void entity_release_internal(struct entity_store *store, struct entity /* Release */ ++ent->handle.gen; ent->valid = false; + ent->active = false; ent->next_free = store->first_free; store->first_free = ent->handle; } @@ -321,8 +335,8 @@ void entity_unlink_parent(struct entity *ent) } else { parent->last = prev->handle; } - ent->prev = entity_handle_nil(); - ent->next = entity_handle_nil(); + ent->prev = entity_nil_handle(); + ent->next = entity_nil_handle(); } /* NOTE: Children will be re-linked as children to their grandparent (ent's parent) */ diff --git a/src/entity.h b/src/entity.h index a38544b5..91838a22 100644 --- a/src/entity.h +++ b/src/entity.h @@ -39,7 +39,7 @@ struct entity_store { struct entity { /* Metadata */ - b32 valid; + b32 valid; /* Is this entity allocated in memory that can be written to (can always be read) */ struct entity_handle handle; u64 continuity_gen; u64 props[(ENTITY_PROP_COUNT + 63) / 64]; @@ -61,6 +61,12 @@ struct entity { struct entity_handle first; struct entity_handle last; + /* ====================================================================== */ + /* Active */ + + /* Is this entity ready to interact with the world (subset of 'valid') */ + b32 active; + /* ====================================================================== */ /* Position */ @@ -157,7 +163,7 @@ struct entity_prop_array { * Handle helpers * ========================== */ -INLINE struct entity_handle entity_handle_nil(void) +INLINE struct entity_handle entity_nil_handle(void) { return (struct entity_handle) { 0 }; } @@ -216,6 +222,7 @@ INLINE b32 entity_has_prop(struct entity *entity, enum entity_prop prop) struct entity_store *entity_store_alloc(void); void entity_store_release(struct entity_store *store); void entity_store_copy_replace(struct entity_store *dest, struct entity_store *src); +void entity_store_reset(struct entity_store *store); /* Entity */ struct entity *entity_alloc_unlinked(struct entity_store *store); diff --git a/src/game.c b/src/game.c index f640b9eb..1dbe3c14 100644 --- a/src/game.c +++ b/src/game.c @@ -224,12 +224,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) /* Clear level */ case GAME_CMD_KIND_CLEAR_ALL: { logf_info("Clearing level"); - for (u64 i = 0; i < store->count; ++i) { - struct entity *ent = &store->entities[i]; - if (ent->valid && !ent->is_root) { - entity_release(store, ent); - } - } + entity_store_reset(store); } break; /* Spawn test */ @@ -248,7 +243,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; if (sprite_tag_is_nil(ent->sprite)) continue; /* Update animation */ @@ -300,7 +295,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { /* Process cmds */ @@ -359,7 +354,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; if (entity_has_prop(ent, ENTITY_PROP_TEST)) { if (!ent->test_initialized) { @@ -394,12 +389,12 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; /* Trigger equipped */ if (entity_has_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED)) { struct entity *eq = entity_from_handle(store, ent->equipped); - if (eq->valid) { + if (eq->active) { entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK); } } @@ -412,7 +407,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; if (!entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) continue; if ((time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) continue; @@ -450,7 +445,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; /* Player angle */ @@ -540,7 +535,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; /* Camera follow */ if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) { @@ -585,7 +580,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; if (entity_has_prop(ent, ENTITY_PROP_TEST_SOUND_EMITTER)) { struct mixer_desc desc = ent->sound_desc; @@ -660,7 +655,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED_NEXT_TICK)) { entity_disable_prop(ent, ENTITY_PROP_TRIGGERED_NEXT_TICK); @@ -670,6 +665,20 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) } } + /* ========================== * + * Activate entities + * ========================== */ + + for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { + struct entity *ent = &store->entities[entity_index]; + if (!ent->valid) continue; + + if (!ent->active) { + ent->active = true; + ++ent->continuity_gen; + } + } + /* ========================== * * End frame cache scopes * ========================== */ diff --git a/src/user.c b/src/user.c index 361bca22..4683ef90 100644 --- a/src/user.c +++ b/src/user.c @@ -772,9 +772,8 @@ INTERNAL void user_update(void) for (u64 entity_index = 0; entity_index < store->count; ++entity_index) { __profscope(user_entity_iter); - struct entity *ent = &store->entities[entity_index]; - if (!ent->valid) continue; + if (!ent->active) continue; if (ent->is_root) continue; struct sprite_tag sprite = ent->sprite; @@ -906,7 +905,7 @@ INTERNAL void user_update(void) } /* Draw hierarchy */ - if (parent->valid && !parent->is_root) { + if (parent->active && !parent->is_root) { u32 color = RGBA_32_F(0.6, 0.6, 1, 0.75); f32 thickness = 5; f32 arrow_height = 15;