diff --git a/examples/luau/queries/archetypes/targets.luau b/examples/luau/queries/archetypes/targets.luau index 5db27a8..f368ca2 100755 --- a/examples/luau/queries/archetypes/targets.luau +++ b/examples/luau/queries/archetypes/targets.luau @@ -1,60 +1,60 @@ --- Using world:target is the recommended way to grab the target in a wildcard --- query. However the random access can add up in very hot paths. Accessing its --- column can drastically improve performance, especially when there are --- multiple adjacent pairs. - -local jecs = require("@jecs") -local pair = jecs.pair -local __ = jecs.Wildcard - -local world = jecs.world() - -local Likes = world:entity() -local function name(e, name: string): string - if name then - world:set(e, jecs.Name, name) - return name - end - return assert(world:get(e, jecs.Name)) -end - -local e1 = world:entity() -name(e1, "e1") -local e2 = world:entity() -name(e2, "e2") -local e3 = world:entity() -name(e3, "e3") - -world:add(e1, pair(Likes, e2)) -world:add(e1, pair(Likes, e3)) - -local likes = jecs.component_record(world, pair(Likes, __)) -assert(likes) - -local likes_cr = likes.records -local likes_counts = likes.counts - -local archetypes = world:query(pair(Likes, __)):archetypes() - -for _, archetype in archetypes do - local types = archetype.types - - -- Get the starting index which is what the (R, *) alias is at - local wc = likes_cr[archetype.id] - local count = likes_counts[archetype.id] - - local entities = archetype.entities - for i = #entities, 1, -1 do - -- It is generally a good idea to iterate backwards on arrays if you - -- need to delete the iterated entity to prevent iterator invalidation - local entity = entities[i] - for cr = wc, wc + count - 1 do - local person = jecs.pair_second(world, types[cr]) - print(`entity ${entity} likes ${person}`) - end - end -end - --- Output: --- entity $273 likes $275 --- entity $273 likes $274 +-- Using world:target is the recommended way to grab the target in a wildcard +-- query. However the random access can add up in very hot paths. Accessing its +-- column can drastically improve performance, especially when there are +-- multiple adjacent pairs. + +local jecs = require("@jecs") +local pair = jecs.pair +local __ = jecs.Wildcard + +local world = jecs.world() + +local Likes = world:entity() +local function name(e, name: string): string + if name then + world:set(e, jecs.Name, name) + return name + end + return assert(world:get(e, jecs.Name)) +end + +local e1 = world:entity() +name(e1, "e1") +local e2 = world:entity() +name(e2, "e2") +local e3 = world:entity() +name(e3, "e3") + +world:add(e1, pair(Likes, e2)) +world:add(e1, pair(Likes, e3)) + +local likes = jecs.component_record(world, pair(Likes, __)) +assert(likes) + +local likes_cr = likes.records +local likes_counts = likes.counts + +local archetypes = world:query(pair(Likes, __)):archetypes() + +for _, archetype in archetypes do + local types = archetype.types + + -- Get the starting index which is what the (R, *) alias is at + local wc = likes_cr[archetype.id] + local count = likes_counts[archetype.id] + + local entities = archetype.entities + for i = #entities, 1, -1 do + -- It is generally a good idea to iterate backwards on arrays if you + -- need to delete the iterated entity to prevent iterator invalidation + local entity = entities[i] + for cr = wc, wc + count - 1 do + local person = jecs.pair_second(world, types[cr]) + print(`entity ${entity} likes ${person}`) + end + end +end + +-- Output: +-- entity $273 likes $275 +-- entity $273 likes $274 diff --git a/examples/luau/queries/archetypes/visibility_cascades.luau b/examples/luau/queries/archetypes/visibility_cascades.luau index 3228fa5..77ddd8d 100755 --- a/examples/luau/queries/archetypes/visibility_cascades.luau +++ b/examples/luau/queries/archetypes/visibility_cascades.luau @@ -1,44 +1,44 @@ --- To get the most out of performance, you can lift the inner loop of queries to --- the system in which you can do archetype-specific optimizations like finding --- the parent once per archetype rather than per entity. - -local jecs = require("@jecs") -local pair = jecs.pair -local ChildOf = jecs.ChildOf -local __ = jecs.Wildcard - -local world = jecs.world() - -local Position = world:component() :: jecs.Id -local Visible = world:entity() - -local parent = world:entity() -world:set(parent, Position, vector.zero) -world:add(parent, Visible) - -local child = world:entity() -world:set(child, Position, vector.one) -world:add(child, pair(ChildOf, parent)) - -local parents = jecs.component_record(world, pair(ChildOf, __)) -assert(parents) - -local parent_cr = parents.records - -local archetypes = world:query(Position, pair(ChildOf, __)):archetypes() - -for _, archetype in archetypes do - local types = archetype.types - local p = jecs.pair_second(world, types[parent_cr[archetype.id]]) - if world:has(p, Visible) then - local columns = archetype.columns_map - local positions = columns[Position] - for row, entity in archetype.entities do - local pos = positions[row] - print(`Child ${entity} of ${p} is visible at {pos}`) - end - end -end - --- Output: --- Child $274 of $273 is visibile at 1,1,1 +-- To get the most out of performance, you can lift the inner loop of queries to +-- the system in which you can do archetype-specific optimizations like finding +-- the parent once per archetype rather than per entity. + +local jecs = require("@jecs") +local pair = jecs.pair +local ChildOf = jecs.ChildOf +local __ = jecs.Wildcard + +local world = jecs.world() + +local Position = world:component() :: jecs.Id +local Visible = world:entity() + +local parent = world:entity() +world:set(parent, Position, vector.zero) +world:add(parent, Visible) + +local child = world:entity() +world:set(child, Position, vector.one) +world:add(child, pair(ChildOf, parent)) + +local parents = jecs.component_record(world, pair(ChildOf, __)) +assert(parents) + +local parent_cr = parents.records + +local archetypes = world:query(Position, pair(ChildOf, __)):archetypes() + +for _, archetype in archetypes do + local types = archetype.types + local p = jecs.pair_second(world, types[parent_cr[archetype.id]]) + if world:has(p, Visible) then + local columns = archetype.columns_map + local positions = columns[Position] + for row, entity in archetype.entities do + local pos = positions[row] + print(`Child ${entity} of ${p} is visible at {pos}`) + end + end +end + +-- Output: +-- Child $274 of $273 is visibile at 1,1,1