1
0
Fork 0
mirror of https://github.com/Reuh/ubiquitousse.git synced 2025-10-27 17:19:31 +00:00

ecs: add callbackFiltered and emitFiltered

This commit is contained in:
Étienne Fildadut 2022-10-13 00:24:47 +09:00
parent bd28610ff4
commit aa332a0adf
20 changed files with 697 additions and 568 deletions

View file

@ -144,6 +144,10 @@ let copy = (a, b, cache={})
end
end
--- Self descriptive
let alwaysTrue = () return true end
let alwaysFalse = () return false end
--- Skip list implementation ---
-- Well technically it's a conbination of a skip list (for ordering) and a hash map (for that sweet O(1) search). Takes more memory but oh so efficient.
@ -759,14 +763,30 @@ let system_mt = {
-- @tparam Entity e the entity to perform the callback on
-- @param ... other arguments to pass to the callback
callback = :(name, e, ...)
-- call callback
if @_has[e] and @[name] then
@[name](@, e, e[@component], ...)
end
-- callback on subsystems (if it wasn't removed during the callback)
if @_has[e] then
for _, ss in ipairs(@systems) do
ss:callback(name, e, ...)
return @callbackFiltered(alwaysTrue, name, e, ...)
end,
--- Same as `callback`, but will check every system against a filter before calling the callback.
--
-- `filter` is a function that receive the arguments `filter(system, name, e, ...)`, and returns a boolean.
-- It will be called on each system before emitting the callback on it; if the filter returns false, the callback will not
-- be called on this system and its subsystems.
--
-- Complexity: O(1) per system
-- @tparam function filter filter function
-- @tparam string name name of the callback
-- @tparam Entity e the entity to perform the callback on
-- @param ... other arguments to pass to the callback
callbackFiltered = :(filter, name, e, ...)
if filter(@, name, e, ...) then
-- call callback
if @_has[e] and @[name] then
@[name](@, e, e[@component], ...)
end
-- callback on subsystems (if it wasn't removed during the callback)
if @_has[e] then
for _, ss in ipairs(@systems) do
ss:callbackFiltered(filter, name, e, ...)
end
end
end
end,
@ -793,19 +813,34 @@ let system_mt = {
-- @tparam string name name of the callback
-- @param ... other arguments to pass to the callback
emit = :(name, ...)
-- call event
let status
if @[name] then
status = @[name](@, ...)
end
-- call event on subsystems (if it wasn't stopped or captured)
if status ~= "stop" and status ~= "capture" then
for _, s in ipairs(@systems) do
status = s:emit(name, ...)
if status == "capture" then break end
return @emitFiltered(alwaysTrue, name, ...)
end,
--- Same as `emit`, but will check every system against a filter before calling the event.
--
-- `filter` is a function that receive the arguments `filter(system, name, ...)`, and returns a boolean.
-- It will be called on each system before emitting the event on it; if the filter returns false, the event will not
-- be emitted to this system and its subsystems.
--
-- Complexity: O(1) per system
-- @tparam function filter filter function
-- @tparam string name name of the callback
-- @param ... other arguments to pass to the callback
emitFiltered = :(filter, name, ...)
if filter(@, name, ...) then
-- call event
let status
if @[name] then
status = @[name](@, ...)
end
-- call event on subsystems (if it wasn't stopped or captured)
if status ~= "stop" and status ~= "capture" then
for _, s in ipairs(@systems) do
status = s:emitFiltered(filter, name, ...)
if status == "capture" then break end
end
end
return status
end
return status
end,
--- Remove all the entities and subsystems in this system.
-- Complexity: O(entityCount) per system
@ -815,10 +850,6 @@ let system_mt = {
end,
}
--- Self descriptive
let alwaysTrue = () return true end
let alwaysFalse = () return false end
--- Recursively instanciate a list of systems for a world:
-- * create their self table with instance fields set
-- * create a field with their name in world.s (if name defined)