[scene] Implement Scene_FreeAllEntities (and use it)

I guess I wasn't sure how to find all the allocated entities from within
the registry, but it turned out to be trivial. This takes care of leaked
static entities (and, in a later commit, leaked light entities, which is
how I found the problem).
This commit is contained in:
Bill Currie 2023-07-22 16:43:08 +09:00
parent befb3ca31b
commit c0f8d102ad
11 changed files with 48 additions and 25 deletions

View file

@ -101,7 +101,9 @@ typedef struct viewstate_s {
#define VF_GIB 2
struct msg_s;
struct scene_s;
void V_NewScene (viewstate_t *vs, struct scene_s *scene);
void V_Init (viewstate_t *vs);
void V_Init_Cvars (void);
void V_RenderView (viewstate_t *vs);

View file

@ -66,6 +66,7 @@ void CL_ParseBaseline (struct msg_s *msg, struct entity_state_s *baseline,
void CL_ParseStatic (struct msg_s *msg, int version);
void CL_MapCfg (const char *mapname);
void CL_World_NewMap (const char *mapname, const char *skyname);
void CL_World_Clear (void);
void CL_LoadLights (struct plitem_s *entities, struct scene_s *scene);
#endif//__client_world_h

View file

@ -932,9 +932,11 @@ void
V_RenderView (viewstate_t *vs)
{
if (!vs->active) {
vec4f_t base = { 0, 0, 0, 1 };
Transform_SetWorldPosition (vs->camera_transform, base);
Transform_SetWorldRotation (vs->camera_transform, base);
if (Transform_Valid (vs->camera_transform)) {
vec4f_t base = { 0, 0, 0, 1 };
Transform_SetWorldPosition (vs->camera_transform, base);
Transform_SetWorldRotation (vs->camera_transform, base);
}
return;
}
@ -952,6 +954,13 @@ V_RenderView (viewstate_t *vs)
}
}
void
V_NewScene (viewstate_t *viewstate, scene_t *scene)
{
viewstate->camera_transform = Transform_New (cl_world.scene->reg,
nulltransform);
}
void
V_Init (viewstate_t *viewstate)
{
@ -965,9 +974,6 @@ V_Init (viewstate_t *viewstate)
"currently being displayed.\n"
"Used when you are underwater, hit, have the Ring of "
"Shadows, or Quad Damage. (v_cshift r g b intensity)");
viewstate->camera_transform = Transform_New (cl_world.scene->reg,
nulltransform);
}
void

View file

@ -233,3 +233,10 @@ CL_World_NewMap (const char *mapname, const char *skyname)
SCR_NewScene (cl_world.scene);
map_cfg (mapname, 1);
}
void
CL_World_Clear (void)
{
Scene_FreeAllEntities (cl_world.scene);
CL_ClearTEnts ();
}

View file

@ -39,6 +39,7 @@
#include "QF/sys.h"
#include "QF/model.h"
#include "QF/plugin/vid_render.h"
#include "QF/scene/entity.h"
#include "QF/scene/scene.h"
#include "QF/scene/transform.h"
@ -73,6 +74,15 @@ destroy_visibility (void *_visibility)
}
}
static void
destroy_renderer (void *_renderer)
{
renderer_t *renderer = _renderer;
if (renderer->skin) {
mod_funcs->Skin_Free (renderer->skin);
}
}
static void
sw_identity_matrix (void *_mat)
{
@ -115,6 +125,7 @@ static const component_t scene_components[scene_comp_count] = {
[scene_renderer] = {
.size = sizeof (renderer_t),
.create = 0,//create_renderer,
.destroy = destroy_renderer,
.name = "renderer",
},
[scene_active] = {
@ -255,4 +266,12 @@ Scene_DestroyEntity (scene_t *scene, entity_t ent)
void
Scene_FreeAllEntities (scene_t *scene)
{
auto reg = scene->reg;
for (uint32_t i = 0; i < reg->num_entities; i++) {
uint32_t ent = reg->entities[i];
uint32_t ind = Ent_Index (ent);
if (ind == i) {
ECS_DelEntity (reg, ent);
}
}
}

View file

@ -72,15 +72,7 @@ CL_ClearEnts (void)
size_t i;
for (i = 0; i < MAX_EDICTS; i++) {
if (Entity_Valid (cl_entities[i])) {
entity_t ent = cl_entities[i];
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg);
if (renderer && renderer->skin) {
mod_funcs->Skin_Free (renderer->skin);
}
Scene_DestroyEntity (cl_world.scene, cl_entities[i]);
cl_entities[i] = nullentity;
}
cl_entities[i] = nullentity;
}
// clear other arrays

View file

@ -228,13 +228,11 @@ CL_ClearMemory (void)
Info_Destroy (cl.players[i].userinfo);
}
// wipe the entire cl structure
__auto_type cam = cl.viewstate.camera_transform;
memset (&cl, 0, sizeof (cl));
Sbar_Intermission (cl.intermission = 0, cl.time);
cl.viewstate.camera_transform = cam;
cl.viewstate.demoplayback = cls.demoplayback;
CL_ClearTEnts ();
CL_World_Clear ();
CL_ClearEnts ();
SCR_NewScene (0);

View file

@ -251,6 +251,8 @@ static void
CL_NewMap (const char *mapname)
{
CL_World_NewMap (mapname, 0);
V_NewScene (&cl.viewstate, cl_world.scene);
cl.chasestate.worldmodel = cl_world.scene->worldmodel;
Con_NewMap ();

View file

@ -72,10 +72,7 @@ CL_ClearEnts (void)
size_t i;
for (i = 0; i < MAX_CLIENTS; i++) {
if (Entity_Valid (cl_flag_ents[i])) {
Scene_DestroyEntity (cl_world.scene, cl_flag_ents[i]);
cl_flag_ents[i] = nullentity;
}
cl_flag_ents[i] = nullentity;
}
for (i = 0; i < 512; i++) {

View file

@ -624,9 +624,7 @@ CL_ClearState (void)
if (cl.serverinfo)
Info_Destroy (cl.serverinfo);
__auto_type players = cl.players;
__auto_type cam = cl.viewstate.camera_transform;
memset (&cl, 0, sizeof (cl));
cl.viewstate.camera_transform = cam;
cl.players = players;
SCR_SetFullscreen (0);
@ -651,7 +649,7 @@ CL_ClearState (void)
if (host_hunklevel) // FIXME: check this...
Hunk_FreeToLowMark (0, host_hunklevel);
CL_ClearEnts ();
CL_World_Clear ();
CL_ClearTEnts ();
cl.viewstate.weapon_entity = Scene_CreateEntity (cl_world.scene);

View file

@ -267,6 +267,7 @@ CL_NewMap (const char *mapname)
skyname = Info_ValueForKey (cl.serverinfo, "sky");
}
CL_World_NewMap (mapname, skyname);
V_NewScene (&cl.viewstate, cl_world.scene);
cl.chasestate.worldmodel = cl_world.scene->worldmodel;
Team_NewMap ();