mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-24 17:10:03 +00:00
Merge branch 'empty-query-replacement' of https://github.com/outofbearspace/jecs into empty-query-replacement
This commit is contained in:
commit
5a550c2786
5 changed files with 3572 additions and 11 deletions
|
@ -9,13 +9,16 @@ local function TITLE(title: string)
|
|||
end
|
||||
|
||||
local jecs = require("../mirror/init")
|
||||
local ecs = jecs.World.new()
|
||||
|
||||
local oldMatter = require("../oldMatter")
|
||||
|
||||
local newMatter = require("../newMatter")
|
||||
type i53 = number
|
||||
|
||||
do TITLE (testkit.color.white_underline("query"))
|
||||
do TITLE (testkit.color.white_underline("Jecs query"))
|
||||
local ecs = jecs.World.new()
|
||||
do TITLE "one component in common"
|
||||
|
||||
local function view_bench(
|
||||
world: jecs.World,
|
||||
A: i53, B: i53, C: i53, D: i53, E: i53, F: i53, G: i53, H: i53
|
||||
|
@ -61,37 +64,37 @@ do TITLE (testkit.color.white_underline("query"))
|
|||
|
||||
if flip() then
|
||||
combination ..= "B"
|
||||
ecs:set(entity, D2, true)
|
||||
ecs:set(entity, D2, {value = true})
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "C"
|
||||
ecs:set(entity, D3, true)
|
||||
ecs:set(entity, D3, { value = true })
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "D"
|
||||
ecs:set(entity, D4, true)
|
||||
ecs:set(entity, D4, { value = true})
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "E"
|
||||
ecs:set(entity, D5, true)
|
||||
ecs:set(entity, D5, { value = true})
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "F"
|
||||
ecs:set(entity, D6, true)
|
||||
ecs:set(entity, D6, {value = true})
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "G"
|
||||
ecs:set(entity, D7, true)
|
||||
ecs:set(entity, D7, { value = true})
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "H"
|
||||
ecs:set(entity, D8, true)
|
||||
ecs:set(entity, D8, {value = true})
|
||||
|
||||
end
|
||||
|
||||
if #combination == 7 then
|
||||
added += 1
|
||||
ecs:set(entity, D1, true)
|
||||
ecs:set(entity, D1, { value = true})
|
||||
end
|
||||
archetypes[combination] = true
|
||||
end
|
||||
|
@ -101,4 +104,196 @@ do TITLE (testkit.color.white_underline("query"))
|
|||
|
||||
view_bench(ecs, D1, D2, D3, D4, D5, D6, D7, D8)
|
||||
end
|
||||
end
|
||||
|
||||
do TITLE(testkit.color.white_underline("OldMatter query"))
|
||||
|
||||
local ecs = oldMatter.World.new()
|
||||
local component = oldMatter.component
|
||||
|
||||
do TITLE "one component in common"
|
||||
local function view_bench(
|
||||
world: jecs.World,
|
||||
A: i53, B: i53, C: i53, D: i53, E: i53, F: i53, G: i53, H: i53
|
||||
)
|
||||
|
||||
BENCH("1 component", function()
|
||||
for _ in world:query(A) do end
|
||||
end)
|
||||
|
||||
BENCH("2 component", function()
|
||||
for _ in world:query(A, B) do end
|
||||
end)
|
||||
|
||||
BENCH("4 component", function()
|
||||
for _ in world:query(A, B, C, D) do
|
||||
end
|
||||
end)
|
||||
|
||||
BENCH("8 component", function()
|
||||
for _ in world:query(A, B, C, D, E, F, G, H) do end
|
||||
end)
|
||||
end
|
||||
|
||||
local D1 = component()
|
||||
local D2 = component()
|
||||
local D3 = component()
|
||||
local D4 = component()
|
||||
local D5 = component()
|
||||
local D6 = component()
|
||||
local D7 = component()
|
||||
local D8 = component()
|
||||
|
||||
local function flip()
|
||||
return math.random() >= 0.15
|
||||
end
|
||||
|
||||
local added = 0
|
||||
local archetypes = {}
|
||||
for i = 1, 2^16-2 do
|
||||
local entity = ecs:spawn()
|
||||
|
||||
local combination = ""
|
||||
|
||||
if flip() then
|
||||
combination ..= "B"
|
||||
ecs:insert(entity, D2({value = true}))
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "C"
|
||||
ecs:insert(entity, D3({value = true}))
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "D"
|
||||
ecs:insert(entity, D4({value = true}))
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "E"
|
||||
ecs:insert(entity, D5({value = true}))
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "F"
|
||||
ecs:insert(entity, D6({value = true}))
|
||||
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "G"
|
||||
ecs:insert(entity, D7({value = true}))
|
||||
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "H"
|
||||
ecs:insert(entity, D8({value = true}))
|
||||
end
|
||||
|
||||
if #combination == 7 then
|
||||
added += 1
|
||||
ecs:insert(entity, D1({value = true}))
|
||||
|
||||
end
|
||||
archetypes[combination] = true
|
||||
end
|
||||
|
||||
local a = 0
|
||||
for _ in archetypes do a+= 1 end
|
||||
|
||||
view_bench(ecs, D1, D2, D3, D4, D5, D6, D7, D8)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do TITLE(testkit.color.white_underline("NewMatter query"))
|
||||
|
||||
local ecs = newMatter.World.new()
|
||||
local component = newMatter.component
|
||||
|
||||
do TITLE "one component in common"
|
||||
local function view_bench(
|
||||
world: jecs.World,
|
||||
A: i53, B: i53, C: i53, D: i53, E: i53, F: i53, G: i53, H: i53
|
||||
)
|
||||
|
||||
BENCH("1 component", function()
|
||||
for _ in world:query(A) do end
|
||||
end)
|
||||
|
||||
BENCH("2 component", function()
|
||||
for _ in world:query(A, B) do end
|
||||
end)
|
||||
|
||||
BENCH("4 component", function()
|
||||
for _ in world:query(A, B, C, D) do
|
||||
end
|
||||
end)
|
||||
|
||||
BENCH("8 component", function()
|
||||
for _ in world:query(A, B, C, D, E, F, G, H) do end
|
||||
end)
|
||||
end
|
||||
|
||||
local D1 = component()
|
||||
local D2 = component()
|
||||
local D3 = component()
|
||||
local D4 = component()
|
||||
local D5 = component()
|
||||
local D6 = component()
|
||||
local D7 = component()
|
||||
local D8 = component()
|
||||
|
||||
local function flip()
|
||||
return math.random() >= 0.15
|
||||
end
|
||||
|
||||
local added = 0
|
||||
local archetypes = {}
|
||||
for i = 1, 2^16-2 do
|
||||
local entity = ecs:spawn()
|
||||
|
||||
local combination = ""
|
||||
|
||||
if flip() then
|
||||
combination ..= "B"
|
||||
ecs:insert(entity, D2({value = true}))
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "C"
|
||||
ecs:insert(entity, D3({value = true}))
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "D"
|
||||
ecs:insert(entity, D4({value = true}))
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "E"
|
||||
ecs:insert(entity, D5({value = true}))
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "F"
|
||||
ecs:insert(entity, D6({value = true}))
|
||||
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "G"
|
||||
ecs:insert(entity, D7({value = true}))
|
||||
|
||||
end
|
||||
if flip() then
|
||||
combination ..= "H"
|
||||
ecs:insert(entity, D8({value = true}))
|
||||
end
|
||||
|
||||
if #combination == 7 then
|
||||
added += 1
|
||||
ecs:insert(entity, D1({value = true}))
|
||||
|
||||
end
|
||||
archetypes[combination] = true
|
||||
end
|
||||
|
||||
local a = 0
|
||||
for _ in archetypes do a+= 1 end
|
||||
|
||||
view_bench(ecs, D1, D2, D3, D4, D5, D6, D7, D8)
|
||||
end
|
||||
|
||||
end
|
|
@ -191,5 +191,113 @@ return function()
|
|||
end
|
||||
expect(count).to.equal(1)
|
||||
end)
|
||||
|
||||
it("should query all matching entities", function()
|
||||
|
||||
local world = jecs.World.new()
|
||||
local A = world:component()
|
||||
local B = world:component()
|
||||
|
||||
local entities = {}
|
||||
for i = 1, N do
|
||||
local id = world:entity()
|
||||
|
||||
|
||||
world:set(id, A, true)
|
||||
if i > 5 then world:set(id, B, true) end
|
||||
entities[i] = id
|
||||
end
|
||||
|
||||
for id in world:query(A) do
|
||||
local i = table.find(entities, id)
|
||||
expect(i).to.be.ok()
|
||||
table.remove(entities, i)
|
||||
end
|
||||
|
||||
expect(#entities).to.equal(0)
|
||||
end)
|
||||
|
||||
it("should query all matching entities when irrelevant component is removed", function()
|
||||
|
||||
|
||||
local world = jecs.World.new()
|
||||
local A = world:component()
|
||||
local B = world:component()
|
||||
|
||||
local entities = {}
|
||||
for i = 1, N do
|
||||
local id = world:entity()
|
||||
|
||||
world:set(id, A, true)
|
||||
world:set(id, B, true)
|
||||
if i > 5 then world:remove(id, B, true) end
|
||||
entities[i] = id
|
||||
end
|
||||
|
||||
local added = 0
|
||||
for id in world:query(A) do
|
||||
added += 1
|
||||
local i = table.find(entities, id)
|
||||
expect(i).to.be.ok()
|
||||
table.remove(entities, i)
|
||||
end
|
||||
|
||||
expect(added).to.equal(N)
|
||||
end)
|
||||
|
||||
it("should query all entities without B", function()
|
||||
local world = jecs.World.new()
|
||||
local A = world:component()
|
||||
local B = world:component()
|
||||
|
||||
local entities = {}
|
||||
for i = 1, N do
|
||||
local id = world:entity()
|
||||
|
||||
world:set(id, A, true)
|
||||
if i < 5 then
|
||||
entities[i] = id
|
||||
else
|
||||
world:set(id, B, true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for id in world:query(A):without(B) do
|
||||
local i = table.find(entities, id)
|
||||
expect(i).to.be.ok()
|
||||
table.remove(entities, i)
|
||||
end
|
||||
|
||||
expect(#entities).to.equal(0)
|
||||
end)
|
||||
|
||||
it("should allow setting components in arbitrary order", function()
|
||||
local world = jecs.World.new()
|
||||
|
||||
local Health = world:entity()
|
||||
local Poison = world:component()
|
||||
|
||||
local id = world:entity()
|
||||
world:set(id, Poison, 5)
|
||||
world:set(id, Health, 50)
|
||||
|
||||
expect(world:get(id, Poison)).to.equal(5)
|
||||
end)
|
||||
|
||||
it("Should allow deleting components", function()
|
||||
local world = jecs.World.new()
|
||||
|
||||
local Health = world:entity()
|
||||
local Poison = world:component()
|
||||
|
||||
local id = world:entity()
|
||||
world:set(id, Poison, 5)
|
||||
world:set(id, Health, 50)
|
||||
world:delete(id)
|
||||
|
||||
expect(world:get(id, Poison)).to.never.be.ok()
|
||||
expect(world:get(id, Health)).to.never.be.ok()
|
||||
end)
|
||||
end)
|
||||
end
|
1664
newMatter.lua
Normal file
1664
newMatter.lua
Normal file
File diff suppressed because it is too large
Load diff
1567
oldMatter.lua
Normal file
1567
oldMatter.lua
Normal file
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,6 @@ local TEST, CASE, CHECK, FINISH, SKIP = testkit.test()
|
|||
local N = 10
|
||||
|
||||
TEST("world:query", function()
|
||||
|
||||
do CASE "should query all matching entities"
|
||||
|
||||
local world = jecs.World.new()
|
||||
|
@ -83,6 +82,34 @@ TEST("world:query", function()
|
|||
|
||||
end
|
||||
|
||||
do CASE "should allow setting components in arbitrary order"
|
||||
local world = jecs.World.new()
|
||||
|
||||
local Health = world:entity()
|
||||
local Poison = world:component()
|
||||
|
||||
local id = world:entity()
|
||||
world:set(id, Poison, 5)
|
||||
world:set(id, Health, 50)
|
||||
|
||||
CHECK(world:get(id, Poison) == 5)
|
||||
end
|
||||
|
||||
do CASE "Should allow deleting components"
|
||||
local world = jecs.World.new()
|
||||
|
||||
local Health = world:entity()
|
||||
local Poison = world:component()
|
||||
|
||||
local id = world:entity()
|
||||
world:set(id, Poison, 5)
|
||||
world:set(id, Health, 50)
|
||||
world:delete(id)
|
||||
|
||||
CHECK(world:get(id, Poison) == nil)
|
||||
CHECK(world:get(id, Health) == nil)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
FINISH()
|
Loading…
Reference in a new issue