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
|
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 component_index = world.component_index
|
||||||
local archetypes = world.archetypes
|
local archetypes = world.archetypes
|
||||||
local tgt = ECS_PAIR(EcsWildcard, entity)
|
local tgt = ECS_PAIR(EcsWildcard, entity)
|
||||||
|
|
@ -3163,6 +3152,7 @@ local function world_new()
|
||||||
local idr_t_archetype = archetypes[archetype_id]
|
local idr_t_archetype = archetypes[archetype_id]
|
||||||
local idr_t_types = idr_t_archetype.types
|
local idr_t_types = idr_t_archetype.types
|
||||||
local entities = idr_t_archetype.entities
|
local entities = idr_t_archetype.entities
|
||||||
|
local will_delete_archetype = false
|
||||||
|
|
||||||
for _, id in idr_t_types do
|
for _, id in idr_t_types do
|
||||||
if not ECS_IS_PAIR(id) then
|
if not ECS_IS_PAIR(id) then
|
||||||
|
|
@ -3173,6 +3163,7 @@ local function world_new()
|
||||||
if object ~= entity then
|
if object ~= entity then
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
will_delete_archetype = true
|
||||||
local id_record = component_index[id]
|
local id_record = component_index[id]
|
||||||
local flags = id_record.flags
|
local flags = id_record.flags
|
||||||
local flags_delete_mask = bit32.btest(flags, ECS_ID_DELETE)
|
local flags_delete_mask = bit32.btest(flags, ECS_ID_DELETE)
|
||||||
|
|
@ -3197,10 +3188,10 @@ local function world_new()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
for archetype_id in archetype_ids do
|
if will_delete_archetype then
|
||||||
archetype_destroy(world, archetypes[archetype_id])
|
archetype_destroy(world, idr_t_archetype)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -3252,6 +3243,16 @@ local function world_new()
|
||||||
end
|
end
|
||||||
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 dense = record.dense
|
||||||
local i_swap = entity_index.alive_count
|
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 entity_visualiser = require("@modules/entity_visualiser")
|
||||||
local dwi = entity_visualiser.stringify
|
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()
|
TEST("Ensure archetype edges get cleaned", function()
|
||||||
local A = jecs.component()
|
local A = jecs.component()
|
||||||
local B = jecs.component()
|
local B = jecs.component()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue