entity active field
This commit is contained in:
parent
57e0d0a84a
commit
52db86b012
2
build.c
2
build.c
@ -394,7 +394,7 @@ void OnBuild(StringList cli_args)
|
|||||||
} else {
|
} else {
|
||||||
/* Enable UBSan */
|
/* Enable UBSan */
|
||||||
StringListAppend(&perm, &compile_and_link_args, Lit("-fsanitize=undefined -fsanitize-trap=all"));
|
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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ INLINE void *_arena_push_bytes_zero(struct arena *arena, u64 size, u64 align)
|
|||||||
return p;
|
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->pos >= pos);
|
||||||
ASSERT(!arena->readonly);
|
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)
|
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)
|
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)
|
INLINE struct buffer arena_to_buffer(struct arena *arena)
|
||||||
|
|||||||
34
src/entity.c
34
src/entity.c
@ -12,6 +12,7 @@ READONLY struct entity_store _g_entity_store_nil = {
|
|||||||
/* Accessed via entity_nil() */
|
/* Accessed via entity_nil() */
|
||||||
/* TODO: Allocate nil entity in nil store */
|
/* TODO: Allocate nil entity in nil store */
|
||||||
READONLY struct entity _g_entity_nil = {
|
READONLY struct entity _g_entity_nil = {
|
||||||
|
.valid = false,
|
||||||
.local_xform = XFORM_IDENT_NOCAST,
|
.local_xform = XFORM_IDENT_NOCAST,
|
||||||
.cached_global_xform = XFORM_IDENT_NOCAST,
|
.cached_global_xform = XFORM_IDENT_NOCAST,
|
||||||
.sprite_local_xform = XFORM_IDENT_NOCAST,
|
.sprite_local_xform = XFORM_IDENT_NOCAST,
|
||||||
@ -31,6 +32,17 @@ GLOBAL READONLY struct entity g_entity_default = {
|
|||||||
* Store allocation
|
* 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 entity_store *entity_store_alloc(void)
|
||||||
{
|
{
|
||||||
struct arena arena = arena_alloc(GIGABYTE(64));
|
struct arena arena = arena_alloc(GIGABYTE(64));
|
||||||
@ -38,14 +50,7 @@ struct entity_store *entity_store_alloc(void)
|
|||||||
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 */
|
ASSERT((u64)store->entities - (u64)store == STORE_ENTITIES_OFFSET); /* Offset must be correct */
|
||||||
|
store_make_root(store);
|
||||||
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;
|
|
||||||
|
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +69,14 @@ void entity_store_copy_replace(struct entity_store *dest, struct entity_store *s
|
|||||||
dest->entities = dest_entities;
|
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
|
* Allocation
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -117,6 +130,7 @@ INTERNAL void entity_release_internal(struct entity_store *store, struct entity
|
|||||||
/* Release */
|
/* Release */
|
||||||
++ent->handle.gen;
|
++ent->handle.gen;
|
||||||
ent->valid = false;
|
ent->valid = false;
|
||||||
|
ent->active = false;
|
||||||
ent->next_free = store->first_free;
|
ent->next_free = store->first_free;
|
||||||
store->first_free = ent->handle;
|
store->first_free = ent->handle;
|
||||||
}
|
}
|
||||||
@ -321,8 +335,8 @@ void entity_unlink_parent(struct entity *ent)
|
|||||||
} else {
|
} else {
|
||||||
parent->last = prev->handle;
|
parent->last = prev->handle;
|
||||||
}
|
}
|
||||||
ent->prev = entity_handle_nil();
|
ent->prev = entity_nil_handle();
|
||||||
ent->next = entity_handle_nil();
|
ent->next = entity_nil_handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: Children will be re-linked as children to their grandparent (ent's parent) */
|
/* NOTE: Children will be re-linked as children to their grandparent (ent's parent) */
|
||||||
|
|||||||
11
src/entity.h
11
src/entity.h
@ -39,7 +39,7 @@ struct entity_store {
|
|||||||
|
|
||||||
struct entity {
|
struct entity {
|
||||||
/* Metadata */
|
/* Metadata */
|
||||||
b32 valid;
|
b32 valid; /* Is this entity allocated in memory that can be written to (can always be read) */
|
||||||
struct entity_handle handle;
|
struct entity_handle handle;
|
||||||
u64 continuity_gen;
|
u64 continuity_gen;
|
||||||
u64 props[(ENTITY_PROP_COUNT + 63) / 64];
|
u64 props[(ENTITY_PROP_COUNT + 63) / 64];
|
||||||
@ -61,6 +61,12 @@ struct entity {
|
|||||||
struct entity_handle first;
|
struct entity_handle first;
|
||||||
struct entity_handle last;
|
struct entity_handle last;
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
/* Active */
|
||||||
|
|
||||||
|
/* Is this entity ready to interact with the world (subset of 'valid') */
|
||||||
|
b32 active;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Position */
|
/* Position */
|
||||||
|
|
||||||
@ -157,7 +163,7 @@ struct entity_prop_array {
|
|||||||
* Handle helpers
|
* Handle helpers
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INLINE struct entity_handle entity_handle_nil(void)
|
INLINE struct entity_handle entity_nil_handle(void)
|
||||||
{
|
{
|
||||||
return (struct entity_handle) { 0 };
|
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);
|
struct entity_store *entity_store_alloc(void);
|
||||||
void entity_store_release(struct entity_store *store);
|
void entity_store_release(struct entity_store *store);
|
||||||
void entity_store_copy_replace(struct entity_store *dest, struct entity_store *src);
|
void entity_store_copy_replace(struct entity_store *dest, struct entity_store *src);
|
||||||
|
void entity_store_reset(struct entity_store *store);
|
||||||
|
|
||||||
/* Entity */
|
/* Entity */
|
||||||
struct entity *entity_alloc_unlinked(struct entity_store *store);
|
struct entity *entity_alloc_unlinked(struct entity_store *store);
|
||||||
|
|||||||
41
src/game.c
41
src/game.c
@ -224,12 +224,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
/* Clear level */
|
/* Clear level */
|
||||||
case GAME_CMD_KIND_CLEAR_ALL: {
|
case GAME_CMD_KIND_CLEAR_ALL: {
|
||||||
logf_info("Clearing level");
|
logf_info("Clearing level");
|
||||||
for (u64 i = 0; i < store->count; ++i) {
|
entity_store_reset(store);
|
||||||
struct entity *ent = &store->entities[i];
|
|
||||||
if (ent->valid && !ent->is_root) {
|
|
||||||
entity_release(store, ent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
/* Spawn test */
|
/* 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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[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;
|
if (sprite_tag_is_nil(ent->sprite)) continue;
|
||||||
|
|
||||||
/* Update animation */
|
/* 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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[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)) {
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
/* Process cmds */
|
/* 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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[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 (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
||||||
if (!ent->test_initialized) {
|
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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->active) continue;
|
||||||
|
|
||||||
/* Trigger equipped */
|
/* Trigger equipped */
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED)) {
|
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED)) {
|
||||||
struct entity *eq = entity_from_handle(store, ent->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);
|
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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[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 (!entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) continue;
|
||||||
if ((time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) 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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->active) continue;
|
||||||
|
|
||||||
/* Player angle */
|
/* 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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->active) continue;
|
||||||
|
|
||||||
/* Camera follow */
|
/* Camera follow */
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[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)) {
|
if (entity_has_prop(ent, ENTITY_PROP_TEST_SOUND_EMITTER)) {
|
||||||
struct mixer_desc desc = ent->sound_desc;
|
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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[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)) {
|
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED_NEXT_TICK)) {
|
||||||
entity_disable_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
|
* End frame cache scopes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -772,9 +772,8 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
__profscope(user_entity_iter);
|
__profscope(user_entity_iter);
|
||||||
|
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->active) continue;
|
||||||
if (ent->is_root) continue;
|
if (ent->is_root) continue;
|
||||||
|
|
||||||
struct sprite_tag sprite = ent->sprite;
|
struct sprite_tag sprite = ent->sprite;
|
||||||
@ -906,7 +905,7 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw hierarchy */
|
/* 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);
|
u32 color = RGBA_32_F(0.6, 0.6, 1, 0.75);
|
||||||
f32 thickness = 5;
|
f32 thickness = 5;
|
||||||
f32 arrow_height = 15;
|
f32 arrow_height = 15;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user