mirror of
				https://github.com/Ukendio/jecs.git
				synced 2025-11-03 18:39:19 +00:00 
			
		
		
		
	Remove focus
	
		
			
	
		
	
	
		
	
		
			Some checks are pending
		
		
	
	
	
				
					
				
			
		
			Some checks are pending
		
		
	
	
This commit is contained in:
		
							parent
							
								
									1eecaac96f
								
							
						
					
					
						commit
						3dacb2af80
					
				
					 5 changed files with 110 additions and 87 deletions
				
			
		| 
						 | 
					@ -2,33 +2,12 @@
 | 
				
			||||||
--!native
 | 
					--!native
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
 | 
					local ReplicatedStorage = game:GetService("ReplicatedStorage")
 | 
				
			||||||
local Matter = require(ReplicatedStorage.DevPackages.Matter)
 | 
					 | 
				
			||||||
local ecr = require(ReplicatedStorage.DevPackages.ecr)
 | 
					 | 
				
			||||||
local newWorld = Matter.World.new()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local jecs = require(ReplicatedStorage.Lib:Clone())
 | 
					local jecs = require(ReplicatedStorage.Lib:Clone())
 | 
				
			||||||
local mirror = require(ReplicatedStorage.mirror:Clone())
 | 
					local mirror = require(ReplicatedStorage.mirror:Clone())
 | 
				
			||||||
local mcs = mirror.world()
 | 
					local mcs = mirror.world()
 | 
				
			||||||
local ecs = jecs.world()
 | 
					local ecs = jecs.world()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local A1 = Matter.component()
 | 
					 | 
				
			||||||
local A2 = Matter.component()
 | 
					 | 
				
			||||||
local A3 = Matter.component()
 | 
					 | 
				
			||||||
local A4 = Matter.component()
 | 
					 | 
				
			||||||
local A5 = Matter.component()
 | 
					 | 
				
			||||||
local A6 = Matter.component()
 | 
					 | 
				
			||||||
local A7 = Matter.component()
 | 
					 | 
				
			||||||
local A8 = Matter.component()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local B1 = ecr.component()
 | 
					 | 
				
			||||||
local B2 = ecr.component()
 | 
					 | 
				
			||||||
local B3 = ecr.component()
 | 
					 | 
				
			||||||
local B4 = ecr.component()
 | 
					 | 
				
			||||||
local B5 = ecr.component()
 | 
					 | 
				
			||||||
local B6 = ecr.component()
 | 
					 | 
				
			||||||
local B7 = ecr.component()
 | 
					 | 
				
			||||||
local B8 = ecr.component()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local D1 = ecs:component()
 | 
					local D1 = ecs:component()
 | 
				
			||||||
local D2 = ecs:component()
 | 
					local D2 = ecs:component()
 | 
				
			||||||
local D3 = ecs:component()
 | 
					local D3 = ecs:component()
 | 
				
			||||||
| 
						 | 
					@ -47,90 +26,53 @@ local E6 = mcs:component()
 | 
				
			||||||
local E7 = mcs:component()
 | 
					local E7 = mcs:component()
 | 
				
			||||||
local E8 = mcs:component()
 | 
					local E8 = mcs:component()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local registry2 = ecr.registry()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local function flip()
 | 
					local function flip()
 | 
				
			||||||
	return math.random() >= 0.25
 | 
						return math.random() >= 0.3
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local N = 2 ^ 16 - 2
 | 
					local N = 2 ^ 16 - 2
 | 
				
			||||||
local archetypes = {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local hm = 0
 | 
					 | 
				
			||||||
for i = 1, N do
 | 
					for i = 1, N do
 | 
				
			||||||
	local id = registry2.create()
 | 
					 | 
				
			||||||
	local combination = ""
 | 
					 | 
				
			||||||
	local n = newWorld:spawn()
 | 
					 | 
				
			||||||
	local entity = ecs:entity()
 | 
						local entity = ecs:entity()
 | 
				
			||||||
	local m = mcs:entity()
 | 
						local m = mcs:entity()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if flip() then
 | 
						if flip() then
 | 
				
			||||||
		registry2:set(id, B1, { value = true })
 | 
							ecs:add(entity, entity)
 | 
				
			||||||
		ecs:set(entity, D1, { value = true })
 | 
							mcs:add(m, m)
 | 
				
			||||||
		newWorld:insert(n, A1({ value = true }))
 | 
					 | 
				
			||||||
		mcs:set(m, E1, { value = 2 })
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	if flip() then
 | 
						if flip() then
 | 
				
			||||||
		combination ..= "B"
 | 
							ecs:set(entity, D1, true)
 | 
				
			||||||
		registry2:set(id, B2, { value = true })
 | 
							mcs:set(m, E1, true)
 | 
				
			||||||
		ecs:set(entity, D2, { value = true })
 | 
					 | 
				
			||||||
		mcs:set(m, E2, { value = 2 })
 | 
					 | 
				
			||||||
		newWorld:insert(n, A2({ value = true }))
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	if flip() then
 | 
						if flip() then
 | 
				
			||||||
		combination ..= "C"
 | 
							ecs:set(entity, D2, true)
 | 
				
			||||||
		registry2:set(id, B3, { value = true })
 | 
							mcs:set(m, E2, true)
 | 
				
			||||||
		ecs:set(entity, D3, { value = true })
 | 
					 | 
				
			||||||
		mcs:set(m, E3, { value = 2 })
 | 
					 | 
				
			||||||
		newWorld:insert(n, A3({ value = true }))
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	if flip() then
 | 
						if flip() then
 | 
				
			||||||
		combination ..= "D"
 | 
							ecs:set(entity, D3, true)
 | 
				
			||||||
		registry2:set(id, B4, { value = true })
 | 
							mcs:set(m, E3, true)
 | 
				
			||||||
		ecs:set(entity, D4, { value = true })
 | 
					 | 
				
			||||||
		mcs:set(m, E4, { value = 2 })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		newWorld:insert(n, A4({ value = true }))
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	if flip() then
 | 
						if flip() then
 | 
				
			||||||
		combination ..= "E"
 | 
							ecs:set(entity, D4, true)
 | 
				
			||||||
		registry2:set(id, B5, { value = true })
 | 
							mcs:set(m, E4, true)
 | 
				
			||||||
		ecs:set(entity, D5, { value = true })
 | 
					 | 
				
			||||||
		mcs:set(m, E5, { value = 2 })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		newWorld:insert(n, A5({ value = true }))
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	if flip() then
 | 
						if flip() then
 | 
				
			||||||
		combination ..= "F"
 | 
							ecs:set(entity, D5, true)
 | 
				
			||||||
		registry2:set(id, B6, { value = true })
 | 
							mcs:set(m, E5, true)
 | 
				
			||||||
		ecs:set(entity, D6, { value = true })
 | 
					 | 
				
			||||||
		mcs:set(m, E6, { value = 2 })
 | 
					 | 
				
			||||||
		newWorld:insert(n, A6({ value = true }))
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	if flip() then
 | 
						if flip() then
 | 
				
			||||||
		combination ..= "G"
 | 
							ecs:set(entity, D6, true)
 | 
				
			||||||
		registry2:set(id, B7, { value = true })
 | 
							mcs:set(m, E6, true)
 | 
				
			||||||
		ecs:set(entity, D7, { value = true })
 | 
					 | 
				
			||||||
		mcs:set(m, E7, { value = 2 })
 | 
					 | 
				
			||||||
		newWorld:insert(n, A7({ value = true }))
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	if flip() then
 | 
						if flip() then
 | 
				
			||||||
		combination ..= "H"
 | 
							ecs:set(entity, D7, true)
 | 
				
			||||||
		registry2:set(id, B8, { value = true })
 | 
							mcs:set(m, E7, true)
 | 
				
			||||||
		newWorld:insert(n, A8({ value = true }))
 | 
					 | 
				
			||||||
		ecs:set(entity, D8, { value = true })
 | 
					 | 
				
			||||||
		mcs:set(m, E8, { value = 2 })
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
						if flip() then
 | 
				
			||||||
	if combination:find("BCDF") then
 | 
							ecs:set(entity, D8, true)
 | 
				
			||||||
		if not archetypes[combination] then
 | 
							mcs:set(m, E8, true)
 | 
				
			||||||
			print(combination)
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
		hm += 1
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	archetypes[combination] = true
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
print("TEST", hm)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local count = 0
 | 
					local count = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,7 +80,11 @@ for _, archetype in ecs:query(D2, D4, D6, D8):archetypes() do
 | 
				
			||||||
	count += #archetype.entities
 | 
						count += #archetype.entities
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print(count)
 | 
					
 | 
				
			||||||
 | 
					local mq = mcs:query(E2, E4, E6, E8):cached()
 | 
				
			||||||
 | 
					local jq = ecs:query(D2, D4, D6, D8):cached()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print(count, #jq:archetypes())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return {
 | 
					return {
 | 
				
			||||||
	ParameterGenerator = function()
 | 
						ParameterGenerator = function()
 | 
				
			||||||
| 
						 | 
					@ -157,12 +103,12 @@ return {
 | 
				
			||||||
		-- end,
 | 
							-- end,
 | 
				
			||||||
		--
 | 
							--
 | 
				
			||||||
		Mirror = function()
 | 
							Mirror = function()
 | 
				
			||||||
			for entityId, firstComponent in mcs:query(E2, E4, E6, E8) do
 | 
								for entityId, firstComponent in mq do
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end,
 | 
							end,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Jecs = function()
 | 
							Jecs = function()
 | 
				
			||||||
			for entityId, firstComponent in ecs:query(D2, D4, D6, D8) do
 | 
								for entityId, firstComponent in jq do
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end,
 | 
							end,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										52
									
								
								jecs.luau
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								jecs.luau
									
									
									
									
									
								
							| 
						 | 
					@ -216,7 +216,8 @@ export type World = {
 | 
				
			||||||
	children: <T>(self: World, id: Id<T>) -> () -> Entity,
 | 
						children: <T>(self: World, id: Id<T>) -> () -> Entity,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	--- Searches the world for entities that match a given query
 | 
						--- Searches the world for entities that match a given query
 | 
				
			||||||
	query: (<A>(World, Id<A>) -> Query<A>)
 | 
						query: ((World) -> Query<nil>)
 | 
				
			||||||
 | 
							& (<A>(World, Id<A>) -> Query<A>)
 | 
				
			||||||
		& (<A, B>(World, Id<A>, Id<B>) -> Query<A, B>)
 | 
							& (<A, B>(World, Id<A>, Id<B>) -> Query<A, B>)
 | 
				
			||||||
		& (<A, B, C>(World, Id<A>, Id<B>, Id<C>) -> Query<A, B, C>)
 | 
							& (<A, B, C>(World, Id<A>, Id<B>, Id<C>) -> Query<A, B, C>)
 | 
				
			||||||
		& (<A, B, C, D>(World, Id<A>, Id<B>, Id<C>, Id<D>) -> Query<A, B, C, D>)
 | 
							& (<A, B, C, D>(World, Id<A>, Id<B>, Id<C>, Id<D>) -> Query<A, B, C, D>)
 | 
				
			||||||
| 
						 | 
					@ -1253,7 +1254,29 @@ local function query_iter_init(query: QueryInner): () -> (number, ...any)
 | 
				
			||||||
	local a: Column, b: Column, c: Column, d: Column
 | 
						local a: Column, b: Column, c: Column, d: Column
 | 
				
			||||||
	local e: Column, f: Column, g: Column, h: Column
 | 
						local e: Column, f: Column, g: Column, h: Column
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if not B then
 | 
						if not A then
 | 
				
			||||||
 | 
							function world_query_iter_next(): any
 | 
				
			||||||
 | 
								local entity = entities[i]
 | 
				
			||||||
 | 
								while entity == nil do
 | 
				
			||||||
 | 
									lastArchetype += 1
 | 
				
			||||||
 | 
									archetype = compatible_archetypes[lastArchetype]
 | 
				
			||||||
 | 
									if not archetype then
 | 
				
			||||||
 | 
										return nil
 | 
				
			||||||
 | 
									end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									entities = archetype.entities
 | 
				
			||||||
 | 
									i = #entities
 | 
				
			||||||
 | 
									if i == 0 then
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									end
 | 
				
			||||||
 | 
									entity = entities[i]
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
								i -= 1
 | 
				
			||||||
 | 
								return entity
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							query.next = world_query_iter_next
 | 
				
			||||||
 | 
							return world_query_iter_next
 | 
				
			||||||
 | 
						elseif not B then
 | 
				
			||||||
		a = columns_map[A]
 | 
							a = columns_map[A]
 | 
				
			||||||
	elseif not C then
 | 
						elseif not C then
 | 
				
			||||||
		a = columns_map[A]
 | 
							a = columns_map[A]
 | 
				
			||||||
| 
						 | 
					@ -1650,7 +1673,8 @@ local function query_cached(query: QueryInner)
 | 
				
			||||||
		entities = archetype.entities
 | 
							entities = archetype.entities
 | 
				
			||||||
		i = #entities
 | 
							i = #entities
 | 
				
			||||||
		columns_map = archetype.columns_map
 | 
							columns_map = archetype.columns_map
 | 
				
			||||||
		if not B then
 | 
							if not A then
 | 
				
			||||||
 | 
							elseif not B then
 | 
				
			||||||
			a = columns_map[A]
 | 
								a = columns_map[A]
 | 
				
			||||||
		elseif not C then
 | 
							elseif not C then
 | 
				
			||||||
			a = columns_map[A]
 | 
								a = columns_map[A]
 | 
				
			||||||
| 
						 | 
					@ -1699,7 +1723,27 @@ local function query_cached(query: QueryInner)
 | 
				
			||||||
		return world_query_iter_next
 | 
							return world_query_iter_next
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if not B then
 | 
						if not A then
 | 
				
			||||||
 | 
							function world_query_iter_next(): any
 | 
				
			||||||
 | 
								local entity = entities[i]
 | 
				
			||||||
 | 
								while entity == nil do
 | 
				
			||||||
 | 
									lastArchetype += 1
 | 
				
			||||||
 | 
									archetype = compatible_archetypes[lastArchetype]
 | 
				
			||||||
 | 
									if not archetype then
 | 
				
			||||||
 | 
										return nil
 | 
				
			||||||
 | 
									end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									entities = archetype.entities
 | 
				
			||||||
 | 
									i = #entities
 | 
				
			||||||
 | 
									if i == 0 then
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									end
 | 
				
			||||||
 | 
									entity = entities[i]
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
								i -= 1
 | 
				
			||||||
 | 
								return entity
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						elseif not B then
 | 
				
			||||||
		function world_query_iter_next(): any
 | 
							function world_query_iter_next(): any
 | 
				
			||||||
			local entity = entities[i]
 | 
								local entity = entities[i]
 | 
				
			||||||
			while entity == nil do
 | 
								while entity == nil do
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	"name": "@rbxts/jecs",
 | 
						"name": "@rbxts/jecs",
 | 
				
			||||||
	"version": "0.9.0-rc.12",
 | 
						"version": "0.9.0",
 | 
				
			||||||
	"description": "Stupidly fast Entity Component System",
 | 
						"description": "Stupidly fast Entity Component System",
 | 
				
			||||||
	"main": "jecs.luau",
 | 
						"main": "jecs.luau",
 | 
				
			||||||
	"repository": {
 | 
						"repository": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -837,6 +837,9 @@ TEST("world:delete()", function()
 | 
				
			||||||
		CHECK(destroyed)
 | 
							CHECK(destroyed)
 | 
				
			||||||
		CHECK(not world:contains(child))
 | 
							CHECK(not world:contains(child))
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
						if true then
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do CASE "Should delete children in different archetypes if they have the same parent"
 | 
						do CASE "Should delete children in different archetypes if they have the same parent"
 | 
				
			||||||
		local world = jecs.world()
 | 
							local world = jecs.world()
 | 
				
			||||||
| 
						 | 
					@ -1706,6 +1709,36 @@ end)
 | 
				
			||||||
TEST("world:query()", function()
 | 
					TEST("world:query()", function()
 | 
				
			||||||
	local N = 2^8
 | 
						local N = 2^8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do CASE "queries should accept zero-ids provided they use :with for the leading component"
 | 
				
			||||||
 | 
							local world = jecs.world()
 | 
				
			||||||
 | 
							local A = world:component()
 | 
				
			||||||
 | 
							local B = world:component()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							local e1 = world:entity()
 | 
				
			||||||
 | 
							world:set(e1, A, "A")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							local e2 = world:entity()
 | 
				
			||||||
 | 
							world:set(e2, A, "A")
 | 
				
			||||||
 | 
							world:set(e2, B, "B")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for e, a in world:query():with(A) do
 | 
				
			||||||
 | 
								CHECK(e == e1 or e == e2)
 | 
				
			||||||
 | 
								CHECK(a == nil)
 | 
				
			||||||
 | 
								if e == e1 then
 | 
				
			||||||
 | 
									CHECK(world:has(e1, A))
 | 
				
			||||||
 | 
									CHECK(not world:has(e1, B))
 | 
				
			||||||
 | 
								elseif e == e2 then
 | 
				
			||||||
 | 
									CHECK(world:has(e2, A, B))
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							for e, a in world:query():with(A):without(B) do
 | 
				
			||||||
 | 
								CHECK(e == e1)
 | 
				
			||||||
 | 
								CHECK(a == nil)
 | 
				
			||||||
 | 
								CHECK(world:has(e1, A))
 | 
				
			||||||
 | 
								CHECK(not world:has(e1, B))
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do CASE "cached"
 | 
						do CASE "cached"
 | 
				
			||||||
		local world = jecs.world()
 | 
							local world = jecs.world()
 | 
				
			||||||
		local Foo = world:component()
 | 
							local Foo = world:component()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "ukendio/jecs"
 | 
					name = "ukendio/jecs"
 | 
				
			||||||
version = "0.9.0-rc.12"
 | 
					version = "0.9.0"
 | 
				
			||||||
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