mirror of
				https://github.com/Ukendio/jecs.git
				synced 2025-11-03 18:39:19 +00:00 
			
		
		
		
	Remove eagerly
This commit is contained in:
		
							parent
							
								
									037035a9a1
								
							
						
					
					
						commit
						917c951d55
					
				
					 2 changed files with 153 additions and 73 deletions
				
			
		
							
								
								
									
										117
									
								
								jecs.luau
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								jecs.luau
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -54,6 +54,8 @@ export type Query<T...> = typeof(setmetatable(
 | 
			
		|||
		archetypes: (self: Query<T...>) -> { Archetype },
 | 
			
		||||
		cached: (self: Query<T...>) -> Query<T...>,
 | 
			
		||||
		ids: { Id<any> },
 | 
			
		||||
		filter_with: { Id<any> }?,
 | 
			
		||||
		filter_without: { Id<any> }?
 | 
			
		||||
		-- world: World
 | 
			
		||||
	},
 | 
			
		||||
	{} :: {
 | 
			
		||||
| 
						 | 
				
			
			@ -92,13 +94,14 @@ type archetype = {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
type componentrecord = {
 | 
			
		||||
	component: i53,
 | 
			
		||||
	records: { [number]: number },
 | 
			
		||||
	counts: { [i53]: number },
 | 
			
		||||
	flags: number,
 | 
			
		||||
	size: number,
 | 
			
		||||
 | 
			
		||||
	on_add: ((entity: i53, id: i53, value: any?) -> ())?,
 | 
			
		||||
	on_change: ((entity: i53, id: i53, value: any) -> ())?,
 | 
			
		||||
	on_add: ((entity: i53, id: i53, value: any, oldarchetype: archetype) -> ())?,
 | 
			
		||||
	on_change: ((entity: i53, id: i53, value: any, oldarchetype: archetype) -> ())?,
 | 
			
		||||
	on_remove: ((entity: i53, id: i53) -> ())?,
 | 
			
		||||
 | 
			
		||||
	wildcard_pairs: { [number]: componentrecord },
 | 
			
		||||
| 
						 | 
				
			
			@ -166,9 +169,9 @@ export type World = {
 | 
			
		|||
 | 
			
		||||
	observable: Map<Id, Map<Id, { Observer }>>,
 | 
			
		||||
 | 
			
		||||
	added: <T>(World, Entity<T>, <e>(e: Entity<e>, id: Id<T>, value: T) -> ()) -> () -> (),
 | 
			
		||||
	added: <T>(World, Entity<T>, <e>(e: Entity<e>, id: Id<T>, value: T, oldarchetype: Archetype) -> ()) -> () -> (),
 | 
			
		||||
	removed: <T>(World, Entity<T>, (e: Entity, id: Id<T>) -> ()) -> () -> (),
 | 
			
		||||
	changed:  <T>(World, Entity<T>, <e>(e: Entity<e>, id: Id<T>, value: T) -> ()) -> () -> (),
 | 
			
		||||
	changed:  <T>(World, Entity<T>, <e>(e: Entity<e>, id: Id<T>, value: T, oldarchetype: Archetype) -> ()) -> () -> (),
 | 
			
		||||
 | 
			
		||||
	--- Enforce a check on entities to be created within desired range
 | 
			
		||||
	range: (self: World, range_begin: number, range_end: number?) -> (),
 | 
			
		||||
| 
						 | 
				
			
			@ -262,8 +265,8 @@ export type ComponentRecord = {
 | 
			
		|||
	flags: number,
 | 
			
		||||
	size: number,
 | 
			
		||||
 | 
			
		||||
	on_add: (<T>(entity: Entity, id: Entity<T>, value: T?) -> ())?,
 | 
			
		||||
	on_change: (<T>(entity: Entity, id: Entity<T>, value: T) -> ())?,
 | 
			
		||||
	on_add: (<T>(entity: Entity, id: Entity<T>, value: T, oldarchetype: Archetype) -> ())?,
 | 
			
		||||
	on_change: (<T>(entity: Entity, id: Entity<T>, value: T, oldArchetype: Archetype) -> ())?,
 | 
			
		||||
	on_remove: ((entity: Entity, id: Entity) -> ())?,
 | 
			
		||||
}
 | 
			
		||||
export type ComponentIndex = Map<Id, ComponentRecord>
 | 
			
		||||
| 
						 | 
				
			
			@ -924,14 +927,6 @@ local function archetype_create(world: world, id_types: { i53 }, ty, prev: i53?)
 | 
			
		|||
 | 
			
		||||
			idr_t.size += 1
 | 
			
		||||
			archetype_append_to_records(idr_t, archetype_id, columns_map, t, i, column)
 | 
			
		||||
 | 
			
		||||
			-- Hypothetically this should only capture leaf component records
 | 
			
		||||
			local idr_t_wc_pairs = idr_t.wildcard_pairs
 | 
			
		||||
			if not idr_t_wc_pairs then
 | 
			
		||||
				idr_t_wc_pairs = {} :: {[i53]: componentrecord }
 | 
			
		||||
				idr_t.wildcard_pairs = idr_t_wc_pairs
 | 
			
		||||
			end
 | 
			
		||||
			idr_t_wc_pairs[component_id] = idr
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2058,6 +2053,7 @@ local function ecs_bulk_insert(world: world, entity: i53, ids: { i53 }, values:
 | 
			
		|||
		local dst_types = ids
 | 
			
		||||
		local to = archetype_ensure(world, dst_types)
 | 
			
		||||
		new_entity(entity, r, to)
 | 
			
		||||
		local ROOT_ARCHETYPE = world.ROOT_ARCHETYPE
 | 
			
		||||
		for i, id in ids do
 | 
			
		||||
			local value = values[i]
 | 
			
		||||
			local cdr = component_index[id]
 | 
			
		||||
| 
						 | 
				
			
			@ -2066,11 +2062,11 @@ local function ecs_bulk_insert(world: world, entity: i53, ids: { i53 }, values:
 | 
			
		|||
			if value then
 | 
			
		||||
				r.archetype.columns_map[id][r.row] = value
 | 
			
		||||
				if on_add then
 | 
			
		||||
					on_add(entity, id, value :: any)
 | 
			
		||||
					on_add(entity, id, value, ROOT_ARCHETYPE)
 | 
			
		||||
				end
 | 
			
		||||
			else
 | 
			
		||||
				if on_add then
 | 
			
		||||
					on_add(entity, id)
 | 
			
		||||
					on_add(entity, id, nil, ROOT_ARCHETYPE)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
| 
						 | 
				
			
			@ -2112,10 +2108,10 @@ local function ecs_bulk_insert(world: world, entity: i53, ids: { i53 }, values:
 | 
			
		|||
			local on_change = idr.on_change
 | 
			
		||||
			local hook = if set then on_change else on_add
 | 
			
		||||
			if hook then
 | 
			
		||||
				hook(entity, id, value :: any)
 | 
			
		||||
				hook(entity, id, value :: any, from)
 | 
			
		||||
			end
 | 
			
		||||
		elseif on_add then
 | 
			
		||||
			on_add(entity, id)
 | 
			
		||||
			on_add(entity, id, nil, from)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -2306,7 +2302,6 @@ local function world_new()
 | 
			
		|||
	end
 | 
			
		||||
 | 
			
		||||
	local function inner_entity_move(
 | 
			
		||||
		entity_index: entityindex,
 | 
			
		||||
		entity: i53,
 | 
			
		||||
		record: record,
 | 
			
		||||
		to: archetype
 | 
			
		||||
| 
						 | 
				
			
			@ -2380,7 +2375,7 @@ local function world_new()
 | 
			
		|||
			-- and just set the data directly.
 | 
			
		||||
			local on_change = idr.on_change
 | 
			
		||||
			if on_change then
 | 
			
		||||
				on_change(entity, id, data)
 | 
			
		||||
				on_change(entity, id, data, src)
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			local to: archetype
 | 
			
		||||
| 
						 | 
				
			
			@ -2450,7 +2445,7 @@ local function world_new()
 | 
			
		|||
 | 
			
		||||
			if from then
 | 
			
		||||
				-- If there was a previous archetype, then the entity needs to move the archetype
 | 
			
		||||
				inner_entity_move(entity_index, entity, record, to)
 | 
			
		||||
				inner_entity_move(entity, record, to)
 | 
			
		||||
			else
 | 
			
		||||
				new_entity(entity, record, to)
 | 
			
		||||
			end
 | 
			
		||||
| 
						 | 
				
			
			@ -2460,7 +2455,7 @@ local function world_new()
 | 
			
		|||
 | 
			
		||||
			local on_add = idr.on_add
 | 
			
		||||
			if on_add then
 | 
			
		||||
				on_add(entity, id, data)
 | 
			
		||||
				on_add(entity, id, data, src)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
| 
						 | 
				
			
			@ -2470,7 +2465,6 @@ local function world_new()
 | 
			
		|||
		entity: i53,
 | 
			
		||||
		id: i53
 | 
			
		||||
	): ()
 | 
			
		||||
		local entity_index = world.entity_index
 | 
			
		||||
		local record = entity_index_try_get_unsafe(entity :: number)
 | 
			
		||||
		if not record then
 | 
			
		||||
			return
 | 
			
		||||
| 
						 | 
				
			
			@ -2549,7 +2543,7 @@ local function world_new()
 | 
			
		|||
		end
 | 
			
		||||
 | 
			
		||||
		if from then
 | 
			
		||||
			inner_entity_move(entity_index, entity, record, to)
 | 
			
		||||
			inner_entity_move(entity, record, to)
 | 
			
		||||
		else
 | 
			
		||||
			if #to.types > 0 then
 | 
			
		||||
				new_entity(entity, record, to)
 | 
			
		||||
| 
						 | 
				
			
			@ -2559,7 +2553,7 @@ local function world_new()
 | 
			
		|||
		local on_add = idr.on_add
 | 
			
		||||
 | 
			
		||||
		if on_add then
 | 
			
		||||
			on_add(entity, id)
 | 
			
		||||
			on_add(entity, id, nil, src)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2593,7 +2587,7 @@ local function world_new()
 | 
			
		|||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	type Listener<T> = (e: i53, id: i53, value: T?) -> ()
 | 
			
		||||
	type Listener<T> = (e: i53, id: i53, value: T, oldarchetype: archetype) -> ()
 | 
			
		||||
 | 
			
		||||
	world.added = function<T>(_: world, component: i53, fn: Listener<T>)
 | 
			
		||||
		local listeners = signals.added[component]
 | 
			
		||||
| 
						 | 
				
			
			@ -2601,9 +2595,9 @@ local function world_new()
 | 
			
		|||
			listeners = {}
 | 
			
		||||
			signals.added[component] = listeners
 | 
			
		||||
 | 
			
		||||
			local function on_add(entity, id, value)
 | 
			
		||||
			local function on_add(entity, id, value, oldarchetype)
 | 
			
		||||
				for _, listener in listeners :: { Listener<T> } do
 | 
			
		||||
					listener(entity, id, value)
 | 
			
		||||
					listener(entity, id, value, oldarchetype)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			local existing_hook = world_get(world, component, EcsOnAdd) :: Listener<T>
 | 
			
		||||
| 
						 | 
				
			
			@ -2644,9 +2638,9 @@ local function world_new()
 | 
			
		|||
		if not listeners then
 | 
			
		||||
			listeners = {}
 | 
			
		||||
			signals.changed[component] = listeners
 | 
			
		||||
			local function on_change(entity, id, value: any)
 | 
			
		||||
			local function on_change(entity, id, value, oldarchetype)
 | 
			
		||||
				for _, listener in listeners :: { Listener<T> }  do
 | 
			
		||||
					listener(entity, id, value)
 | 
			
		||||
					listener(entity, id, value, oldarchetype)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			local existing_hook = world_get(world, component, EcsOnChange) :: Listener<T>
 | 
			
		||||
| 
						 | 
				
			
			@ -2686,7 +2680,7 @@ local function world_new()
 | 
			
		|||
			listeners = {}
 | 
			
		||||
			signals.removed[component] = listeners
 | 
			
		||||
			local function on_remove(entity, id)
 | 
			
		||||
				for _, listener in listeners :: { Listener<T> } do
 | 
			
		||||
				for _, listener in listeners :: { (...any) -> () } do
 | 
			
		||||
					listener(entity, id)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
| 
						 | 
				
			
			@ -2881,7 +2875,7 @@ local function world_new()
 | 
			
		|||
 | 
			
		||||
			local to = archetype_traverse_remove(world, id, record.archetype)
 | 
			
		||||
 | 
			
		||||
			inner_entity_move(entity_index, entity, record, to)
 | 
			
		||||
			inner_entity_move(entity, record, to)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2945,7 +2939,7 @@ local function world_new()
 | 
			
		|||
								-- this is hypothetically not that expensive of an operation anyways
 | 
			
		||||
								to = archetype_traverse_remove(world, entity, from)
 | 
			
		||||
							end
 | 
			
		||||
							inner_entity_move(entity_index, e, r, to)
 | 
			
		||||
							inner_entity_move(e, r, to)
 | 
			
		||||
						end
 | 
			
		||||
 | 
			
		||||
						archetype_destroy(world, idr_archetype)
 | 
			
		||||
| 
						 | 
				
			
			@ -2967,55 +2961,43 @@ local function world_new()
 | 
			
		|||
			end
 | 
			
		||||
		end
 | 
			
		||||
		if idr_t then
 | 
			
		||||
			for id, cr in idr_t.wildcard_pairs do
 | 
			
		||||
				local flags = cr.flags
 | 
			
		||||
				local flags_delete_mask = bit32.btest(flags, ECS_ID_DELETE)
 | 
			
		||||
				local on_remove = cr.on_remove
 | 
			
		||||
				if flags_delete_mask then
 | 
			
		||||
					for archetype_id in cr.records do
 | 
			
		||||
			local archetype_ids = idr_t.records
 | 
			
		||||
			for archetype_id in archetype_ids do
 | 
			
		||||
				local idr_t_archetype = archetypes[archetype_id]
 | 
			
		||||
				local idr_t_types = idr_t_archetype.types
 | 
			
		||||
				local entities = idr_t_archetype.entities
 | 
			
		||||
 | 
			
		||||
				for _, id in idr_t_types do
 | 
			
		||||
					if not ECS_IS_PAIR(id) then
 | 
			
		||||
						continue
 | 
			
		||||
					end
 | 
			
		||||
					local object = entity_index_get_alive(
 | 
			
		||||
					    entity_index, ECS_PAIR_SECOND(id))
 | 
			
		||||
					if object ~= entity then
 | 
			
		||||
						continue
 | 
			
		||||
					end
 | 
			
		||||
					local id_record = component_index[id]
 | 
			
		||||
					local flags = id_record.flags
 | 
			
		||||
					local flags_delete_mask = bit32.btest(flags, ECS_ID_DELETE)
 | 
			
		||||
					if flags_delete_mask then
 | 
			
		||||
						for i = #entities, 1, -1 do
 | 
			
		||||
							local child = entities[i]
 | 
			
		||||
							world_delete(world, child)
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
						break
 | 
			
		||||
					else
 | 
			
		||||
					for archetype_id in cr.records do
 | 
			
		||||
						local idr_t_archetype = archetypes[archetype_id]
 | 
			
		||||
						local entities = idr_t_archetype.entities
 | 
			
		||||
						-- archetype_traverse_remove is not idempotent meaning
 | 
			
		||||
						-- this access is actually unsafe because it can
 | 
			
		||||
						-- incorrectly cache an edge despite a node of the
 | 
			
		||||
						-- component id on the archetype does not exist. This
 | 
			
		||||
						-- requires careful testing to ensure correct values are
 | 
			
		||||
						-- being passed to the arguments.
 | 
			
		||||
						local to = archetype_traverse_remove(world, id, idr_t_archetype)
 | 
			
		||||
 | 
			
		||||
						for i = #entities, 1, -1 do
 | 
			
		||||
							local e = entities[i]
 | 
			
		||||
							local r = eindex_sparse_array[ECS_ID(e :: number)]
 | 
			
		||||
							if on_remove then
 | 
			
		||||
								on_remove(e, id)
 | 
			
		||||
 | 
			
		||||
								local from = r.archetype
 | 
			
		||||
								if from ~= idr_t_archetype then
 | 
			
		||||
									-- unfortunately the on_remove hook allows a window where `e` can have changed archetype
 | 
			
		||||
									-- this is hypothetically not that expensive of an operation anyways
 | 
			
		||||
									to = archetype_traverse_remove(world, id, from)
 | 
			
		||||
							local child = entities[i]
 | 
			
		||||
							world_remove(world, child, id)
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
							inner_entity_move(entity_index, e, r, to)
 | 
			
		||||
						end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
				for archetype_id in cr.records do
 | 
			
		||||
			for archetype_id in archetype_ids do
 | 
			
		||||
				archetype_destroy(world, archetypes[archetype_id])
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if idr_r then
 | 
			
		||||
			local archetype_ids = idr_r.records
 | 
			
		||||
| 
						 | 
				
			
			@ -3055,7 +3037,7 @@ local function world_new()
 | 
			
		|||
					for i = #entities, 1, -1 do
 | 
			
		||||
						local e = entities[i]
 | 
			
		||||
						local r = entity_index_try_get_unsafe(e) :: record
 | 
			
		||||
						inner_entity_move(entity_index, e, r, node)
 | 
			
		||||
						inner_entity_move(e, r, node)
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3065,6 +3047,7 @@ local function world_new()
 | 
			
		|||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		local dense = record.dense
 | 
			
		||||
		local i_swap = entity_index.alive_count
 | 
			
		||||
		entity_index.alive_count = i_swap - 1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,104 @@ type Id<T=unknown> = jecs.Id<T>
 | 
			
		|||
local entity_visualiser = require("@tools/entity_visualiser")
 | 
			
		||||
local dwi = entity_visualiser.stringify
 | 
			
		||||
 | 
			
		||||
SKIP()
 | 
			
		||||
TEST("jecs delete", function()
 | 
			
		||||
	do CASE "delete children"
 | 
			
		||||
		local world = jecs.world()
 | 
			
		||||
 | 
			
		||||
		local Health = world:component()
 | 
			
		||||
		local Poison = world:component()
 | 
			
		||||
		local FriendsWith = world:component()
 | 
			
		||||
 | 
			
		||||
		local e = world:entity()
 | 
			
		||||
		world:set(e, Poison, 5)
 | 
			
		||||
		world:set(e, Health, 50)
 | 
			
		||||
 | 
			
		||||
		local children = {}
 | 
			
		||||
		for i = 1, 10 do
 | 
			
		||||
			local child = world:entity()
 | 
			
		||||
			world:set(child, Poison, 9999)
 | 
			
		||||
			world:set(child, Health, 100)
 | 
			
		||||
			world:add(child, pair(jecs.ChildOf, e))
 | 
			
		||||
			table.insert(children, child)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		BENCH("delete children of entity", function()
 | 
			
		||||
			world:delete(e)
 | 
			
		||||
		end)
 | 
			
		||||
 | 
			
		||||
		for i, child in children do
 | 
			
		||||
			CHECK(not world:contains(child))
 | 
			
		||||
			CHECK(not world:has(child, pair(jecs.ChildOf, e)))
 | 
			
		||||
			CHECK(not world:has(child, Health))
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		e = world:entity()
 | 
			
		||||
 | 
			
		||||
		local friends = {}
 | 
			
		||||
		for i = 1, 10 do
 | 
			
		||||
			local friend = world:entity()
 | 
			
		||||
			world:set(friend, Poison, 9999)
 | 
			
		||||
			world:set(friend, Health, 100)
 | 
			
		||||
			world:add(friend, pair(FriendsWith, e))
 | 
			
		||||
			for j = 1, 10 do
 | 
			
		||||
				world:add(friend, world:component())
 | 
			
		||||
			end
 | 
			
		||||
			table.insert(friends, friend)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		BENCH("remove friends of entity", function()
 | 
			
		||||
			world:delete(e)
 | 
			
		||||
		end)
 | 
			
		||||
 | 
			
		||||
		for i, friend in friends do
 | 
			
		||||
			CHECK(not world:has(friend, pair(FriendsWith, e)))
 | 
			
		||||
			CHECK(world:has(friend, Health))
 | 
			
		||||
			CHECK(world:contains(friend))
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
TEST("pepe", function()
 | 
			
		||||
	local world = jecs.world()
 | 
			
		||||
	local t = world:entity()
 | 
			
		||||
	local c = world:component()
 | 
			
		||||
	world:add(c, t)
 | 
			
		||||
 | 
			
		||||
	local component = world:component()
 | 
			
		||||
	local lifetime = world:component()
 | 
			
		||||
 | 
			
		||||
	local tag = world:entity()
 | 
			
		||||
	local rel1 = world:entity()
 | 
			
		||||
	local rel2 = world:entity()
 | 
			
		||||
	local rel3 = world:entity()
 | 
			
		||||
 | 
			
		||||
	local destroyed = false
 | 
			
		||||
 | 
			
		||||
	world:removed(lifetime, function(e)
 | 
			
		||||
	    destroyed = true
 | 
			
		||||
	end)
 | 
			
		||||
 | 
			
		||||
	local parent = world:entity()
 | 
			
		||||
	world:set(parent, component, "foo")
 | 
			
		||||
	world:add(parent, jecs.pair(rel1, component))
 | 
			
		||||
 | 
			
		||||
	local other1 = world:entity()
 | 
			
		||||
	world:add(other1, tag)
 | 
			
		||||
	world:add(other1, jecs.pair(jecs.ChildOf, parent))
 | 
			
		||||
	world:add(other1, jecs.pair(rel1, component))
 | 
			
		||||
 | 
			
		||||
	local child = world:entity()
 | 
			
		||||
	world:set(child, lifetime, "")
 | 
			
		||||
	world:add(child, jecs.pair(jecs.ChildOf, parent))
 | 
			
		||||
	world:add(child, jecs.pair(rel3, parent))
 | 
			
		||||
	world:add(child, jecs.pair(rel2, other1))
 | 
			
		||||
 | 
			
		||||
	world:delete(parent)
 | 
			
		||||
 | 
			
		||||
	CHECK(destroyed)
 | 
			
		||||
	CHECK(not world:contains(child))
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
TEST("ardi", function()
 | 
			
		||||
	local world = jecs.world()
 | 
			
		||||
| 
						 | 
				
			
			@ -856,7 +954,6 @@ TEST("world:delete()", function()
 | 
			
		|||
		local world = jecs.world()
 | 
			
		||||
		local A = world:component()
 | 
			
		||||
		local B = world:component()
 | 
			
		||||
		local C = world:component()
 | 
			
		||||
		world:set(A, jecs.OnRemove, function(entity, id)
 | 
			
		||||
			world:set(entity, B, true)
 | 
			
		||||
		end)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue