mirror of
				https://github.com/Ukendio/jecs.git
				synced 2025-11-04 02:49:18 +00:00 
			
		
		
		
	
							parent
							
								
									bee92f489c
								
							
						
					
					
						commit
						3c7f3b4eb3
					
				
					 5 changed files with 85 additions and 19 deletions
				
			
		
							
								
								
									
										4
									
								
								jecs.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								jecs.d.ts
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -105,7 +105,7 @@ export class World {
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Creates a new World.
 | 
						 * Creates a new World.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	constructor();
 | 
						private constructor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Enforces a check for entities to be created within a desired range.
 | 
						 * Enforces a check for entities to be created within a desired range.
 | 
				
			||||||
| 
						 | 
					@ -249,6 +249,8 @@ export class World {
 | 
				
			||||||
	query<T extends Id[]>(...components: T): Query<InferComponents<T>>;
 | 
						query<T extends Id[]>(...components: T): Query<InferComponents<T>>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function world(): World;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function component<T>(): Entity<T>;
 | 
					export function component<T>(): Entity<T>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function tag(): Tag;
 | 
					export function tag(): Tag;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										33
									
								
								jecs.luau
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								jecs.luau
									
									
									
									
									
								
							| 
						 | 
					@ -52,6 +52,8 @@ export type Query<T...> = typeof(setmetatable(
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
))
 | 
					))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type QueryArm<T...> = () -> ()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Observer = {
 | 
					export type Observer = {
 | 
				
			||||||
	callback: (archetype: Archetype) -> (),
 | 
						callback: (archetype: Archetype) -> (),
 | 
				
			||||||
	query: QueryInner,
 | 
						query: QueryInner,
 | 
				
			||||||
| 
						 | 
					@ -658,6 +660,9 @@ local function id_record_ensure(world: World, id: Entity): ComponentRecord
 | 
				
			||||||
	local relation = id
 | 
						local relation = id
 | 
				
			||||||
	local target = 0
 | 
						local target = 0
 | 
				
			||||||
	local is_pair = ECS_IS_PAIR(id :: number)
 | 
						local is_pair = ECS_IS_PAIR(id :: number)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local has_delete = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if is_pair then
 | 
						if is_pair then
 | 
				
			||||||
		relation = entity_index_get_alive(entity_index, ECS_PAIR_FIRST(id :: number)) :: i53
 | 
							relation = entity_index_get_alive(entity_index, ECS_PAIR_FIRST(id :: number)) :: i53
 | 
				
			||||||
		ecs_assert(relation and entity_index_is_alive(
 | 
							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
 | 
							target = entity_index_get_alive(entity_index, ECS_PAIR_SECOND(id :: number)) :: i53
 | 
				
			||||||
		ecs_assert(target and entity_index_is_alive(
 | 
							ecs_assert(target and entity_index_is_alive(
 | 
				
			||||||
			entity_index, target), ECS_INTERNAL_ERROR)
 | 
								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
 | 
							if cleanup_policy == EcsDelete then
 | 
				
			||||||
		has_delete = true
 | 
								has_delete = true
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local on_add, on_change, on_remove = world_get(world,
 | 
						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 value = values[i] :: any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		local on_add = idr.hooks.on_add
 | 
							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
 | 
								columns_map[id][row] = value
 | 
				
			||||||
 | 
								local on_change = idr.hooks.on_change
 | 
				
			||||||
			local hook = if set then on_change else on_add
 | 
								local hook = if set then on_change else on_add
 | 
				
			||||||
			if hook then
 | 
								if hook then
 | 
				
			||||||
				hook(entity, id, value :: any)
 | 
									hook(entity, id, value :: any)
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		else
 | 
							elseif on_add then
 | 
				
			||||||
			if on_add then
 | 
								on_add(entity, id)
 | 
				
			||||||
				on_add(entity, id, value)
 | 
					 | 
				
			||||||
			end
 | 
					 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -2533,6 +2539,7 @@ local function world_new()
 | 
				
			||||||
				end
 | 
									end
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local function inner_world_delete<T>(world: World, entity: Entity<T>)
 | 
						local function inner_world_delete<T>(world: World, entity: Entity<T>)
 | 
				
			||||||
| 
						 | 
					@ -2803,7 +2810,7 @@ local function world_new()
 | 
				
			||||||
			if value == NULL then
 | 
								if value == NULL then
 | 
				
			||||||
				inner_world_add(world, i, ty)
 | 
									inner_world_add(world, i, ty)
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				inner_world_add(world, i, ty, value)
 | 
									inner_world_set(world, i, ty, value)
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	"name": "@rbxts/jecs",
 | 
						"name": "@rbxts/jecs",
 | 
				
			||||||
	"version": "0.7.2",
 | 
						"version": "0.7.3",
 | 
				
			||||||
	"description": "Stupidly fast Entity Component System",
 | 
						"description": "Stupidly fast Entity Component System",
 | 
				
			||||||
	"main": "jecs.luau",
 | 
						"main": "jecs.luau",
 | 
				
			||||||
	"repository": {
 | 
						"repository": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,57 @@ local entity_visualiser = require("@tools/entity_visualiser")
 | 
				
			||||||
local lifetime_tracker_add = require("@tools/lifetime_tracker")
 | 
					local lifetime_tracker_add = require("@tools/lifetime_tracker")
 | 
				
			||||||
local dwi = entity_visualiser.stringify
 | 
					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()
 | 
					TEST("bulk", function()
 | 
				
			||||||
	local world = jecs.world()
 | 
						local world = jecs.world()
 | 
				
			||||||
	local A = world:component()
 | 
						local A = world:component()
 | 
				
			||||||
| 
						 | 
					@ -42,7 +93,10 @@ TEST("bulk", function()
 | 
				
			||||||
	CHECK(world:get(e, B) == 2)
 | 
						CHECK(world:get(e, B) == 2)
 | 
				
			||||||
	CHECK(world:get(e, C) == 3)
 | 
						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, A) == 1)
 | 
				
			||||||
	CHECK(world:get(e, B) == 2)
 | 
						CHECK(world:get(e, B) == 2)
 | 
				
			||||||
	CHECK(world:get(e, C) == 3)
 | 
						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, E) == nil and world:has(e, E))
 | 
				
			||||||
	CHECK(world:get(e, F) == 5)
 | 
						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, A) == 10)
 | 
				
			||||||
	CHECK(world:get(e, B) == 2)
 | 
						CHECK(world:get(e, B) == 2)
 | 
				
			||||||
| 
						 | 
					@ -441,7 +498,7 @@ TEST("world:delete()", function()
 | 
				
			||||||
		local A = world:entity()
 | 
							local A = world:entity()
 | 
				
			||||||
		local B = 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()
 | 
							local entity = world:entity()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "ukendio/jecs"
 | 
					name = "ukendio/jecs"
 | 
				
			||||||
version = "0.7.2"
 | 
					version = "0.7.3"
 | 
				
			||||||
registry = "https://github.com/UpliftGames/wally-index"
 | 
					registry = "https://github.com/UpliftGames/wally-index"
 | 
				
			||||||
realm = "shared"
 | 
					realm = "shared"
 | 
				
			||||||
license = "MIT"
 | 
					license = "MIT"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue