Skip to content

Commit

Permalink
Call entity_move before invoke_hook (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ukendio authored Sep 17, 2024
1 parent 2b1122e commit bd187e6
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 21 deletions.
44 changes: 40 additions & 4 deletions benches/general.luau
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ do TITLE "target"
world:set(ent, pair(A, B))
world:set(ent, pair(A, C))
world:set(ent, pair(A, D))
end
end

for i = 1, START(N) do
world:target(entities[i], A)
world:target(entities[i], A, 0)
end
end)

Expand All @@ -170,7 +170,10 @@ do TITLE(`query {N} entities`)
local function view_bench(n: number)
BENCH(`{n} entities per archetype`, function()
local world = jecs.World.new()
local A, B, C, D = world:entity(), world:entity(), world:entity(), world:entity()
local A = world:component()
local B = world:component()
local C = world:component()
local D = world:component()

for i = 1, N, n do
local ct = world:entity()
Expand All @@ -184,15 +187,48 @@ do TITLE(`query {N} entities`)
end
end


START()
for id in world:query(A, B, C, D) do
end
end)

BENCH(`inlined query`, function()
local world = jecs.World.new()
local A = world:component()
local B = world:component()
local C = world:component()
local D = world:component()

for i = 1, N, n do
local ct = world:entity()
for j = 1, n do
local id = world:entity()
world:set(id, A, true)
world:set(id, B, true)
world:set(id, C, true)
world:set(id, D, true)
world:set(id, ct, true)
end
end


START()
for _, archetype in world:query(A, B, C, D):archetypes() do
local columns, records = archetype.columns, archetype.records
local a = columns[records[A].column]
local b = columns[records[B].column]
local c = columns[records[C].column]
local d = columns[records[D].column]
for row in archetype.entities do
local _1, _2, _3, _4 = a[row], b[row], c[row], d[row]
end
end
end)
end

for i = 13, 0, -1 do
view_bench(2^i)
end
end

end
15 changes: 8 additions & 7 deletions src/init.luau
Original file line number Diff line number Diff line change
Expand Up @@ -728,8 +728,13 @@ local function world_remove(world: World, entity: i53, id: i53)
local to = archetype_traverse_remove(world, id, from)

if from and not (from == to) then
invoke_hook(world, EcsOnRemove, id, entity)
entity_move(entity_index, entity, record, to)
local idr = world.componentIndex[id]
local flags = idr.flags
local has_on_remove = bit32.band(flags, ECS_ID_HAS_ON_REMOVE) ~= 0
if has_on_remove then
invoke_hook(world, EcsOnRemove, id, entity)
end
end
end

Expand Down Expand Up @@ -955,7 +960,7 @@ local EMPTY_QUERY = {

setmetatable(EMPTY_QUERY, EMPTY_QUERY)

local function query_init(query)
local function query_iter(query)
local world_query_iter_next

if query.should_drain then
Expand Down Expand Up @@ -1215,12 +1220,8 @@ local function query_init(query)
return world_query_iter_next
end

local function query_iter(query)
return query_init(query)
end

local function query_drain(query)
local query_iter_next = query_init(query)
local query_iter_next = query_iter(query)
query.next = query_iter_next
query.should_drain = true
return query
Expand Down
41 changes: 31 additions & 10 deletions test/tests.luau
Original file line number Diff line number Diff line change
Expand Up @@ -1284,16 +1284,37 @@ TEST("Hooks", function()
end

do CASE "OnRemove"
local world = jecs.World.new()
local A = world:component()
local e1 = world:entity()
world:add(e1, A)
world:set(A, jecs.OnRemove, function(entity)
CHECK(e1 == entity)
CHECK(world:has(e1, A))
end)
world:remove(e1, A)
CHECK(not world:has(e1, A))
do
-- basic
local world = jecs.World.new()
local A = world:component()
local e1 = world:entity()
world:add(e1, A)
world:set(A, jecs.OnRemove, function(entity)
CHECK(e1 == entity)
CHECK(not world:has(e1, A))
end)
world:remove(e1, A)
CHECK(not world:has(e1, A))
end
do
-- [BUG] https://github.com/Ukendio/jecs/issues/118
local world = world_new()
local A = world:component()
local B = world:component()
local e = world:entity()

world:set(A, jecs.OnRemove, function(entity)
world:set(entity, B, true)
CHECK(not world:get(entity, A))
CHECK(world:get(entity, B))
end)

world:set(e, A, true)
world:remove(e, A)
CHECK(not world:get(e, A))
CHECK(world:get(e, B))
end
end

do CASE "the filip incident"
Expand Down

0 comments on commit bd187e6

Please sign in to comment.