mirror of
				https://github.com/Ukendio/jecs.git
				synced 2025-11-03 18:39:19 +00:00 
			
		
		
		
	Optimized observers
This commit is contained in:
		
							parent
							
								
									23540e5919
								
							
						
					
					
						commit
						cf94a48a40
					
				
					 1 changed files with 50 additions and 27 deletions
				
			
		| 
						 | 
					@ -1,9 +1,10 @@
 | 
				
			||||||
 | 
					--!strict
 | 
				
			||||||
local jecs = require("@jecs")
 | 
					local jecs = require("@jecs")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type PatchedWorld = jecs.World & {
 | 
					export type PatchedWorld = jecs.World & {
 | 
				
			||||||
	added: <T>(PatchedWorld, jecs.Id<T>, (e: jecs.Entity, id: jecs.Id, value: T) -> ()) -> () -> (),
 | 
						added: <T>(PatchedWorld, jecs.Id<T>, <e>(e: jecs.Entity<e>, id: jecs.Id<T>, value: T?) -> ()) -> () -> (),
 | 
				
			||||||
	removed: <T>(PatchedWorld, jecs.Id<T>, (e: jecs.Entity, id: jecs.Id) -> ()) -> () -> (),
 | 
						removed: <T>(PatchedWorld, jecs.Id<T>, (e: jecs.Entity, id: jecs.Id) -> ()) -> () -> (),
 | 
				
			||||||
	changed: <T>(PatchedWorld, jecs.Id<T>, (e: jecs.Entity, id: jecs.Id, value: T) -> ()) -> () -> (),
 | 
						changed:  <T>(PatchedWorld, jecs.Id<T>, <e>(e: jecs.Entity<e>, id: jecs.Id<T>, value: T) -> ()) -> () -> (),
 | 
				
			||||||
	observer: <T...>(
 | 
						observer: <T...>(
 | 
				
			||||||
		PatchedWorld,
 | 
							PatchedWorld,
 | 
				
			||||||
		jecs.Query<T...>,
 | 
							jecs.Query<T...>,
 | 
				
			||||||
| 
						 | 
					@ -16,28 +17,41 @@ export type PatchedWorld = jecs.World & {
 | 
				
			||||||
	) -> ()
 | 
						) -> ()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function observers_new(world, query, callback)
 | 
					local function observers_new(
 | 
				
			||||||
	local terms = query.filter_with :: { jecs.Id }
 | 
						world: PatchedWorld,
 | 
				
			||||||
	if not terms then
 | 
						query: any,
 | 
				
			||||||
		local ids = query.ids
 | 
						callback: (<T, a>(jecs.Entity<T>, jecs.Id<a>, value: a?) -> ())?
 | 
				
			||||||
		query.filter_with = ids
 | 
					)
 | 
				
			||||||
		terms = ids
 | 
						query = query:cached()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local archetypes = {}
 | 
				
			||||||
 | 
						local terms = query.ids
 | 
				
			||||||
 | 
						local first = terms[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local observers_on_create = world.observable[jecs.ArchetypeCreate][first]
 | 
				
			||||||
 | 
						observers_on_create[#observers_on_create].callback = function(archetype)
 | 
				
			||||||
 | 
							archetypes[archetype.id] = true
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						local observers_on_delete = world.observable[jecs.ArchetypeDelete][first]
 | 
				
			||||||
 | 
						observers_on_delete[#observers_on_delete].callback = function(archetype)
 | 
				
			||||||
 | 
							archetypes[archetype.id] = nil
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local entity_index = world.entity_index :: any
 | 
						local entity_index = world.entity_index :: any
 | 
				
			||||||
	local i = 0
 | 
						local i = 0
 | 
				
			||||||
	local entities = {}
 | 
						local entities = {}
 | 
				
			||||||
	local function emplaced(entity, id, value)
 | 
					 | 
				
			||||||
		local r = jecs.entity_index_try_get_fast(
 | 
					 | 
				
			||||||
			entity_index, entity :: any)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if not r then
 | 
						local function emplaced<T, a>(
 | 
				
			||||||
			return
 | 
							entity: jecs.Entity<T>,
 | 
				
			||||||
		end
 | 
							id: jecs.Id<a>,
 | 
				
			||||||
 | 
							value: a?
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
							local r = jecs.entity_index_try_get_fast(
 | 
				
			||||||
 | 
								entity_index, entity :: any) :: jecs.Record
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		local archetype = r.archetype
 | 
							local archetype = r.archetype
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if jecs.query_match(query, archetype) then
 | 
							if archetypes[archetype.id] then
 | 
				
			||||||
			i += 1
 | 
								i += 1
 | 
				
			||||||
			entities[i] = entity
 | 
								entities[i] = entity
 | 
				
			||||||
			if callback ~= nil then
 | 
								if callback ~= nil then
 | 
				
			||||||
| 
						 | 
					@ -110,27 +124,36 @@ local function join(world, component)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function monitors_new(world, query, callback)
 | 
					local function monitors_new(world, query, callback)
 | 
				
			||||||
	local terms = query.filter_with :: { jecs.Id }
 | 
						query = query:cached()
 | 
				
			||||||
	if not terms then
 | 
					
 | 
				
			||||||
		local ids = query.ids
 | 
						local archetypes = {}
 | 
				
			||||||
		query.filter_with = ids
 | 
						local terms = query.ids
 | 
				
			||||||
		terms = ids
 | 
						local first = terms[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local observers_on_create = world.observable[jecs.ArchetypeCreate][first]
 | 
				
			||||||
 | 
						observers_on_create[#observers_on_create].callback = function(archetype)
 | 
				
			||||||
 | 
							archetypes[archetype.id] = true
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						local observers_on_delete = world.observable[jecs.ArchetypeDelete][first]
 | 
				
			||||||
 | 
						observers_on_delete[#observers_on_delete].callback = function(archetype)
 | 
				
			||||||
 | 
							archetypes[archetype.id] = nil
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local entity_index = world.entity_index :: any
 | 
						local entity_index = world.entity_index :: any
 | 
				
			||||||
	local i = 0
 | 
						local i = 0
 | 
				
			||||||
	local entities = {}
 | 
						local entities = {}
 | 
				
			||||||
	local function emplaced(entity, id, value)
 | 
					 | 
				
			||||||
		local r = jecs.entity_index_try_get_fast(
 | 
					 | 
				
			||||||
			entity_index, entity :: any)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if not r then
 | 
						local function emplaced<T, a>(
 | 
				
			||||||
			return
 | 
							entity: jecs.Entity<T>,
 | 
				
			||||||
		end
 | 
							id: jecs.Id<a>,
 | 
				
			||||||
 | 
							value: a?
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
							local r = jecs.entity_index_try_get_fast(
 | 
				
			||||||
 | 
								entity_index, entity :: any) :: jecs.Record
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		local archetype = r.archetype
 | 
							local archetype = r.archetype
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if jecs.query_match(query, archetype) then
 | 
							if archetypes[archetype.id] then
 | 
				
			||||||
			i += 1
 | 
								i += 1
 | 
				
			||||||
			entities[i] = entity
 | 
								entities[i] = entity
 | 
				
			||||||
			if callback ~= nil then
 | 
								if callback ~= nil then
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue