sim iter helpers

This commit is contained in:
jacob 2025-11-13 15:49:31 -06:00
parent 5a3f5ad12b
commit 87848eaeac
3 changed files with 126 additions and 67 deletions

View File

@ -111,6 +111,92 @@ S_Ent *S_EntFromKey(S_World *world, S_Key key)
return ent; return ent;
} }
////////////////////////////////////////////////////////////
//~ Iteration helpers
void S_ResetIter(Arena *arena, S_Iter *iter, S_World *world, S_Key key, S_IterKind kind)
{
iter->kind = kind;
iter->world = world;
for (S_IterDfsNode *n = iter->first_dfs; n; n = n->next)
{
n->next = iter->first_free_dfs;
iter->first_free_dfs = n;
}
iter->first_dfs = 0;
{
S_IterDfsNode *n = iter->first_free_dfs;
if (n)
{
SllStackPop(iter->first_free_dfs);
ZeroStruct(n);
}
else
{
n = PushStruct(arena, S_IterDfsNode);
}
n->ent_key = key;
SllStackPush(iter->first_dfs, n);
}
}
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter)
{
S_Ent *result = &S_nil_ent;
S_World *world = iter->world;
b32 is_post_order = iter->kind == S_IterKind_Post;
b32 stop = 0;
while (!stop)
{
if (iter->first_dfs)
{
S_IterDfsNode *n = iter->first_dfs;
S_Ent *ent = S_EntFromKey(iter->world, n->ent_key);
if (!n->visited)
{
/* Push children to dfs stack */
for (S_Ent *child = S_EntFromKey(world, ent->last); !S_IsEntNil(child); child = S_EntFromKey(world, ent->prev))
{
S_IterDfsNode *child_n = iter->first_free_dfs;
if (child_n)
{
SllStackPop(iter->first_free_dfs);
ZeroStruct(child_n);
}
else
{
child_n = PushStruct(arena, S_IterDfsNode);
}
child_n->ent_key = child->key;
SllStackPush(iter->first_dfs, child_n);
}
n->visited = 1;
if (!is_post_order)
{
result = ent;
stop = 1;
}
}
else
{
SllStackPop(iter->first_dfs);
if (is_post_order)
{
result = ent;
stop = 1;
}
}
}
else
{
stop = 1;
}
}
return result;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Snapshot helpers //~ Snapshot helpers
@ -138,60 +224,6 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
SllStackPush(*bin, n); SllStackPush(*bin, n);
} }
/* Sort tree */
{
i64 ents_count = world->allocated_ents_count;
S_Ent **ents_pre = PushStructsNoZero(arena, S_Ent *, ents_count);
S_Ent **ents_post = PushStructsNoZero(arena, S_Ent *, ents_count);
{
Struct(EntNode) { EntNode *next; b32 visited; S_Ent *ent; };
EntNode *first_dfs = 0;
i64 pre_idx = 0;
i64 post_idx = 0;
{
EntNode *n = PushStruct(scratch.arena, EntNode);
for (i64 ent_idx = 0; ent_idx < world->allocated_ents_count; ++ent_idx)
{
S_Ent *ent = &world->ents[ent_idx];
if (S_MatchKey(ent->key, S_RootKey))
{
n->ent = ent;
break;
}
}
SllStackPush(first_dfs, n);
}
while (first_dfs)
{
EntNode *n = first_dfs;
S_Ent *ent = n->ent;
if (!n->visited)
{
/* Push children to dfs stack */
for (S_Ent *child = S_EntFromKey(world, ent->first); !S_IsEntNil(child); child = S_EntFromKey(world, child->prev))
{
EntNode *child_n = PushStruct(scratch.arena, EntNode);
child_n->ent = child;
SllStackPush(first_dfs, child_n);
}
ent->pre_idx = pre_idx++;
ents_pre[ent->pre_idx] = ent;
n->visited = 1;
}
else
{
SllStackPop(first_dfs);
ent->post_idx = post_idx++;
ents_post[ent->post_idx] = ent;
}
}
Assert(pre_idx == post_idx);
world->active_ents_count = pre_idx;
world->ents_pre = ents_pre;
world->ents_post = ents_post;
}
}
EndScratch(scratch); EndScratch(scratch);
return world; return world;
} }
@ -258,6 +290,7 @@ JobDef(S_SimWorker, _, __)
while (!shutdown) while (!shutdown)
{ {
ResetArena(frame_arena); ResetArena(frame_arena);
S_Iter ent_iter = ZI;
////////////////////////////// //////////////////////////////
//- Begin sim frame //- Begin sim frame
@ -297,6 +330,11 @@ JobDef(S_SimWorker, _, __)
////////////////////////////// //////////////////////////////
//- Update entities from user control //- Update entities from user control
S_ResetIter(frame_arena, &ent_iter, world, S_RootKey, S_IterKind_Post);
for (S_Ent *ent = S_NextEnt(frame_arena, &ent_iter); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &ent_iter))
{
}
////////////////////////////// //////////////////////////////
//- Publish sim state //- Publish sim state

View File

@ -52,10 +52,6 @@ Struct(S_Ent)
//- Final data //- Final data
Xform final_local_to_world_xf; Xform final_local_to_world_xf;
//- Per-world data
i64 pre_idx;
i64 post_idx;
} extern Readonly S_nil_ent; } extern Readonly S_nil_ent;
////////////////////////////// //////////////////////////////
@ -92,10 +88,6 @@ Struct(S_World)
S_EntLookupNode **ent_bins; S_EntLookupNode **ent_bins;
i64 ent_bins_count; i64 ent_bins_count;
S_Ent **ents_pre;
S_Ent **ents_post;
i64 active_ents_count;
}; };
Struct(S_Snapshot) Struct(S_Snapshot)
@ -111,6 +103,30 @@ Struct(S_SnapshotNode)
S_Snapshot snapshot; S_Snapshot snapshot;
}; };
////////////////////////////////////////////////////////////
//~ Iterator types
Enum(S_IterKind)
{
S_IterKind_Pre,
S_IterKind_Post,
};
Struct(S_IterDfsNode)
{
S_IterDfsNode *next;
b32 visited;
S_Key ent_key;
};
Struct(S_Iter)
{
S_IterKind kind;
S_World *world;
S_IterDfsNode *first_dfs;
S_IterDfsNode *first_free_dfs;
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Command types //~ Command types
@ -196,6 +212,12 @@ Vec2 S_SupportPointFromShape(S_Shape shape, Vec2 dir);
S_Ent *S_EntFromKey(S_World *world, S_Key key); S_Ent *S_EntFromKey(S_World *world, S_Key key);
////////////////////////////////////////////////////////////
//~ Iteration helpers
void S_ResetIter(Arena *arena, S_Iter *iter, S_World *world, S_Key key, S_IterKind kind);
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Snapshot helpers //~ Snapshot helpers

View File

@ -117,6 +117,7 @@ JobDef(V_VisWorker, _, __)
while (!shutdown) while (!shutdown)
{ {
ResetArena(frame_arena); ResetArena(frame_arena);
S_Iter ent_iter = ZI;
////////////////////////////// //////////////////////////////
//- Begin vis frame //- Begin vis frame
@ -346,12 +347,10 @@ JobDef(V_VisWorker, _, __)
//- Build render data //- Build render data
/* Build shapes */ /* Build shapes */
for (i64 pre_idx = 0; pre_idx < world->active_ents_count; ++pre_idx) S_ResetIter(frame_arena, &ent_iter, world, S_RootKey, S_IterKind_Pre);
for (S_Ent *ent = S_NextEnt(frame_arena, &ent_iter); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &ent_iter))
{ {
S_Ent *ent = &world->ents[pre_idx]; Xform xf = ent->final_local_to_world_xf;
// Xform xf = ent->final_to_world_xf;
Xform xf = XformIdentity;
S_Shape shape = S_MulXformShape(ent->final_local_to_world_xf, ent->local_shape); S_Shape shape = S_MulXformShape(ent->final_local_to_world_xf, ent->local_shape);
for (i32 point_idx = 0; point_idx < shape.points_count; ++point_idx) for (i32 point_idx = 0; point_idx < shape.points_count; ++point_idx)
{ {