entity release prop
This commit is contained in:
parent
52db86b012
commit
cad25d24b2
@ -36,7 +36,6 @@ INTERNAL void store_make_root(struct entity_store *store)
|
|||||||
{
|
{
|
||||||
struct entity *root = entity_alloc_unlinked(store);
|
struct entity *root = entity_alloc_unlinked(store);
|
||||||
root->is_root = true;
|
root->is_root = true;
|
||||||
root->active = true;
|
|
||||||
root->local_xform = XFORM_IDENT;
|
root->local_xform = XFORM_IDENT;
|
||||||
root->cached_global_xform = XFORM_IDENT;
|
root->cached_global_xform = XFORM_IDENT;
|
||||||
root->cached_global_xform_dirty = false;
|
root->cached_global_xform_dirty = false;
|
||||||
@ -130,7 +129,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/entity.h
25
src/entity.h
@ -7,6 +7,9 @@
|
|||||||
enum entity_prop {
|
enum entity_prop {
|
||||||
ENTITY_PROP_NONE,
|
ENTITY_PROP_NONE,
|
||||||
|
|
||||||
|
ENTITY_PROP_ACTIVE,
|
||||||
|
ENTITY_PROP_RELEASE_AT_END_OF_TICK,
|
||||||
|
|
||||||
ENTITY_PROP_PLAYER_CONTROLLED,
|
ENTITY_PROP_PLAYER_CONTROLLED,
|
||||||
ENTITY_PROP_CAMERA,
|
ENTITY_PROP_CAMERA,
|
||||||
ENTITY_PROP_CAMERA_ACTIVE,
|
ENTITY_PROP_CAMERA_ACTIVE,
|
||||||
@ -14,7 +17,7 @@ enum entity_prop {
|
|||||||
ENTITY_PROP_WEAPON,
|
ENTITY_PROP_WEAPON,
|
||||||
ENTITY_PROP_TRIGGERING_EQUIPPED,
|
ENTITY_PROP_TRIGGERING_EQUIPPED,
|
||||||
ENTITY_PROP_TRIGGERED_THIS_TICK,
|
ENTITY_PROP_TRIGGERED_THIS_TICK,
|
||||||
ENTITY_PROP_TRIGGERED_NEXT_TICK,
|
ENTITY_PROP_TRIGGER_NEXT_TICK,
|
||||||
|
|
||||||
/* Test props */
|
/* Test props */
|
||||||
|
|
||||||
@ -61,12 +64,6 @@ 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 */
|
||||||
|
|
||||||
@ -193,25 +190,25 @@ INLINE struct entity_store *entity_store_nil(void)
|
|||||||
* Property helpers
|
* Property helpers
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INLINE void entity_enable_prop(struct entity *entity, enum entity_prop prop)
|
INLINE void entity_enable_prop(struct entity *ent, enum entity_prop prop)
|
||||||
{
|
{
|
||||||
u64 index = prop / 64;
|
u64 index = prop / 64;
|
||||||
u64 bit = prop % 64;
|
u64 bit = prop % 64;
|
||||||
entity->props[index] |= ((u64)1 << bit);
|
ent->props[index] |= ((u64)1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void entity_disable_prop(struct entity *entity, enum entity_prop prop)
|
INLINE void entity_disable_prop(struct entity *ent, enum entity_prop prop)
|
||||||
{
|
{
|
||||||
u64 index = prop / 64;
|
u64 index = prop / 64;
|
||||||
u64 bit = prop % 64;
|
u64 bit = prop % 64;
|
||||||
entity->props[index] &= ~((u64)1 << bit);
|
ent->props[index] &= ~((u64)1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE b32 entity_has_prop(struct entity *entity, enum entity_prop prop)
|
INLINE b32 entity_has_prop(struct entity *ent, enum entity_prop prop)
|
||||||
{
|
{
|
||||||
u64 index = prop / 64;
|
u64 index = prop / 64;
|
||||||
u64 bit = prop % 64;
|
u64 bit = prop % 64;
|
||||||
return !!(entity->props[index] & ((u64)1 << bit));
|
return !!(ent->props[index] & ((u64)1 << bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -228,7 +225,7 @@ void entity_store_reset(struct entity_store *store);
|
|||||||
struct entity *entity_alloc_unlinked(struct entity_store *store);
|
struct entity *entity_alloc_unlinked(struct entity_store *store);
|
||||||
struct entity *entity_alloc_top(struct entity_store *store);
|
struct entity *entity_alloc_top(struct entity_store *store);
|
||||||
struct entity *entity_alloc_child(struct entity *parent);
|
struct entity *entity_alloc_child(struct entity *parent);
|
||||||
void entity_release(struct entity_store *store, struct entity *entity);
|
void entity_release(struct entity_store *store, struct entity *ent);
|
||||||
|
|
||||||
/* Xform */
|
/* Xform */
|
||||||
struct xform entity_get_xform(struct entity *ent);
|
struct xform entity_get_xform(struct entity *ent);
|
||||||
|
|||||||
63
src/game.c
63
src/game.c
@ -243,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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
if (sprite_tag_is_nil(ent->sprite)) continue;
|
if (sprite_tag_is_nil(ent->sprite)) continue;
|
||||||
|
|
||||||
/* Update animation */
|
/* Update animation */
|
||||||
@ -295,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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
/* Process cmds */
|
/* Process cmds */
|
||||||
@ -314,12 +314,14 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
* start and immediate stop cmd should still move the player a
|
* start and immediate stop cmd should still move the player a
|
||||||
* tad. */
|
* tad. */
|
||||||
switch (cmd.kind) {
|
switch (cmd.kind) {
|
||||||
case GAME_CMD_KIND_PLAYER_MOVE: {
|
case GAME_CMD_KIND_PLAYER_MOVE:
|
||||||
|
{
|
||||||
move = cmd.move_dir;
|
move = cmd.move_dir;
|
||||||
focus = v2_sub(cmd.aim_pos, entity_get_xform(ent).og);
|
focus = v2_sub(cmd.aim_pos, entity_get_xform(ent).og);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case GAME_CMD_KIND_PLAYER_FIRE: {
|
case GAME_CMD_KIND_PLAYER_FIRE:
|
||||||
|
{
|
||||||
if (start) {
|
if (start) {
|
||||||
firing = true;
|
firing = true;
|
||||||
} else if (stop) {
|
} else if (stop) {
|
||||||
@ -354,7 +356,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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_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) {
|
||||||
@ -389,12 +391,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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_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->active) {
|
if (entity_has_prop(eq, ENTITY_PROP_ACTIVE)) {
|
||||||
entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,7 +409,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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_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;
|
||||||
|
|
||||||
@ -445,7 +447,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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
|
|
||||||
/* Player angle */
|
/* Player angle */
|
||||||
|
|
||||||
@ -535,7 +537,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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
|
|
||||||
/* Camera follow */
|
/* Camera follow */
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
||||||
@ -580,7 +582,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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_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;
|
||||||
@ -599,6 +601,35 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Release entities
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
/* TODO: Breadth first iteration to only release parent entities (since
|
||||||
|
* child entities will be released along with parent anyway) */
|
||||||
|
|
||||||
|
{
|
||||||
|
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
||||||
|
|
||||||
|
struct entity **ents_to_release = arena_dry_push(temp.arena, struct entity *);
|
||||||
|
u64 ents_to_release_count = 0;
|
||||||
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
|
struct entity *ent = &store->entities[entity_index];
|
||||||
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
|
if (entity_has_prop(ent, ENTITY_PROP_RELEASE_AT_END_OF_TICK)) {
|
||||||
|
*arena_push(temp.arena, struct entity *) = ent;
|
||||||
|
++ents_to_release_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u64 i = 0; i < ents_to_release_count; ++i) {
|
||||||
|
entity_release(store, ents_to_release[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_temp_end(temp);
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Publish tick
|
* Publish tick
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -655,10 +686,10 @@ 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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED_NEXT_TICK)) {
|
if (entity_has_prop(ent, ENTITY_PROP_TRIGGER_NEXT_TICK)) {
|
||||||
entity_disable_prop(ent, ENTITY_PROP_TRIGGERED_NEXT_TICK);
|
entity_disable_prop(ent, ENTITY_PROP_TRIGGER_NEXT_TICK);
|
||||||
entity_enable_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
entity_enable_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
||||||
} else if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) {
|
} else if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) {
|
||||||
entity_disable_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
entity_disable_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
||||||
@ -673,8 +704,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
if (!ent->active) {
|
if (!entity_has_prop(ent, ENTITY_PROP_ACTIVE)) {
|
||||||
ent->active = true;
|
entity_enable_prop(ent, ENTITY_PROP_ACTIVE);
|
||||||
++ent->continuity_gen;
|
++ent->continuity_gen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -456,7 +456,7 @@ INTERNAL void user_update(void)
|
|||||||
struct entity *e0 = &t0->entity_store->entities[i];
|
struct entity *e0 = &t0->entity_store->entities[i];
|
||||||
struct entity *e1 = &t1->entity_store->entities[i];
|
struct entity *e1 = &t1->entity_store->entities[i];
|
||||||
struct entity *e = &store->entities[i];
|
struct entity *e = &store->entities[i];
|
||||||
ASSERT(e->cached_global_xform_dirty == false); /* Game thread should have cached all global xforms before publishing */
|
ASSERT(!e->valid || e->cached_global_xform_dirty == false); /* Game thread should have cached all global xforms before publishing */
|
||||||
if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) {
|
if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) {
|
||||||
e->local_xform = xform_lerp(e0->local_xform, e1->local_xform, tick_blend);
|
e->local_xform = xform_lerp(e0->local_xform, e1->local_xform, tick_blend);
|
||||||
e->cached_global_xform = xform_lerp(e0->cached_global_xform, e1->cached_global_xform, tick_blend);
|
e->cached_global_xform = xform_lerp(e0->cached_global_xform, e1->cached_global_xform, tick_blend);
|
||||||
@ -773,7 +773,7 @@ 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->active) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
if (ent->is_root) continue;
|
if (ent->is_root) continue;
|
||||||
|
|
||||||
struct sprite_tag sprite = ent->sprite;
|
struct sprite_tag sprite = ent->sprite;
|
||||||
@ -905,7 +905,7 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw hierarchy */
|
/* Draw hierarchy */
|
||||||
if (parent->active && !parent->is_root) {
|
if (entity_has_prop(parent, ENTITY_PROP_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