mirror of
https://github.com/Ukendio/jecs.git
synced 2026-02-04 15:15:21 +00:00
Only delete archetypes when completely invalidated
This commit is contained in:
parent
007097b791
commit
4db44476a9
2 changed files with 82 additions and 14 deletions
|
|
@ -3084,17 +3084,6 @@ local function world_new()
|
|||
|
||||
local archetype = record.archetype
|
||||
|
||||
if archetype then
|
||||
for _, id in archetype.types do
|
||||
local idr = component_index[id]
|
||||
local on_remove = idr.on_remove
|
||||
if on_remove then
|
||||
on_remove(entity, id, true)
|
||||
end
|
||||
end
|
||||
archetype_delete(world, record.archetype, record.row)
|
||||
end
|
||||
|
||||
local component_index = world.component_index
|
||||
local archetypes = world.archetypes
|
||||
local tgt = ECS_PAIR(EcsWildcard, entity)
|
||||
|
|
@ -3163,6 +3152,7 @@ local function world_new()
|
|||
local idr_t_archetype = archetypes[archetype_id]
|
||||
local idr_t_types = idr_t_archetype.types
|
||||
local entities = idr_t_archetype.entities
|
||||
local will_delete_archetype = false
|
||||
|
||||
for _, id in idr_t_types do
|
||||
if not ECS_IS_PAIR(id) then
|
||||
|
|
@ -3173,6 +3163,7 @@ local function world_new()
|
|||
if object ~= entity then
|
||||
continue
|
||||
end
|
||||
will_delete_archetype = true
|
||||
local id_record = component_index[id]
|
||||
local flags = id_record.flags
|
||||
local flags_delete_mask = bit32.btest(flags, ECS_ID_DELETE)
|
||||
|
|
@ -3197,10 +3188,10 @@ local function world_new()
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for archetype_id in archetype_ids do
|
||||
archetype_destroy(world, archetypes[archetype_id])
|
||||
if will_delete_archetype then
|
||||
archetype_destroy(world, idr_t_archetype)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -3252,6 +3243,16 @@ local function world_new()
|
|||
end
|
||||
end
|
||||
|
||||
if archetype then
|
||||
for _, id in archetype.types do
|
||||
local cr = component_index[id]
|
||||
local on_remove = cr.on_remove
|
||||
if on_remove then
|
||||
on_remove(entity, id, true)
|
||||
end
|
||||
end
|
||||
archetype_delete(world, record.archetype, record.row)
|
||||
end
|
||||
|
||||
local dense = record.dense
|
||||
local i_swap = entity_index.alive_count
|
||||
|
|
|
|||
|
|
@ -24,6 +24,73 @@ type Id<T=unknown> = jecs.Id<T>
|
|||
local entity_visualiser = require("@modules/entity_visualiser")
|
||||
local dwi = entity_visualiser.stringify
|
||||
|
||||
FOCUS()
|
||||
TEST("reproduce idr_t nil archetype bug", function()
|
||||
local world = jecs.world()
|
||||
|
||||
local cts = {
|
||||
Humanoid = world:component(),
|
||||
Animator = world:component(),
|
||||
VelocitizeAnimationWeight = world:component(),
|
||||
}
|
||||
|
||||
local char = world:entity()
|
||||
|
||||
-- REMOVING ONE OF THESE THESE OFFSETS i BY +1
|
||||
world:set(char, cts.Humanoid, 0)
|
||||
world:set(char, cts.Animator, 0)
|
||||
--
|
||||
|
||||
world:added(cts.Humanoid, function() end) -- REMOVING THIS OFFSETS i BY +1 TOO
|
||||
world:removed(cts.Animator, function(entity, id)
|
||||
local r = jecs.record(world, entity)
|
||||
local src = r.archetype
|
||||
|
||||
--REMOVING THIS jecs.archetype_traverse_remove CALL STOPS IT FROM HAPPENING
|
||||
local dst = src and jecs.archetype_traverse_remove(world, id, src)
|
||||
end)
|
||||
|
||||
local batches = 10
|
||||
local batchSize = 20
|
||||
|
||||
local trackedEntities: { [number]: { parentId: number? } } = {}
|
||||
|
||||
for batch = 1, batches do
|
||||
for i = 1, batchSize do
|
||||
local root = world:entity()
|
||||
world:add(root, jecs.pair(jecs.ChildOf, char))
|
||||
|
||||
-- Removing animator from trackEntity1 causes it to stop happening
|
||||
local trackEntity1 = world:entity()
|
||||
world:set(trackEntity1, cts.Animator, 0)
|
||||
world:add(trackEntity1, jecs.pair(jecs.ChildOf, root))
|
||||
trackedEntities[trackEntity1] = { parentId = root }
|
||||
|
||||
-- Removing animator from trackEntity2 causes it to happen less frequently
|
||||
local trackEntity2 = world:entity()
|
||||
world:set(trackEntity2, cts.Animator, 0)
|
||||
world:add(trackEntity2, jecs.pair(jecs.ChildOf, root))
|
||||
trackedEntities[trackEntity2] = { parentId = root }
|
||||
|
||||
-- Removing this, but keeping Animator on the other 2 causes it to stop happening
|
||||
world:set(trackEntity1, cts.VelocitizeAnimationWeight, 0)
|
||||
|
||||
world:delete(root)
|
||||
|
||||
for entityId, info in trackedEntities do
|
||||
if world:contains(entityId) and not world:parent(entityId :: any) then
|
||||
print(`bugged entity found: {entityId}`)
|
||||
print(`original parent: {info.parentId}`)
|
||||
print(`batch = {batch}, i = {i}`)
|
||||
print("==========================================")
|
||||
trackedEntities[entityId] = nil
|
||||
world:deletee(entityId)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
TEST("Ensure archetype edges get cleaned", function()
|
||||
local A = jecs.component()
|
||||
local B = jecs.component()
|
||||
|
|
|
|||
Loading…
Reference in a new issue