Compare commits

...

4 commits

Author SHA1 Message Date
Ukendio
6bb36f281e Merge branch 'main' of https://github.com/Ukendio/jecs
Some checks failed
analysis / Run Luau Analyze (push) Has been cancelled
deploy-docs / build (push) Has been cancelled
publish-npm / publish (push) Has been cancelled
unit-testing / Run Luau Tests (push) Has been cancelled
deploy-docs / Deploy (push) Has been cancelled
2025-04-05 04:55:21 +02:00
Ukendio
74ef525092 Fix dst clone 2025-04-05 04:55:11 +02:00
Ukendio
df6c568c6b 0.6.0-rc.1 2025-04-05 00:42:04 +02:00
Ukendio
d24ab71e4c Style fixes 2025-04-05 00:41:38 +02:00
5 changed files with 116 additions and 10 deletions

View file

@ -16,6 +16,10 @@ local function observers_new(world, description)
local r = jecs.entity_index_try_get_fast( local r = jecs.entity_index_try_get_fast(
entity_index, entity) entity_index, entity)
if not r then
return
end
local archetype = r.archetype local archetype = r.archetype
if jecs.query_match(query, archetype) then if jecs.query_match(query, archetype) then
@ -42,9 +46,13 @@ local function world_track(world, ...)
local r = jecs.entity_index_try_get_fast( local r = jecs.entity_index_try_get_fast(
entity_index, entity) entity_index, entity)
if not r then
return
end
local archetype = r.archetype local archetype = r.archetype
if jecs.query_match(q_shim, archetype) then if jecs.query_match(q_shim :: any, archetype) then
n += 1 n += 1
dense_array[n] = entity dense_array[n] = entity
sparse_array[entity] = n sparse_array[entity] = n
@ -73,7 +81,7 @@ local function world_track(world, ...)
return nil return nil
end end
i -= 1 i -= 1
return dense_array[row] return dense_array[row] :: any
end end
end end

View file

@ -124,9 +124,9 @@ local EcsOnArchetypeCreate = HI_COMPONENT_ID + 12
local EcsOnArchetypeDelete = HI_COMPONENT_ID + 13 local EcsOnArchetypeDelete = HI_COMPONENT_ID + 13
local EcsRest = HI_COMPONENT_ID + 14 local EcsRest = HI_COMPONENT_ID + 14
local ECS_ID_DELETE = 0b01 local ECS_ID_DELETE = 0b01
local ECS_ID_IS_TAG = 0b10 local ECS_ID_IS_TAG = 0b10
local ECS_ID_MASK = 0b00 local ECS_ID_MASK = 0b00
local ECS_ENTITY_MASK = bit32.lshift(1, 24) local ECS_ENTITY_MASK = bit32.lshift(1, 24)
local ECS_GENERATION_MASK = bit32.lshift(1, 16) local ECS_GENERATION_MASK = bit32.lshift(1, 16)
@ -733,13 +733,14 @@ local function find_archetype_with(world: ecs_world_t, node: ecs_archetype_t, id
-- them each time would be expensive. Instead this insertion sort can find the insertion -- them each time would be expensive. Instead this insertion sort can find the insertion
-- point in the types array. -- point in the types array.
local dst = table.clone(node.types) :: { i53 }
local at = find_insert(id_types, id) local at = find_insert(id_types, id)
if at == -1 then if at == -1 then
-- If it finds a duplicate, it just means it is the same archetype so it can return it -- If it finds a duplicate, it just means it is the same archetype so it can return it
-- directly instead of needing to hash types for a lookup to the archetype. -- directly instead of needing to hash types for a lookup to the archetype.
return node return node
end end
local dst = table.clone(node.types) :: { i53 }
table.insert(dst, at, id) table.insert(dst, at, id)
return archetype_ensure(world, dst) return archetype_ensure(world, dst)
@ -2600,7 +2601,7 @@ export type World = {
return { return {
World = World :: { new: () -> World }, World = World :: { new: () -> World },
world = World.new :: () -> World, world = world_new :: () -> World,
OnAdd = EcsOnAdd :: Entity<(entity: Entity) -> ()>, OnAdd = EcsOnAdd :: Entity<(entity: Entity) -> ()>,
OnRemove = EcsOnRemove :: Entity<(entity: Entity) -> ()>, OnRemove = EcsOnRemove :: Entity<(entity: Entity) -> ()>,

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "@rbxts/jecs", "name": "@rbxts/jecs",
"version": "0.5.5", "version": "0.6.0-rc.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@rbxts/jecs", "name": "@rbxts/jecs",
"version": "0.5.5", "version": "0.6.0-rc.1",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@rbxts/compiler-types": "^2.3.0-types.1", "@rbxts/compiler-types": "^2.3.0-types.1",

View file

@ -1,6 +1,6 @@
{ {
"name": "@rbxts/jecs", "name": "@rbxts/jecs",
"version": "0.5.5", "version": "0.6.0-rc.1",
"description": "Stupidly fast Entity Component System", "description": "Stupidly fast Entity Component System",
"main": "jecs.luau", "main": "jecs.luau",
"repository": { "repository": {

View file

@ -117,6 +117,103 @@ local function name(world, e)
return world:get(e, jecs.Name) return world:get(e, jecs.Name)
end end
local function worldReset(world)
local entity_index = world.entity_index
for i = jecs.Rest, entity_index.max_id do
local entity = entity_index.dense_array[i]
world:delete(entity)
end
for i = jecs.Rest, entity_index.max_id do
local sparse = entity_index.dense_array[i]
entity_index.sparse_array[sparse] = nil
entity_index.dense_array[i] = nil
end
entity_index.alive_count = jecs.Rest
entity_index.max_id = jecs.Rest
end
local lifetime_tracker_add = require("@tools/lifetime_tracker")
TEST("the great reset", function()
local world = world_new()
lifetime_tracker_add(world, {padding_enabled=false})
local A = world:component()
local B = world:component()
for i = 1, 10 do
local e = world:entity()
world:set(e, A, true)
world:set(e, B, true)
end
world:print_entity_index()
worldReset(world)
CHECK(world:contains(A))
CHECK(world:contains(B))
world:print_entity_index()
end)
TEST("#repro3", function()
local world = world_new()
local Model = world:component()
local ModelBase = world:component()
local systems = {}
local function progress()
for _, system in systems do
system()
end
end
local newQuery = nil
local oldQuery = nil
local function modelBase()
if not newQuery then
newQuery = world:query(Model):without(ModelBase):cached()
end
if not oldQuery then
oldQuery = world:query(ModelBase):without(Model):cached()
end
for e, model in newQuery do
world:set(e, ModelBase, { "part base" })
end
for e, model in oldQuery do
world:remove(e, ModelBase)
end
end
table.insert(systems, modelBase)
do CASE("should add the correct ModelBase for parts")
local e = world:entity()
world:set(e, Model, { instance = "Model" })
progress()
CHECK(world:get(e, ModelBase)[1] == "part base" )
end
do CASE("should add the correct ModelBase for parts")
local e = world:entity()
world:set(e, Model, { instance = "Model "})
progress()
CHECK(world:get(e, ModelBase)[1] == "part base")
end
do CASE("")
local e = world:entity()
world:set(e, Model, { instance = "Model "})
progress()
CHECK(world:get(e, ModelBase)[1] == "part base")
world:remove(e, Model)
progress()
CHECK(world:get(e, ModelBase) == nil)
end
end)
TEST("#adding a recycled target", function() TEST("#adding a recycled target", function()
local world = world_new() local world = world_new()
local R = world:component() local R = world:component()