mirror of
				https://github.com/Ukendio/jecs.git
				synced 2025-10-30 16:59:17 +00:00 
			
		
		
		
	Add dual types
This commit is contained in:
		
							parent
							
								
									9d83c3bc13
								
							
						
					
					
						commit
						f3befa3adb
					
				
					 4 changed files with 502 additions and 373 deletions
				
			
		|  | @ -5,21 +5,21 @@ local lifetime_tracker_add = require("@tools/lifetime_tracker") | |||
| local pe = require("@tools/entity_visualiser").prettify | ||||
| local world = lifetime_tracker_add(jecs.world(), {padding_enabled=false}) | ||||
| local FriendsWith = world:component() | ||||
| local _1 = world:print_snapshot() | ||||
| world:print_snapshot() | ||||
| local e1 = world:entity() | ||||
| local e2 = world:entity() | ||||
| world:delete(e2) | ||||
| 
 | ||||
| local _2 = world:print_snapshot() | ||||
| world:print_snapshot() | ||||
| local e3 = world:entity() | ||||
| world:add(e3, pair(ChildOf, e1)) | ||||
| local e4 = world:entity() | ||||
| world:add(e4, pair(FriendsWith, e3)) | ||||
| local _3 = world:print_snapshot() | ||||
| world:print_snapshot() | ||||
| world:delete(e1) | ||||
| world:delete(e3) | ||||
| local _4 = world:print_snapshot() | ||||
| world:print_snapshot() | ||||
| world:print_entity_index() | ||||
| world:entity() | ||||
| world:entity() | ||||
| local _5 = world:print_snapshot() | ||||
| world:print_snapshot() | ||||
|  |  | |||
|  | @ -117,6 +117,34 @@ local function name(world, e) | |||
| 	return world:get(e, jecs.Name) | ||||
| end | ||||
| 
 | ||||
| TEST("#repro2", function() | ||||
| 	local world = world_new() | ||||
| 	local Lifetime = world:component() :: jecs.Id<number> | ||||
| 	local Particle = world:entity() | ||||
| 	local Beam = world:entity() | ||||
| 
 | ||||
| 	local entity = world:entity() | ||||
| 	world:set(entity, pair(Lifetime, Particle), 1) | ||||
| 	world:set(entity, pair(Lifetime, Beam), 2) | ||||
| 
 | ||||
| 	for e in world:each(pair(Lifetime, __)) do | ||||
| 		local i = 0 | ||||
| 		local nth = world:target(e, Lifetime, i) | ||||
| 		while nth do | ||||
| 			local data = world:get(e, pair(Lifetime, nth)) | ||||
| 			if nth == Particle then | ||||
| 				CHECK(data == 1) | ||||
| 			elseif nth == Beam then | ||||
| 				CHECK(data == 2) | ||||
| 			else | ||||
| 				CHECK(false) | ||||
| 			end | ||||
| 			i += 1 | ||||
| 			nth = world:target(e, Lifetime, i) | ||||
| 		end | ||||
| 	end | ||||
| end) | ||||
| 
 | ||||
| TEST("#repro", function() | ||||
| 	local world = world_new() | ||||
| 
 | ||||
|  | @ -1394,24 +1422,10 @@ TEST("world:target", function() | |||
| 		CHECK(world:target(e, C, 0) == D) | ||||
| 		CHECK(world:target(e, C, 1) == nil) | ||||
| 
 | ||||
| 		-- for id in archetype.records do | ||||
| 		-- 	local f = world:get(ecs_pair_first(world, id), jecs.Name) | ||||
| 		-- 	local s = world:get(ecs_pair_second(world, id), jecs.Name) | ||||
| 		-- 	print(`({f}, {s})`) | ||||
| 		-- end | ||||
| 		-- | ||||
| 
 | ||||
| 		CHECK(archetype.records[pair(A, B)] == 1) | ||||
| 		CHECK(archetype.records[pair(A, C)] == 2) | ||||
| 		CHECK(archetype.records[pair(A, D)] == 3) | ||||
| 		CHECK(archetype.records[pair(A, E)] == 4) | ||||
| 		-- print("(A, B)", archetype.records[pair(A, B)]) | ||||
| 		-- print("(A, C)", archetype.records[pair(A, C)]) | ||||
| 		-- print("(A, D)", archetype.records[pair(A, D)]) | ||||
| 		-- print("(A, E)", archetype.records[pair(A, E)]) | ||||
| 
 | ||||
| 		-- print(pair(A, D), pair(B, C)) | ||||
| 		-- print("(B, C)", archetype.records[pair(B, C)]) | ||||
| 
 | ||||
| 		CHECK(world:target(e, C, 0) == D) | ||||
| 		CHECK(world:target(e, C, 1) == nil) | ||||
|  |  | |||
							
								
								
									
										108
									
								
								tools/runtime_lints.luau
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								tools/runtime_lints.luau
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,108 @@ | |||
| local function dbg_info(n: number): any | ||||
| 	return debug.info(n, "s") | ||||
| end | ||||
| local function throw(msg: string) | ||||
| 	local s = 1 | ||||
| 	local root = dbg_info(1) | ||||
| 	repeat | ||||
| 		s += 1 | ||||
| 	until dbg_info(s) ~= root | ||||
| 	if warn then | ||||
| 		error(msg, s) | ||||
| 	else | ||||
| 		print(`[jecs] error: {msg}\n`) | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| local function ASSERT<T>(v: T, msg: string) | ||||
| 	if v then | ||||
| 		return | ||||
| 	end | ||||
| 	throw(msg) | ||||
| end | ||||
| 
 | ||||
| local function runtime_lints_add(world) | ||||
| 	local function get_name(id) | ||||
| 		return world_get_one_inline(world, id, EcsName) | ||||
| 	end | ||||
| 
 | ||||
| 	local function bname(id): string | ||||
| 		local name: string | ||||
| 		if ECS_IS_PAIR(id) then | ||||
| 			local first = get_name(world, ecs_pair_first(world, id)) | ||||
| 			local second = get_name(world, ecs_pair_second(world, id)) | ||||
| 			name = `pair({first}, {second})` | ||||
| 		else | ||||
| 			return get_name(world, id) | ||||
| 		end | ||||
| 		if name then | ||||
| 			return name | ||||
| 		else | ||||
| 			return `${id}` | ||||
| 		end | ||||
| 	end | ||||
| 
 | ||||
| 	local function ID_IS_TAG(world: World, id) | ||||
| 		if ECS_IS_PAIR(id) then | ||||
| 			id = ecs_pair_first(world, id) | ||||
| 		end | ||||
| 		return not world_has_one_inline(world, id, EcsComponent) | ||||
| 	end | ||||
| 
 | ||||
| 	World.query = function(world: World, ...) | ||||
| 		ASSERT((...), "Requires at least a single component") | ||||
| 		return world_query(world, ...) | ||||
| 	end | ||||
| 
 | ||||
| 	World.set = function(world: World, entity: i53, id: i53, value: any): () | ||||
| 		local is_tag = ID_IS_TAG(world, id) | ||||
| 		if is_tag and value == nil then | ||||
| 			local _1 = bname(world, entity) | ||||
| 			local _2 = bname(world, id) | ||||
| 			local why = "cannot set component value to nil" | ||||
| 			throw(why) | ||||
| 			return | ||||
| 		elseif value ~= nil and is_tag then | ||||
| 			local _1 = bname(world, entity) | ||||
| 			local _2 = bname(world, id) | ||||
| 			local why = `cannot set a component value because {_2} is a tag` | ||||
| 			why ..= `\n[jecs] note: consider using "world:add({_1}, {_2})" instead` | ||||
| 			throw(why) | ||||
| 			return | ||||
| 		end | ||||
| 
 | ||||
| 		world_set(world, entity, id, value) | ||||
| 	end | ||||
| 
 | ||||
| 	World.add = function(world: World, entity: i53, id: i53, value: any) | ||||
| 		if value ~= nil then | ||||
| 			local _1 = bname(world, entity) | ||||
| 			local _2 = bname(world, id) | ||||
| 			throw("You provided a value when none was expected. " .. `Did you mean to use "world:add({_1}, {_2})"`) | ||||
| 		end | ||||
| 
 | ||||
| 		world_add(world, entity, id) | ||||
| 	end | ||||
| 
 | ||||
| 	World.get = function(world: World, entity: i53, ...) | ||||
| 		local length = select("#", ...) | ||||
| 		ASSERT(length < 5, "world:get does not support more than 4 components") | ||||
| 		local _1 | ||||
| 		for i = 1, length do | ||||
| 			local id = select(i, ...) | ||||
| 			local id_is_tag = not world_has(world, id, EcsComponent) | ||||
| 			if id_is_tag then | ||||
| 				local name = get_name(world, id) | ||||
| 				if not _1 then | ||||
| 					_1 = get_name(world, entity) | ||||
| 				end | ||||
| 				throw( | ||||
| 					`cannot get (#{i}) component {name} value because it is a tag.` | ||||
| 						.. `\n[jecs] note: If this was intentional, use "world:has({_1}, {name}) instead"` | ||||
| 				) | ||||
| 			end | ||||
| 		end | ||||
| 
 | ||||
| 		return world_get(world, entity, ...) | ||||
| 	end | ||||
| end | ||||
		Loading…
	
		Reference in a new issue