diff --git a/jecs.d.ts b/jecs.d.ts index cccf6d5..ea36bf8 100755 --- a/jecs.d.ts +++ b/jecs.d.ts @@ -105,7 +105,7 @@ export class World { /** * Creates a new World. */ - constructor(); + private constructor(); /** * Enforces a check for entities to be created within a desired range. @@ -249,6 +249,8 @@ export class World { query(...components: T): Query>; } +export function world(): World; + export function component(): Entity; export function tag(): Tag; diff --git a/jecs.luau b/jecs.luau index 3dacd69..214b066 100755 --- a/jecs.luau +++ b/jecs.luau @@ -52,6 +52,8 @@ export type Query = typeof(setmetatable( } )) +type QueryArm = () -> () + export type Observer = { callback: (archetype: Archetype) -> (), query: QueryInner, @@ -658,6 +660,9 @@ local function id_record_ensure(world: World, id: Entity): ComponentRecord local relation = id local target = 0 local is_pair = ECS_IS_PAIR(id :: number) + + local has_delete = false + if is_pair then relation = entity_index_get_alive(entity_index, ECS_PAIR_FIRST(id :: number)) :: i53 ecs_assert(relation and entity_index_is_alive( @@ -665,15 +670,18 @@ local function id_record_ensure(world: World, id: Entity): ComponentRecord target = entity_index_get_alive(entity_index, ECS_PAIR_SECOND(id :: number)) :: i53 ecs_assert(target and entity_index_is_alive( entity_index, target), ECS_INTERNAL_ERROR) - end - local cleanup_policy = world_target(world, relation, EcsOnDelete, 0) - local cleanup_policy_target = world_target(world, relation, EcsOnDeleteTarget, 0) + local cleanup_policy_target = world_target(world, relation, EcsOnDeleteTarget, 0) - local has_delete = false + if cleanup_policy_target == EcsDelete then + has_delete = true + end + else + local cleanup_policy = world_target(world, relation, EcsOnDelete, 0) - if cleanup_policy == EcsDelete or cleanup_policy_target == EcsDelete then - has_delete = true + if cleanup_policy == EcsDelete then + has_delete = true + end end local on_add, on_change, on_remove = world_get(world, @@ -2026,18 +2034,16 @@ local function ecs_bulk_insert(world: World, entity: Entity, ids: { Entity }, va local value = values[i] :: any local on_add = idr.hooks.on_add - local on_change = idr.hooks.on_change - if value then + if value ~= nil then columns_map[id][row] = value + local on_change = idr.hooks.on_change local hook = if set then on_change else on_add if hook then hook(entity, id, value :: any) end - else - if on_add then - on_add(entity, id, value) - end + elseif on_add then + on_add(entity, id) end end end @@ -2533,6 +2539,7 @@ local function world_new() end end end + end local function inner_world_delete(world: World, entity: Entity) @@ -2803,7 +2810,7 @@ local function world_new() if value == NULL then inner_world_add(world, i, ty) else - inner_world_add(world, i, ty, value) + inner_world_set(world, i, ty, value) end end end diff --git a/package.json b/package.json index 5e4af50..568bcbf 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rbxts/jecs", - "version": "0.7.2", + "version": "0.7.3", "description": "Stupidly fast Entity Component System", "main": "jecs.luau", "repository": { diff --git a/test/tests.luau b/test/tests.luau index 74a5cab..dd53258 100755 --- a/test/tests.luau +++ b/test/tests.luau @@ -25,6 +25,57 @@ local entity_visualiser = require("@tools/entity_visualiser") local lifetime_tracker_add = require("@tools/lifetime_tracker") local dwi = entity_visualiser.stringify +TEST("repro#", function() + do CASE "pair(OnDelete, Delete)" + local world = jecs.world() + local ct = world:component() + world:add(ct, jecs.pair(jecs.OnDelete, jecs.Delete)) + + local e1 = world:entity() + local e2 = world:entity() + + local dummy = world:entity() + + world:add(e1, ct) + world:add(e2, jecs.pair(ct, dummy)) + + world:delete(dummy) + + CHECK(world:contains(e2)) + + world:delete(ct) + + CHECK(not world:contains(e1)) + end + + do CASE "pair(OnDeleteTarget, Delete)" + print("start") + local world = jecs.world() + local ct = world:component() + world:add(ct, jecs.pair(jecs.OnDeleteTarget, jecs.Delete)) + + local e1 = world:entity() + local e2 = world:entity() + + -- local dummy = world:entity() + + print("flags") + world:add(e1, ct) + + print(world.component_index[ct].flags) + -- world:add(e2, jecs.pair(ct, dummy)) + + -- world:delete(dummy) + + -- CHECK(not world:contains(e2)) + + world:delete(ct) + + CHECK(world:contains(e1)) + end + +end) + TEST("bulk", function() local world = jecs.world() local A = world:component() @@ -42,7 +93,10 @@ TEST("bulk", function() CHECK(world:get(e, B) == 2) CHECK(world:get(e, C) == 3) - jecs.bulk_insert(world, e, { D, E, F }, { 4, nil, 5 }) + jecs.bulk_insert(world, e, + { D, E, F }, + { 4, nil, 5 } + ) CHECK(world:get(e, A) == 1) CHECK(world:get(e, B) == 2) CHECK(world:get(e, C) == 3) @@ -51,7 +105,10 @@ TEST("bulk", function() CHECK(world:get(e, E) == nil and world:has(e, E)) CHECK(world:get(e, F) == 5) - jecs.bulk_insert(world, e, { A, D, E, F, C }, { 10, 40, nil, 50, 30 }) + jecs.bulk_insert(world, e, + { A, D, E, F, C }, + { 10, 40, nil, 50, 30 } + ) CHECK(world:get(e, A) == 10) CHECK(world:get(e, B) == 2) @@ -441,7 +498,7 @@ TEST("world:delete()", function() local A = world:entity() local B = world:entity() - world:add(Relation, pair(jecs.OnDelete, jecs.Delete)) + world:add(Relation, pair(jecs.OnDeleteTarget, jecs.Delete)) local entity = world:entity() diff --git a/wally.toml b/wally.toml index a551265..19f4969 100755 --- a/wally.toml +++ b/wally.toml @@ -1,6 +1,6 @@ [package] name = "ukendio/jecs" -version = "0.7.2" +version = "0.7.3" registry = "https://github.com/UpliftGames/wally-index" realm = "shared" license = "MIT"