mirror of
https://github.com/Ukendio/jecs.git
synced 2025-07-08 23:59:17 +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