mirror of
				https://github.com/Ukendio/jecs.git
				synced 2025-11-04 10:59:18 +00:00 
			
		
		
		
	Compare commits
	
		
			4 commits
		
	
	
		
			5e6b030fb4
			...
			6bb36f281e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							 | 
						6bb36f281e | ||
| 
							 | 
						74ef525092 | ||
| 
							 | 
						df6c568c6b | ||
| 
							 | 
						d24ab71e4c | 
					 5 changed files with 116 additions and 10 deletions
				
			
		| 
						 | 
					@ -16,6 +16,10 @@ local function observers_new(world, description)
 | 
				
			||||||
		local r = jecs.entity_index_try_get_fast(
 | 
							local r = jecs.entity_index_try_get_fast(
 | 
				
			||||||
			entity_index, entity)
 | 
								entity_index, entity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if not r then
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		local archetype = r.archetype
 | 
							local archetype = r.archetype
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if jecs.query_match(query, archetype) then
 | 
							if jecs.query_match(query, archetype) then
 | 
				
			||||||
| 
						 | 
					@ -42,9 +46,13 @@ local function world_track(world, ...)
 | 
				
			||||||
		local r = jecs.entity_index_try_get_fast(
 | 
							local r = jecs.entity_index_try_get_fast(
 | 
				
			||||||
			entity_index, entity)
 | 
								entity_index, entity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if not r then
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		local archetype = r.archetype
 | 
							local archetype = r.archetype
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if jecs.query_match(q_shim, archetype) then
 | 
							if jecs.query_match(q_shim :: any, archetype) then
 | 
				
			||||||
			n += 1
 | 
								n += 1
 | 
				
			||||||
			dense_array[n] = entity
 | 
								dense_array[n] = entity
 | 
				
			||||||
			sparse_array[entity] = n
 | 
								sparse_array[entity] = n
 | 
				
			||||||
| 
						 | 
					@ -73,7 +81,7 @@ local function world_track(world, ...)
 | 
				
			||||||
				return nil
 | 
									return nil
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
			i -= 1
 | 
								i -= 1
 | 
				
			||||||
			return dense_array[row]
 | 
								return dense_array[row] :: any
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								jecs.luau
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								jecs.luau
									
									
									
									
									
								
							| 
						 | 
					@ -124,9 +124,9 @@ local EcsOnArchetypeCreate =        HI_COMPONENT_ID + 12
 | 
				
			||||||
local EcsOnArchetypeDelete =        HI_COMPONENT_ID + 13
 | 
					local EcsOnArchetypeDelete =        HI_COMPONENT_ID + 13
 | 
				
			||||||
local EcsRest =                     HI_COMPONENT_ID + 14
 | 
					local EcsRest =                     HI_COMPONENT_ID + 14
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local ECS_ID_DELETE =                        		0b01
 | 
					local ECS_ID_DELETE =                        	    0b01
 | 
				
			||||||
local ECS_ID_IS_TAG =                        		0b10
 | 
					local ECS_ID_IS_TAG =                        	    0b10
 | 
				
			||||||
local ECS_ID_MASK =                          		0b00
 | 
					local ECS_ID_MASK =                          	    0b00
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local ECS_ENTITY_MASK =              bit32.lshift(1, 24)
 | 
					local ECS_ENTITY_MASK =              bit32.lshift(1, 24)
 | 
				
			||||||
local ECS_GENERATION_MASK =          bit32.lshift(1, 16)
 | 
					local ECS_GENERATION_MASK =          bit32.lshift(1, 16)
 | 
				
			||||||
| 
						 | 
					@ -733,13 +733,14 @@ local function find_archetype_with(world: ecs_world_t, node: ecs_archetype_t, id
 | 
				
			||||||
	-- them each time would be expensive. Instead this insertion sort can find the insertion
 | 
						-- them each time would be expensive. Instead this insertion sort can find the insertion
 | 
				
			||||||
	-- point in the types array.
 | 
						-- point in the types array.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local dst = table.clone(node.types) :: { i53 }
 | 
					 | 
				
			||||||
	local at = find_insert(id_types, id)
 | 
						local at = find_insert(id_types, id)
 | 
				
			||||||
	if at == -1 then
 | 
						if at == -1 then
 | 
				
			||||||
		-- If it finds a duplicate, it just means it is the same archetype so it can return it
 | 
							-- If it finds a duplicate, it just means it is the same archetype so it can return it
 | 
				
			||||||
		-- directly instead of needing to hash types for a lookup to the archetype.
 | 
							-- directly instead of needing to hash types for a lookup to the archetype.
 | 
				
			||||||
		return node
 | 
							return node
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local dst = table.clone(node.types) :: { i53 }
 | 
				
			||||||
	table.insert(dst, at, id)
 | 
						table.insert(dst, at, id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return archetype_ensure(world, dst)
 | 
						return archetype_ensure(world, dst)
 | 
				
			||||||
| 
						 | 
					@ -2600,7 +2601,7 @@ export type World = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return {
 | 
					return {
 | 
				
			||||||
	World = World :: { new: () -> World },
 | 
						World = World :: { new: () -> World },
 | 
				
			||||||
	world = World.new :: () -> World,
 | 
						world = world_new :: () -> World,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	OnAdd = EcsOnAdd :: Entity<(entity: Entity) -> ()>,
 | 
						OnAdd = EcsOnAdd :: Entity<(entity: Entity) -> ()>,
 | 
				
			||||||
	OnRemove = EcsOnRemove :: Entity<(entity: Entity) -> ()>,
 | 
						OnRemove = EcsOnRemove :: Entity<(entity: Entity) -> ()>,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| 
						 | 
					@ -1,12 +1,12 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	"name": "@rbxts/jecs",
 | 
						"name": "@rbxts/jecs",
 | 
				
			||||||
	"version": "0.5.5",
 | 
						"version": "0.6.0-rc.1",
 | 
				
			||||||
	"lockfileVersion": 3,
 | 
						"lockfileVersion": 3,
 | 
				
			||||||
	"requires": true,
 | 
						"requires": true,
 | 
				
			||||||
	"packages": {
 | 
						"packages": {
 | 
				
			||||||
		"": {
 | 
							"": {
 | 
				
			||||||
			"name": "@rbxts/jecs",
 | 
								"name": "@rbxts/jecs",
 | 
				
			||||||
			"version": "0.5.5",
 | 
								"version": "0.6.0-rc.1",
 | 
				
			||||||
			"license": "MIT",
 | 
								"license": "MIT",
 | 
				
			||||||
			"devDependencies": {
 | 
								"devDependencies": {
 | 
				
			||||||
				"@rbxts/compiler-types": "^2.3.0-types.1",
 | 
									"@rbxts/compiler-types": "^2.3.0-types.1",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	"name": "@rbxts/jecs",
 | 
						"name": "@rbxts/jecs",
 | 
				
			||||||
	"version": "0.5.5",
 | 
						"version": "0.6.0-rc.1",
 | 
				
			||||||
	"description": "Stupidly fast Entity Component System",
 | 
						"description": "Stupidly fast Entity Component System",
 | 
				
			||||||
	"main": "jecs.luau",
 | 
						"main": "jecs.luau",
 | 
				
			||||||
	"repository": {
 | 
						"repository": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,6 +117,103 @@ local function name(world, e)
 | 
				
			||||||
	return world:get(e, jecs.Name)
 | 
						return world:get(e, jecs.Name)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function worldReset(world)
 | 
				
			||||||
 | 
						local entity_index = world.entity_index
 | 
				
			||||||
 | 
						for i = jecs.Rest, entity_index.max_id do
 | 
				
			||||||
 | 
							local entity = entity_index.dense_array[i]
 | 
				
			||||||
 | 
							world:delete(entity)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						for i = jecs.Rest, entity_index.max_id do
 | 
				
			||||||
 | 
							local sparse = entity_index.dense_array[i]
 | 
				
			||||||
 | 
							entity_index.sparse_array[sparse] = nil
 | 
				
			||||||
 | 
							entity_index.dense_array[i] = nil
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						entity_index.alive_count = jecs.Rest
 | 
				
			||||||
 | 
						entity_index.max_id = jecs.Rest
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local lifetime_tracker_add = require("@tools/lifetime_tracker")
 | 
				
			||||||
 | 
					TEST("the great reset", function()
 | 
				
			||||||
 | 
						local world = world_new()
 | 
				
			||||||
 | 
						lifetime_tracker_add(world, {padding_enabled=false})
 | 
				
			||||||
 | 
						local A = world:component()
 | 
				
			||||||
 | 
						local B = world:component()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i = 1, 10 do
 | 
				
			||||||
 | 
							local e = world:entity()
 | 
				
			||||||
 | 
							world:set(e, A, true)
 | 
				
			||||||
 | 
							world:set(e, B, true)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						world:print_entity_index()
 | 
				
			||||||
 | 
						worldReset(world)
 | 
				
			||||||
 | 
						CHECK(world:contains(A))
 | 
				
			||||||
 | 
						CHECK(world:contains(B))
 | 
				
			||||||
 | 
						world:print_entity_index()
 | 
				
			||||||
 | 
					end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST("#repro3", function()
 | 
				
			||||||
 | 
						local world = world_new()
 | 
				
			||||||
 | 
						local Model = world:component()
 | 
				
			||||||
 | 
						local ModelBase = world:component()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local systems = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local function progress()
 | 
				
			||||||
 | 
							for _, system in systems do
 | 
				
			||||||
 | 
								system()
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local newQuery = nil
 | 
				
			||||||
 | 
						local oldQuery = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local function modelBase()
 | 
				
			||||||
 | 
							if not newQuery then
 | 
				
			||||||
 | 
								newQuery = world:query(Model):without(ModelBase):cached()
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							if not oldQuery then
 | 
				
			||||||
 | 
								oldQuery = world:query(ModelBase):without(Model):cached()
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							for e, model in newQuery do
 | 
				
			||||||
 | 
								world:set(e, ModelBase, { "part base" })
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							for e, model in oldQuery do
 | 
				
			||||||
 | 
								world:remove(e, ModelBase)
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						table.insert(systems, modelBase)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do CASE("should add the correct ModelBase for parts")
 | 
				
			||||||
 | 
							local e = world:entity()
 | 
				
			||||||
 | 
							world:set(e, Model, { instance = "Model" })
 | 
				
			||||||
 | 
							progress()
 | 
				
			||||||
 | 
							CHECK(world:get(e, ModelBase)[1] == "part base" )
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do CASE("should add the correct ModelBase for parts")
 | 
				
			||||||
 | 
							local e = world:entity()
 | 
				
			||||||
 | 
							world:set(e, Model, { instance = "Model "})
 | 
				
			||||||
 | 
							progress()
 | 
				
			||||||
 | 
							CHECK(world:get(e, ModelBase)[1] == "part base")
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do CASE("")
 | 
				
			||||||
 | 
							local e = world:entity()
 | 
				
			||||||
 | 
							world:set(e, Model, { instance = "Model "})
 | 
				
			||||||
 | 
							progress()
 | 
				
			||||||
 | 
							CHECK(world:get(e, ModelBase)[1] == "part base")
 | 
				
			||||||
 | 
							world:remove(e, Model)
 | 
				
			||||||
 | 
							progress()
 | 
				
			||||||
 | 
							CHECK(world:get(e, ModelBase) == nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST("#adding a recycled target", function()
 | 
					TEST("#adding a recycled target", function()
 | 
				
			||||||
    local world = world_new()
 | 
					    local world = world_new()
 | 
				
			||||||
    local R = world:component()
 | 
					    local R = world:component()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue