entity lifetime

This commit is contained in:
jacob 2026-03-19 17:21:46 -05:00
parent cbcec3639f
commit a6f9bcf4f3
8 changed files with 43 additions and 46 deletions

View File

@ -2,6 +2,7 @@
//~ Inflate
//
// DEFLATE decoder based on Handmade Hero's png parser
// https://www.youtube.com/watch?v=fuPhHEBTShI
//- Bitbuff

View File

@ -771,7 +771,6 @@ Struct(ComputeShaderDesc) { ResourceKey resource; u32 x, y, z; };
#define DeclPixelShader(name, resource_hash)
#endif
////////////////////////////////////////////////////////////
//~ Dynamic api linkage

View File

@ -717,8 +717,8 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
if (arg0_tok->valid)
{
String shader_name = arg0_tok->s;
Vec3U32 thread_dims = Zi;
i32 thread_dims_count = 1;
Vec3U32 group_dims = Zi;
i32 group_dims_count = 1;
{
StringList thread_count_args = Zi;
for (i32 arg_idx = 1; arg_idx < countof(entry->arg_tokens); ++arg_idx)
@ -733,21 +733,21 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
break;
}
}
String thread_count_str = StringFromList(perm, thread_count_args, Lit(" "));
Vec3 tmp = CR_Vec3FromString(thread_count_str);
thread_dims.x = MaxI32(tmp.x, 1);
thread_dims.y = MaxI32(tmp.y, 1);
thread_dims.z = MaxI32(tmp.z, 1);
// Determine compute shader dimensions by counting comma-separated values in dimensions string
for (u64 char_idx = 0; char_idx < thread_count_str.len; ++char_idx)
String group_dims_str = StringFromList(perm, thread_count_args, Lit(" "));
Vec3 tmp = CR_Vec3FromString(group_dims_str);
group_dims.x = MaxI32(tmp.x, 1);
group_dims.y = MaxI32(tmp.y, 1);
group_dims.z = MaxI32(tmp.z, 1);
// Determine compute shader dimensions type by counting comma-separated values in group size string
for (u64 char_idx = 0; char_idx < group_dims_str.len; ++char_idx)
{
u8 c = thread_count_str.text[char_idx];
u8 c = group_dims_str.text[char_idx];
if (c == ',')
{
thread_dims_count += 1;
group_dims_count += 1;
}
}
thread_dims_count = ClampI32(thread_dims_count, 1, 3);
group_dims_count = ClampI32(group_dims_count, 1, 3);
}
String decl_type = (
kind == M_EntryKind_VertexShader ? Lit("DeclVertexShader") :
@ -764,8 +764,8 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
"#define %F__ThreadDimsType %F",
FmtString(shader_name),
FmtString(
thread_dims_count == 1 ? Lit("u32") :
thread_dims_count == 2 ? Lit("Vec2U32") :
group_dims_count == 1 ? Lit("u32") :
group_dims_count == 2 ? Lit("Vec2U32") :
Lit("Vec3U32")
)
);
@ -782,9 +782,9 @@ void M_BuildEntryPoint(WaveLaneCtx *lane)
FmtString(decl_type),
FmtString(shader_name),
FmtHex(shader_resource_hash),
FmtUint(thread_dims.x),
FmtUint(thread_dims.y),
FmtUint(thread_dims.z)
FmtUint(group_dims.x),
FmtUint(group_dims.y),
FmtUint(group_dims.z)
);
}
else

View File

@ -5,6 +5,7 @@ Readonly P_Ent P_NilEnt = {
.xf = CompXformIdentity,
.control.look = { 1, 0 },
.health = 1,
.lifetime_seconds = Inf,
};
Readonly P_Constraint P_NilConstraint = {
@ -2168,11 +2169,24 @@ void P_StepFrame(P_Frame *frame)
i64 sim_dt_ns = SIM_TICK_INTERVAL_NS;
f64 sim_dt = SecondsFromNs(sim_dt_ns);
//////////////////////////////
//- Kill ents with expired lifetimes
{
for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
{
if (ent->lifetime_seconds != Inf && SecondsFromNs(frame->time_ns - ent->created_at_ns) >= ent->lifetime_seconds)
{
ent->exists = 0;
}
}
}
//////////////////////////////
//- Prune ents
{
// Mark dead entities
// Mark dead child ents
for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
{
if (ent->exists <= 0)

View File

@ -116,6 +116,7 @@ Struct(P_Ent)
u64 rand_seq;
i64 created_at_ns;
i64 created_at_tick;
f64 lifetime_seconds;
//- Build data

View File

@ -921,33 +921,6 @@ void S_TickForever(WaveLaneCtx *lane)
ZeroStruct(&P_tl.out_msgs);
}
//////////////////////////////
//- Prune ents
// {
// i64 ents_to_prune_count = 0;
// P_Ent **ents_to_prune = PushStructsNoZero(frame_arena, P_Ent *, world_frame->ents_count);
// for (P_Ent *ent = P_FirstEnt(world_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
// {
// if (ent->exists <= 0)
// {
// ents_to_prune[ents_to_prune_count] = ent;
// ents_to_prune_count += 1;
// }
// }
// for (i64 prune_idx = 0; prune_idx < ents_to_prune_count; ++prune_idx)
// {
// // FIXME: Ensure sure prunes are received by player
// P_Ent *ent = ents_to_prune[prune_idx];
// P_EntBin *bin = &world_frame->ent_bins[ent->key.v % world_frame->ent_bins_count];
// DllQueueRemoveNP(bin->first, bin->last, ent, next_in_bin, prev_in_bin);
// DllQueueRemoveNPZ(&P_NilEnt, world_frame->first_ent, world_frame->last_ent, ent, next, prev);
// world_frame->ents_count -= 1;
// SllStackPush(world->first_free_ent, ent);
// }
// }
//////////////////////////////
//- Publish Sim -> User data

View File

@ -76,6 +76,7 @@ String P_PackWorld(Arena *arena, P_World *src_world)
result.len += StringF(arena, " created_at_ns: \"%F\"\n", FmtSint(ent->created_at_ns)).len;
result.len += StringF(arena, " created_at_tick: \"%F\"\n", FmtSint(ent->created_at_tick)).len;
result.len += StringF(arena, " last_spawn_reset_ns: \"%F\"\n", FmtSint(ent->last_spawn_reset_ns)).len;
result.len += StringF(arena, " lifetime_seconds: \"%F\"\n", FmtFloat(ent->lifetime_seconds)).len;
result.len += StringF(arena, " pickup: \"0x%F\"\n", FmtHex(ent->pickup.v)).len;
result.len += StringF(arena, " pos: \"%F\"\n", FmtFloat2(ent->xf.t)).len;
result.len += StringF(arena, " angle: \"%F\"\n", FmtFloat(AngleFromVec2(ent->xf.r))).len;
@ -216,6 +217,10 @@ P_UnpackedWorld P_UnpackWorld(Arena *arena, String packed)
{
ent->last_spawn_reset_ns = CR_IntFromString(attr->value);
}
if (MatchString(attr->name, Lit("lifetime_seconds")))
{
ent->lifetime_seconds = CR_FloatFromString(attr->value);
}
if (MatchString(attr->name, Lit("pickup")))
{
ent->pickup.v = CR_IntFromString(attr->value);

View File

@ -1902,6 +1902,10 @@ void V_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Query local player