From aa332a0adf4f4b19dd5fc7a3fcbe7df02d240f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Thu, 13 Oct 2022 00:24:47 +0900 Subject: [PATCH 1/4] ecs: add callbackFiltered and emitFiltered --- docs/index.html | 2 +- docs/modules/asset.html | 2 +- docs/modules/ecs.html | 90 ++- docs/modules/input.html | 2 +- docs/modules/ldtk.html | 6 +- docs/modules/scene.html | 2 +- docs/modules/signal.html | 2 +- docs/modules/timer.html | 2 +- docs/modules/ubiquitousse.html | 2 +- docs/modules/util.html | 2 +- docs/topics/LICENSE.html | 2 +- docs/topics/README.md.html | 2 +- ecs/children.lua | 33 - ecs/{ => commonsystems}/children.can | 0 ecs/commonsystems/children.lua | 33 + ecs/{ => commonsystems}/timer.can | 2 +- ecs/commonsystems/timer.lua | 23 + ecs/ecs.can | 77 ++- ecs/ecs.lua | 958 ++++++++++++++------------- ecs/timer.lua | 23 - 20 files changed, 697 insertions(+), 568 deletions(-) delete mode 100644 ecs/children.lua rename ecs/{ => commonsystems}/children.can (100%) create mode 100644 ecs/commonsystems/children.lua rename ecs/{ => commonsystems}/timer.can (96%) create mode 100644 ecs/commonsystems/timer.lua delete mode 100644 ecs/timer.lua diff --git a/docs/index.html b/docs/index.html index fd17121..5216dce 100644 --- a/docs/index.html +++ b/docs/index.html @@ -113,7 +113,7 @@
generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
diff --git a/docs/modules/asset.html b/docs/modules/asset.html index a939867..c3222a1 100644 --- a/docs/modules/asset.html +++ b/docs/modules/asset.html @@ -337,7 +337,7 @@
generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
diff --git a/docs/modules/ecs.html b/docs/modules/ecs.html index 6196154..9fb1371 100644 --- a/docs/modules/ecs.html +++ b/docs/modules/ecs.html @@ -323,10 +323,18 @@ end Trigger a custom callback on a single entity. + System:callbackFiltered (filter, name, e, ...) + Same as callback, but will check every system against a filter before calling the callback. + + System:emit (name, ...) Emit an event on the system. + System:emitFiltered (filter, name, ...) + Same as emit, but will check every system against a filter before calling the event. + + System:destroy () Remove all the entities and subsystems in this system. @@ -1799,6 +1807,48 @@ avoid repeating your filters or allow controlling several system from a single p + +
+ + System:callbackFiltered (filter, name, e, ...) +
+
+ 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 + + + + + + +

Parameters:

+ + + + + +
@@ -1849,6 +1899,44 @@ its sibling systems (i.e. completely stop the propagation of the event). + +
+ + System:emitFiltered (filter, name, ...) +
+
+ 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 + + + + + + +

Parameters:

+ + + + + +
@@ -1876,7 +1964,7 @@ its sibling systems (i.e. completely stop the propagation of the event).
generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
diff --git a/docs/modules/input.html b/docs/modules/input.html index 42552b9..13173b4 100644 --- a/docs/modules/input.html +++ b/docs/modules/input.html @@ -1723,7 +1723,7 @@ player.fire.event:bind("pressed",
generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
diff --git a/docs/modules/ldtk.html b/docs/modules/ldtk.html index 4dc42bd..cfa6047 100644 --- a/docs/modules/ldtk.html +++ b/docs/modules/ldtk.html @@ -2066,7 +2066,7 @@ end Level background.

If there is a background image, background.image contains a table {image=image, x=number, y=number, sx=number, sy=number} - where image is the LÖVE image (or image filepath if LÖVE not available) x and y are the top-left position, + where image is the LÖVE image (or image filepath if LÖVE not available) x and y are the top-left position, and sx and sy the horizontal and vertical scale factors. @@ -2142,7 +2142,7 @@ end

  • Enum are converted into a Lua string giving the currently selected enum value.
  • Filepath are converted into a Lua string giving the file path.
  • Arrays are converted into a Lua table with the elements in it as a list.
  • -
  • Points are converted into a Lua table with the fields x and y, in pixels: { x=number, y=number }.
  • +
  • Points are converted into a Lua table with the fields x and y, in pixels: { x=number, y=number }.
  • Colors are converted into a Lua table with the red, green and blue components in [0-1] as a list: {r,g,b}.
  • Tiles are converted into a Lua table { tileset = associated tileset object, quad = associated quad } where quad is a LÖVE Quad if LÖVE is available, otherwise a table { x, y, width, height }.
  • EntityRef are converted into a Lua table { level = level, layerIid = layer IID, entityIid = entity IID, entity = see explanation }. If the entity being refernced belongs to another level and this level is not loaded, entity will be nil; otherwise (same level or the other level is also loaded), it will contain the entity.
  • @@ -2170,7 +2170,7 @@ end
    generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
    diff --git a/docs/modules/scene.html b/docs/modules/scene.html index 0b9bdf6..cf100b5 100644 --- a/docs/modules/scene.html +++ b/docs/modules/scene.html @@ -703,7 +703,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
    diff --git a/docs/modules/signal.html b/docs/modules/signal.html index 8b93b1c..de7aeb6 100644 --- a/docs/modules/signal.html +++ b/docs/modules/signal.html @@ -788,7 +788,7 @@ signal.event:bind("keypressed", function(key, scancode) print("pr
    generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
    diff --git a/docs/modules/timer.html b/docs/modules/timer.html index 9cf1428..7e71ada 100644 --- a/docs/modules/timer.html +++ b/docs/modules/timer.html @@ -1154,7 +1154,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
    diff --git a/docs/modules/ubiquitousse.html b/docs/modules/ubiquitousse.html index 5c59f85..ba1a602 100644 --- a/docs/modules/ubiquitousse.html +++ b/docs/modules/ubiquitousse.html @@ -394,7 +394,7 @@ the repository to save you a few seconds.

    generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
    diff --git a/docs/modules/util.html b/docs/modules/util.html index 67f3da4..a2bdff5 100644 --- a/docs/modules/util.html +++ b/docs/modules/util.html @@ -785,7 +785,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
    diff --git a/docs/topics/LICENSE.html b/docs/topics/LICENSE.html index 6188111..bbab437 100644 --- a/docs/topics/LICENSE.html +++ b/docs/topics/LICENSE.html @@ -65,7 +65,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
    diff --git a/docs/topics/README.md.html b/docs/topics/README.md.html index 1371bcf..3397497 100644 --- a/docs/topics/README.md.html +++ b/docs/topics/README.md.html @@ -87,7 +87,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-10-11 19:12:05 +Last updated 2022-10-13 00:23:58
    diff --git a/ecs/children.lua b/ecs/children.lua deleted file mode 100644 index c8b6d5b..0000000 --- a/ecs/children.lua +++ /dev/null @@ -1,33 +0,0 @@ -return { -- ./ecs/children.can:12 -["name"] = "children", -- ./ecs/children.can:13 -["filter"] = true, -- ./ecs/children.can:14 -["onAdd"] = function(self, e) -- ./ecs/children.can:15 -if not e["children"] then -- ./ecs/children.can:16 -e["children"] = {} -- ./ecs/children.can:16 -end -- ./ecs/children.can:16 -if e["parent"] then -- ./ecs/children.can:17 -local parentchildren -- ./ecs/children.can:18 -parentchildren = e["parent"]["children"] -- ./ecs/children.can:18 -table["insert"](parentchildren, e) -- ./ecs/children.can:19 -end -- ./ecs/children.can:19 -for _, o in ipairs(e["children"]) do -- ./ecs/children.can:21 -o["parent"] = e -- ./ecs/children.can:22 -self["world"]:add(o) -- ./ecs/children.can:23 -end -- ./ecs/children.can:23 -end, -- ./ecs/children.can:23 -["onRemove"] = function(self, e) -- ./ecs/children.can:26 -for i = # e["children"], 1, - 1 do -- ./ecs/children.can:27 -self["world"]:remove(e["children"][i]) -- ./ecs/children.can:28 -end -- ./ecs/children.can:28 -if e["parent"] then -- ./ecs/children.can:30 -local parentchildren -- ./ecs/children.can:31 -parentchildren = e["parent"]["children"] -- ./ecs/children.can:31 -for i = # parentchildren, 1, - 1 do -- ./ecs/children.can:32 -if parentchildren[i] == e then -- ./ecs/children.can:33 -table["remove"](parentchildren, i) -- ./ecs/children.can:34 -break -- ./ecs/children.can:35 -end -- ./ecs/children.can:35 -end -- ./ecs/children.can:35 -end -- ./ecs/children.can:35 -end -- ./ecs/children.can:35 -} -- ./ecs/children.can:35 diff --git a/ecs/children.can b/ecs/commonsystems/children.can similarity index 100% rename from ecs/children.can rename to ecs/commonsystems/children.can diff --git a/ecs/commonsystems/children.lua b/ecs/commonsystems/children.lua new file mode 100644 index 0000000..843806e --- /dev/null +++ b/ecs/commonsystems/children.lua @@ -0,0 +1,33 @@ +return { -- ./ecs/commonsystems/children.can:12 +["name"] = "children", -- ./ecs/commonsystems/children.can:13 +["filter"] = true, -- ./ecs/commonsystems/children.can:14 +["onAdd"] = function(self, e) -- ./ecs/commonsystems/children.can:15 +if not e["children"] then -- ./ecs/commonsystems/children.can:16 +e["children"] = {} -- ./ecs/commonsystems/children.can:16 +end -- ./ecs/commonsystems/children.can:16 +if e["parent"] then -- ./ecs/commonsystems/children.can:17 +local parentchildren -- ./ecs/commonsystems/children.can:18 +parentchildren = e["parent"]["children"] -- ./ecs/commonsystems/children.can:18 +table["insert"](parentchildren, e) -- ./ecs/commonsystems/children.can:19 +end -- ./ecs/commonsystems/children.can:19 +for _, o in ipairs(e["children"]) do -- ./ecs/commonsystems/children.can:21 +o["parent"] = e -- ./ecs/commonsystems/children.can:22 +self["world"]:add(o) -- ./ecs/commonsystems/children.can:23 +end -- ./ecs/commonsystems/children.can:23 +end, -- ./ecs/commonsystems/children.can:23 +["onRemove"] = function(self, e) -- ./ecs/commonsystems/children.can:26 +for i = # e["children"], 1, - 1 do -- ./ecs/commonsystems/children.can:27 +self["world"]:remove(e["children"][i]) -- ./ecs/commonsystems/children.can:28 +end -- ./ecs/commonsystems/children.can:28 +if e["parent"] then -- ./ecs/commonsystems/children.can:30 +local parentchildren -- ./ecs/commonsystems/children.can:31 +parentchildren = e["parent"]["children"] -- ./ecs/commonsystems/children.can:31 +for i = # parentchildren, 1, - 1 do -- ./ecs/commonsystems/children.can:32 +if parentchildren[i] == e then -- ./ecs/commonsystems/children.can:33 +table["remove"](parentchildren, i) -- ./ecs/commonsystems/children.can:34 +break -- ./ecs/commonsystems/children.can:35 +end -- ./ecs/commonsystems/children.can:35 +end -- ./ecs/commonsystems/children.can:35 +end -- ./ecs/commonsystems/children.can:35 +end -- ./ecs/commonsystems/children.can:35 +} -- ./ecs/commonsystems/children.can:35 diff --git a/ecs/timer.can b/ecs/commonsystems/timer.can similarity index 96% rename from ecs/timer.can rename to ecs/commonsystems/timer.can index 52405e8..ff51a9e 100644 --- a/ecs/timer.can +++ b/ecs/commonsystems/timer.can @@ -9,7 +9,7 @@ return { default = { -- timer object }, - process = :(t, dt) + process = :(e, t, dt) t:update(dt) if t:dead() then @world:remove(t.entity) diff --git a/ecs/commonsystems/timer.lua b/ecs/commonsystems/timer.lua new file mode 100644 index 0000000..299a20b --- /dev/null +++ b/ecs/commonsystems/timer.lua @@ -0,0 +1,23 @@ +local timer -- ./ecs/commonsystems/timer.can:4 +timer = require((...):match("^(.-)ecs%.timer") .. "scene") -- ./ecs/commonsystems/timer.can:4 +return { -- ./ecs/commonsystems/timer.can:6 +["name"] = "timer", -- ./ecs/commonsystems/timer.can:7 +["filter"] = "timer", -- ./ecs/commonsystems/timer.can:8 +["default"] = {}, -- ./ecs/commonsystems/timer.can:9 +["process"] = function(self, e, t, dt) -- ./ecs/commonsystems/timer.can:12 +t:update(dt) -- ./ecs/commonsystems/timer.can:13 +if t:dead() then -- ./ecs/commonsystems/timer.can:14 +self["world"]:remove(t["entity"]) -- ./ecs/commonsystems/timer.can:15 +end -- ./ecs/commonsystems/timer.can:15 +end, -- ./ecs/commonsystems/timer.can:15 +["run"] = function(self, func) -- ./ecs/commonsystems/timer.can:20 +local t = timer["run"](func) -- ./ecs/commonsystems/timer.can:21 +self["world"]:add({ ["timer"] = t }) -- ./ecs/commonsystems/timer.can:23 +return t -- ./ecs/commonsystems/timer.can:25 +end, -- ./ecs/commonsystems/timer.can:25 +["tween"] = function(self, duration, tbl, to, method) -- ./ecs/commonsystems/timer.can:28 +local t = timer["tween"](duration, tbl, to, method) -- ./ecs/commonsystems/timer.can:29 +self["world"]:add({ ["timer"] = t }) -- ./ecs/commonsystems/timer.can:31 +return t -- ./ecs/commonsystems/timer.can:33 +end -- ./ecs/commonsystems/timer.can:33 +} -- ./ecs/commonsystems/timer.can:33 diff --git a/ecs/ecs.can b/ecs/ecs.can index c61d5dd..d64ec67 100644 --- a/ecs/ecs.can +++ b/ecs/ecs.can @@ -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) diff --git a/ecs/ecs.lua b/ecs/ecs.lua index e558f77..bbf13b0 100644 --- a/ecs/ecs.lua +++ b/ecs/ecs.lua @@ -49,494 +49,504 @@ b[k] = v -- ./ecs/ecs.can:142 end -- ./ecs/ecs.can:142 end -- ./ecs/ecs.can:142 end -- ./ecs/ecs.can:142 -local head -- ./ecs/ecs.can:151 -head = {} -- ./ecs/ecs.can:151 -local skipNew -- ./ecs/ecs.can:154 -skipNew = function() -- ./ecs/ecs.can:154 -local s -- ./ecs/ecs.can:155 -s = { -- ./ecs/ecs.can:155 -["first"] = { -- ./ecs/ecs.can:158 -head, -- ./ecs/ecs.can:158 -nil -- ./ecs/ecs.can:158 -}, -- ./ecs/ecs.can:158 -["firstBase"] = nil, -- ./ecs/ecs.can:160 -["previous"] = { {} }, -- ./ecs/ecs.can:164 -["nLayers"] = 1, -- ./ecs/ecs.can:166 -["n"] = 0 -- ./ecs/ecs.can:168 -} -- ./ecs/ecs.can:168 -s["firstBase"] = s["first"] -- ./ecs/ecs.can:170 -return s -- ./ecs/ecs.can:171 -end -- ./ecs/ecs.can:171 -local nextEntity -- ./ecs/ecs.can:175 -nextEntity = function(s) -- ./ecs/ecs.can:175 -if s[1] then -- ./ecs/ecs.can:176 -local var -- ./ecs/ecs.can:177 -var = s[1][1] -- ./ecs/ecs.can:177 -s[1] = s[1][2] -- ./ecs/ecs.can:178 -return var -- ./ecs/ecs.can:179 -else -- ./ecs/ecs.can:179 -return nil -- ./ecs/ecs.can:181 -end -- ./ecs/ecs.can:181 -end -- ./ecs/ecs.can:181 -local skipIter -- ./ecs/ecs.can:186 -skipIter = function(self) -- ./ecs/ecs.can:186 -return nextEntity, { self["firstBase"][2] } -- ./ecs/ecs.can:187 -end -- ./ecs/ecs.can:187 -local skipAddLayers -- ./ecs/ecs.can:193 -skipAddLayers = function(self) -- ./ecs/ecs.can:193 -while self["n"] > 2 ^ self["nLayers"] do -- ./ecs/ecs.can:194 -self["first"] = { -- ./ecs/ecs.can:195 -head, -- ./ecs/ecs.can:195 -nil, -- ./ecs/ecs.can:195 -self["first"] -- ./ecs/ecs.can:195 -} -- ./ecs/ecs.can:195 -table["insert"](self["previous"], {}) -- ./ecs/ecs.can:196 -self["nLayers"] = self["nLayers"] + (1) -- ./ecs/ecs.can:197 -end -- ./ecs/ecs.can:197 -end -- ./ecs/ecs.can:197 -local coinFlip -- ./ecs/ecs.can:202 -coinFlip = function() -- ./ecs/ecs.can:202 -return math["random"](0, 1) == 1 -- ./ecs/ecs.can:203 -end -- ./ecs/ecs.can:203 -local skipInsert -- ./ecs/ecs.can:208 -skipInsert = function(self, system, e) -- ./ecs/ecs.can:208 -local prevLayer -- ./ecs/ecs.can:210 -prevLayer = {} -- ./ecs/ecs.can:210 -local prev -- ./ecs/ecs.can:211 -prev = self["first"] -- ./ecs/ecs.can:211 -for i = self["nLayers"], 1, - 1 do -- ./ecs/ecs.can:212 -while true do -- ./ecs/ecs.can:213 -if prev[2] == nil or system:compare(e, prev[2][1]) then -- ./ecs/ecs.can:215 -prevLayer[i] = prev -- ./ecs/ecs.can:216 -if prev[3] then -- ./ecs/ecs.can:218 -prev = prev[3] -- ./ecs/ecs.can:219 -break -- ./ecs/ecs.can:220 -end -- ./ecs/ecs.can:220 -break -- ./ecs/ecs.can:222 -else -- ./ecs/ecs.can:222 -prev = prev[2] -- ./ecs/ecs.can:225 -end -- ./ecs/ecs.can:225 -end -- ./ecs/ecs.can:225 -end -- ./ecs/ecs.can:225 -local inLowerLayer -- ./ecs/ecs.can:230 -for i = 1, self["nLayers"] do -- ./ecs/ecs.can:231 -prev = prevLayer[i] -- ./ecs/ecs.can:232 -if i == 1 or coinFlip() then -- ./ecs/ecs.can:233 -local nxt -- ./ecs/ecs.can:234 -nxt = prev[2] -- ./ecs/ecs.can:234 -prev[2] = { -- ./ecs/ecs.can:235 -e, -- ./ecs/ecs.can:235 -nxt, -- ./ecs/ecs.can:235 -inLowerLayer -- ./ecs/ecs.can:235 -} -- ./ecs/ecs.can:235 -self["previous"][i][e] = prev -- ./ecs/ecs.can:236 -if nxt then -- ./ecs/ecs.can:237 -self["previous"][i][nxt[1]] = prev[2] -- ./ecs/ecs.can:238 -end -- ./ecs/ecs.can:238 -inLowerLayer = prev[2] -- ./ecs/ecs.can:240 -else -- ./ecs/ecs.can:240 -break -- ./ecs/ecs.can:242 +local alwaysTrue -- ./ecs/ecs.can:148 +alwaysTrue = function() -- ./ecs/ecs.can:148 +return true -- ./ecs/ecs.can:148 +end -- ./ecs/ecs.can:148 +local alwaysFalse -- ./ecs/ecs.can:149 +alwaysFalse = function() -- ./ecs/ecs.can:149 +return false -- ./ecs/ecs.can:149 +end -- ./ecs/ecs.can:149 +local head -- ./ecs/ecs.can:155 +head = {} -- ./ecs/ecs.can:155 +local skipNew -- ./ecs/ecs.can:158 +skipNew = function() -- ./ecs/ecs.can:158 +local s -- ./ecs/ecs.can:159 +s = { -- ./ecs/ecs.can:159 +["first"] = { -- ./ecs/ecs.can:162 +head, -- ./ecs/ecs.can:162 +nil -- ./ecs/ecs.can:162 +}, -- ./ecs/ecs.can:162 +["firstBase"] = nil, -- ./ecs/ecs.can:164 +["previous"] = { {} }, -- ./ecs/ecs.can:168 +["nLayers"] = 1, -- ./ecs/ecs.can:170 +["n"] = 0 -- ./ecs/ecs.can:172 +} -- ./ecs/ecs.can:172 +s["firstBase"] = s["first"] -- ./ecs/ecs.can:174 +return s -- ./ecs/ecs.can:175 +end -- ./ecs/ecs.can:175 +local nextEntity -- ./ecs/ecs.can:179 +nextEntity = function(s) -- ./ecs/ecs.can:179 +if s[1] then -- ./ecs/ecs.can:180 +local var -- ./ecs/ecs.can:181 +var = s[1][1] -- ./ecs/ecs.can:181 +s[1] = s[1][2] -- ./ecs/ecs.can:182 +return var -- ./ecs/ecs.can:183 +else -- ./ecs/ecs.can:183 +return nil -- ./ecs/ecs.can:185 +end -- ./ecs/ecs.can:185 +end -- ./ecs/ecs.can:185 +local skipIter -- ./ecs/ecs.can:190 +skipIter = function(self) -- ./ecs/ecs.can:190 +return nextEntity, { self["firstBase"][2] } -- ./ecs/ecs.can:191 +end -- ./ecs/ecs.can:191 +local skipAddLayers -- ./ecs/ecs.can:197 +skipAddLayers = function(self) -- ./ecs/ecs.can:197 +while self["n"] > 2 ^ self["nLayers"] do -- ./ecs/ecs.can:198 +self["first"] = { -- ./ecs/ecs.can:199 +head, -- ./ecs/ecs.can:199 +nil, -- ./ecs/ecs.can:199 +self["first"] -- ./ecs/ecs.can:199 +} -- ./ecs/ecs.can:199 +table["insert"](self["previous"], {}) -- ./ecs/ecs.can:200 +self["nLayers"] = self["nLayers"] + (1) -- ./ecs/ecs.can:201 +end -- ./ecs/ecs.can:201 +end -- ./ecs/ecs.can:201 +local coinFlip -- ./ecs/ecs.can:206 +coinFlip = function() -- ./ecs/ecs.can:206 +return math["random"](0, 1) == 1 -- ./ecs/ecs.can:207 +end -- ./ecs/ecs.can:207 +local skipInsert -- ./ecs/ecs.can:212 +skipInsert = function(self, system, e) -- ./ecs/ecs.can:212 +local prevLayer -- ./ecs/ecs.can:214 +prevLayer = {} -- ./ecs/ecs.can:214 +local prev -- ./ecs/ecs.can:215 +prev = self["first"] -- ./ecs/ecs.can:215 +for i = self["nLayers"], 1, - 1 do -- ./ecs/ecs.can:216 +while true do -- ./ecs/ecs.can:217 +if prev[2] == nil or system:compare(e, prev[2][1]) then -- ./ecs/ecs.can:219 +prevLayer[i] = prev -- ./ecs/ecs.can:220 +if prev[3] then -- ./ecs/ecs.can:222 +prev = prev[3] -- ./ecs/ecs.can:223 +break -- ./ecs/ecs.can:224 +end -- ./ecs/ecs.can:224 +break -- ./ecs/ecs.can:226 +else -- ./ecs/ecs.can:226 +prev = prev[2] -- ./ecs/ecs.can:229 +end -- ./ecs/ecs.can:229 +end -- ./ecs/ecs.can:229 +end -- ./ecs/ecs.can:229 +local inLowerLayer -- ./ecs/ecs.can:234 +for i = 1, self["nLayers"] do -- ./ecs/ecs.can:235 +prev = prevLayer[i] -- ./ecs/ecs.can:236 +if i == 1 or coinFlip() then -- ./ecs/ecs.can:237 +local nxt -- ./ecs/ecs.can:238 +nxt = prev[2] -- ./ecs/ecs.can:238 +prev[2] = { -- ./ecs/ecs.can:239 +e, -- ./ecs/ecs.can:239 +nxt, -- ./ecs/ecs.can:239 +inLowerLayer -- ./ecs/ecs.can:239 +} -- ./ecs/ecs.can:239 +self["previous"][i][e] = prev -- ./ecs/ecs.can:240 +if nxt then -- ./ecs/ecs.can:241 +self["previous"][i][nxt[1]] = prev[2] -- ./ecs/ecs.can:242 end -- ./ecs/ecs.can:242 -end -- ./ecs/ecs.can:242 -self["n"] = self["n"] + (1) -- ./ecs/ecs.can:245 -end -- ./ecs/ecs.can:245 -local skipDelete -- ./ecs/ecs.can:251 -skipDelete = function(self, e) -- ./ecs/ecs.can:251 -for i = 1, self["nLayers"] do -- ./ecs/ecs.can:253 -local previous -- ./ecs/ecs.can:254 -previous = self["previous"][i] -- ./ecs/ecs.can:254 -if previous[e] then -- ./ecs/ecs.can:255 -local prev -- ./ecs/ecs.can:256 -prev = previous[e] -- ./ecs/ecs.can:256 -prev[2] = prev[2][2] -- ./ecs/ecs.can:257 -previous[e] = nil -- ./ecs/ecs.can:258 -if prev[2] then -- ./ecs/ecs.can:259 -previous[prev[2][1]] = prev -- ./ecs/ecs.can:260 -end -- ./ecs/ecs.can:260 -else -- ./ecs/ecs.can:260 -break -- ./ecs/ecs.can:263 -end -- ./ecs/ecs.can:263 -end -- ./ecs/ecs.can:263 -self["n"] = self["n"] - (1) -- ./ecs/ecs.can:266 -end -- ./ecs/ecs.can:266 -local skipReorder -- ./ecs/ecs.can:272 -skipReorder = function(self, system, e) -- ./ecs/ecs.can:272 -skipDelete(self, e) -- ./ecs/ecs.can:273 -skipInsert(self, system, e) -- ./ecs/ecs.can:274 -end -- ./ecs/ecs.can:274 -local skipIndex -- ./ecs/ecs.can:279 -skipIndex = function(self, i) -- ./ecs/ecs.can:279 -local n = 1 -- ./ecs/ecs.can:280 -for e in skipIter(self) do -- ./ecs/ecs.can:281 -if n == i then -- ./ecs/ecs.can:282 -return e -- ./ecs/ecs.can:283 -end -- ./ecs/ecs.can:283 -n = n + (1) -- ./ecs/ecs.can:285 -end -- ./ecs/ecs.can:285 -return nil -- ./ecs/ecs.can:287 +inLowerLayer = prev[2] -- ./ecs/ecs.can:244 +else -- ./ecs/ecs.can:244 +break -- ./ecs/ecs.can:246 +end -- ./ecs/ecs.can:246 +end -- ./ecs/ecs.can:246 +self["n"] = self["n"] + (1) -- ./ecs/ecs.can:249 +end -- ./ecs/ecs.can:249 +local skipDelete -- ./ecs/ecs.can:255 +skipDelete = function(self, e) -- ./ecs/ecs.can:255 +for i = 1, self["nLayers"] do -- ./ecs/ecs.can:257 +local previous -- ./ecs/ecs.can:258 +previous = self["previous"][i] -- ./ecs/ecs.can:258 +if previous[e] then -- ./ecs/ecs.can:259 +local prev -- ./ecs/ecs.can:260 +prev = previous[e] -- ./ecs/ecs.can:260 +prev[2] = prev[2][2] -- ./ecs/ecs.can:261 +previous[e] = nil -- ./ecs/ecs.can:262 +if prev[2] then -- ./ecs/ecs.can:263 +previous[prev[2][1]] = prev -- ./ecs/ecs.can:264 +end -- ./ecs/ecs.can:264 +else -- ./ecs/ecs.can:264 +break -- ./ecs/ecs.can:267 +end -- ./ecs/ecs.can:267 +end -- ./ecs/ecs.can:267 +self["n"] = self["n"] - (1) -- ./ecs/ecs.can:270 +end -- ./ecs/ecs.can:270 +local skipReorder -- ./ecs/ecs.can:276 +skipReorder = function(self, system, e) -- ./ecs/ecs.can:276 +skipDelete(self, e) -- ./ecs/ecs.can:277 +skipInsert(self, system, e) -- ./ecs/ecs.can:278 +end -- ./ecs/ecs.can:278 +local skipIndex -- ./ecs/ecs.can:283 +skipIndex = function(self, i) -- ./ecs/ecs.can:283 +local n = 1 -- ./ecs/ecs.can:284 +for e in skipIter(self) do -- ./ecs/ecs.can:285 +if n == i then -- ./ecs/ecs.can:286 +return e -- ./ecs/ecs.can:287 end -- ./ecs/ecs.can:287 -local system_mt -- ./ecs/ecs.can:351 -system_mt = { -- ./ecs/ecs.can:351 -["name"] = nil, -- ./ecs/ecs.can:365 -["systems"] = nil, -- ./ecs/ecs.can:373 -["interval"] = false, -- ./ecs/ecs.can:379 -["active"] = true, -- ./ecs/ecs.can:383 -["visible"] = true, -- ./ecs/ecs.can:387 -["component"] = nil, -- ./ecs/ecs.can:394 -["default"] = nil, -- ./ecs/ecs.can:404 -["filter"] = function(self, e) -- ./ecs/ecs.can:425 -return false -- ./ecs/ecs.can:425 -end, -- ./ecs/ecs.can:425 -["compare"] = function(self, e1, e2) -- ./ecs/ecs.can:437 -return true -- ./ecs/ecs.can:437 -end, -- ./ecs/ecs.can:437 -["onAdd"] = function(self, e, c) -- ./ecs/ecs.can:443 - -- ./ecs/ecs.can:443 -end, -- ./ecs/ecs.can:443 -["onRemove"] = function(self, e, c) -- ./ecs/ecs.can:448 - -- ./ecs/ecs.can:448 -end, -- ./ecs/ecs.can:448 -["onInstance"] = function(self) -- ./ecs/ecs.can:451 - -- ./ecs/ecs.can:451 -end, -- ./ecs/ecs.can:451 -["onAddToWorld"] = function(self, world) -- ./ecs/ecs.can:455 +n = n + (1) -- ./ecs/ecs.can:289 +end -- ./ecs/ecs.can:289 +return nil -- ./ecs/ecs.can:291 +end -- ./ecs/ecs.can:291 +local system_mt -- ./ecs/ecs.can:355 +system_mt = { -- ./ecs/ecs.can:355 +["name"] = nil, -- ./ecs/ecs.can:369 +["systems"] = nil, -- ./ecs/ecs.can:377 +["interval"] = false, -- ./ecs/ecs.can:383 +["active"] = true, -- ./ecs/ecs.can:387 +["visible"] = true, -- ./ecs/ecs.can:391 +["component"] = nil, -- ./ecs/ecs.can:398 +["default"] = nil, -- ./ecs/ecs.can:408 +["filter"] = function(self, e) -- ./ecs/ecs.can:429 +return false -- ./ecs/ecs.can:429 +end, -- ./ecs/ecs.can:429 +["compare"] = function(self, e1, e2) -- ./ecs/ecs.can:441 +return true -- ./ecs/ecs.can:441 +end, -- ./ecs/ecs.can:441 +["onAdd"] = function(self, e, c) -- ./ecs/ecs.can:447 + -- ./ecs/ecs.can:447 +end, -- ./ecs/ecs.can:447 +["onRemove"] = function(self, e, c) -- ./ecs/ecs.can:452 + -- ./ecs/ecs.can:452 +end, -- ./ecs/ecs.can:452 +["onInstance"] = function(self) -- ./ecs/ecs.can:455 -- ./ecs/ecs.can:455 end, -- ./ecs/ecs.can:455 -["onRemoveFromWorld"] = function(self, world) -- ./ecs/ecs.can:459 +["onAddToWorld"] = function(self, world) -- ./ecs/ecs.can:459 -- ./ecs/ecs.can:459 end, -- ./ecs/ecs.can:459 -["onDestroy"] = function(self) -- ./ecs/ecs.can:462 - -- ./ecs/ecs.can:462 -end, -- ./ecs/ecs.can:462 -["onUpdate"] = function(self, dt) -- ./ecs/ecs.can:467 - -- ./ecs/ecs.can:467 -end, -- ./ecs/ecs.can:467 -["onDraw"] = function(self) -- ./ecs/ecs.can:471 +["onRemoveFromWorld"] = function(self, world) -- ./ecs/ecs.can:463 + -- ./ecs/ecs.can:463 +end, -- ./ecs/ecs.can:463 +["onDestroy"] = function(self) -- ./ecs/ecs.can:466 + -- ./ecs/ecs.can:466 +end, -- ./ecs/ecs.can:466 +["onUpdate"] = function(self, dt) -- ./ecs/ecs.can:471 -- ./ecs/ecs.can:471 end, -- ./ecs/ecs.can:471 -["process"] = function(self, e, c, dt) -- ./ecs/ecs.can:478 - -- ./ecs/ecs.can:478 -end, -- ./ecs/ecs.can:478 -["render"] = function(self, e, c) -- ./ecs/ecs.can:484 - -- ./ecs/ecs.can:484 -end, -- ./ecs/ecs.can:484 -["onUpdateEnd"] = function(self, dt) -- ./ecs/ecs.can:489 - -- ./ecs/ecs.can:489 -end, -- ./ecs/ecs.can:489 -["onDrawEnd"] = function(self) -- ./ecs/ecs.can:493 +["onDraw"] = function(self) -- ./ecs/ecs.can:475 + -- ./ecs/ecs.can:475 +end, -- ./ecs/ecs.can:475 +["process"] = function(self, e, c, dt) -- ./ecs/ecs.can:482 + -- ./ecs/ecs.can:482 +end, -- ./ecs/ecs.can:482 +["render"] = function(self, e, c) -- ./ecs/ecs.can:488 + -- ./ecs/ecs.can:488 +end, -- ./ecs/ecs.can:488 +["onUpdateEnd"] = function(self, dt) -- ./ecs/ecs.can:493 -- ./ecs/ecs.can:493 end, -- ./ecs/ecs.can:493 -["world"] = nil, -- ./ecs/ecs.can:503 -["w"] = nil, -- ./ecs/ecs.can:507 -["entityCount"] = 0, -- ./ecs/ecs.can:511 -["s"] = nil, -- ./ecs/ecs.can:515 -["_has"] = nil, -- ./ecs/ecs.can:523 -["_waited"] = 0, -- ./ecs/ecs.can:527 -["add"] = function(self, e, ...) -- ./ecs/ecs.can:548 -if e ~= nil and not self["_has"][e] and self:filter(e) then -- ./ecs/ecs.can:549 -if self["component"] and self["default"] then -- ./ecs/ecs.can:551 -copy({ [self["component"]] = self["default"] }, e) -- ./ecs/ecs.can:552 -end -- ./ecs/ecs.can:552 -if self["compare"] ~= system_mt["compare"] then -- ./ecs/ecs.can:555 -skipAddLayers(self["_skiplist"]) -- ./ecs/ecs.can:556 +["onDrawEnd"] = function(self) -- ./ecs/ecs.can:497 + -- ./ecs/ecs.can:497 +end, -- ./ecs/ecs.can:497 +["world"] = nil, -- ./ecs/ecs.can:507 +["w"] = nil, -- ./ecs/ecs.can:511 +["entityCount"] = 0, -- ./ecs/ecs.can:515 +["s"] = nil, -- ./ecs/ecs.can:519 +["_has"] = nil, -- ./ecs/ecs.can:527 +["_waited"] = 0, -- ./ecs/ecs.can:531 +["add"] = function(self, e, ...) -- ./ecs/ecs.can:552 +if e ~= nil and not self["_has"][e] and self:filter(e) then -- ./ecs/ecs.can:553 +if self["component"] and self["default"] then -- ./ecs/ecs.can:555 +copy({ [self["component"]] = self["default"] }, e) -- ./ecs/ecs.can:556 end -- ./ecs/ecs.can:556 -skipInsert(self["_skiplist"], self, e) -- ./ecs/ecs.can:559 -self["entityCount"] = self["entityCount"] + (1) -- ./ecs/ecs.can:561 -self:onAdd(e, e[self["component"]]) -- ./ecs/ecs.can:562 -if self["_has"][e] then -- ./ecs/ecs.can:564 -for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:565 -s:add(e) -- ./ecs/ecs.can:566 -end -- ./ecs/ecs.can:566 -end -- ./ecs/ecs.can:566 -end -- ./ecs/ecs.can:566 -if ... then -- ./ecs/ecs.can:570 -return e, self:add(...) -- ./ecs/ecs.can:571 -else -- ./ecs/ecs.can:571 -return e -- ./ecs/ecs.can:573 -end -- ./ecs/ecs.can:573 -end, -- ./ecs/ecs.can:573 -["remove"] = function(self, e, ...) -- ./ecs/ecs.can:588 -if e ~= nil then -- ./ecs/ecs.can:589 -if self["_has"][e] then -- ./ecs/ecs.can:590 -for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:592 -s:remove(e) -- ./ecs/ecs.can:593 -end -- ./ecs/ecs.can:593 -end -- ./ecs/ecs.can:593 -if self["_has"][e] then -- ./ecs/ecs.can:596 -skipDelete(self["_skiplist"], e) -- ./ecs/ecs.can:597 -self["entityCount"] = self["entityCount"] - (1) -- ./ecs/ecs.can:599 -self:onRemove(e, e[self["component"]]) -- ./ecs/ecs.can:600 -end -- ./ecs/ecs.can:600 -end -- ./ecs/ecs.can:600 -if ... then -- ./ecs/ecs.can:603 -return e, self:remove(...) -- ./ecs/ecs.can:604 -else -- ./ecs/ecs.can:604 -return e -- ./ecs/ecs.can:606 -end -- ./ecs/ecs.can:606 -end, -- ./ecs/ecs.can:606 -["refresh"] = function(self, e, ...) -- ./ecs/ecs.can:618 -if e ~= nil then -- ./ecs/ecs.can:619 -if not self["_has"][e] then -- ./ecs/ecs.can:620 -self:add(e) -- ./ecs/ecs.can:621 -else -- ./ecs/ecs.can:621 -if not self:filter(e) then -- ./ecs/ecs.can:623 -self:remove(e) -- ./ecs/ecs.can:624 -else -- ./ecs/ecs.can:624 -for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:626 -s:refresh(e) -- ./ecs/ecs.can:627 -end -- ./ecs/ecs.can:627 -end -- ./ecs/ecs.can:627 -end -- ./ecs/ecs.can:627 -end -- ./ecs/ecs.can:627 -if ... then -- ./ecs/ecs.can:632 -return e, self:refresh(...) -- ./ecs/ecs.can:633 -else -- ./ecs/ecs.can:633 -return e -- ./ecs/ecs.can:635 -end -- ./ecs/ecs.can:635 -end, -- ./ecs/ecs.can:635 -["reorder"] = function(self, e, ...) -- ./ecs/ecs.can:647 -if e ~= nil and self["_has"][e] then -- ./ecs/ecs.can:648 -skipReorder(self["_skiplist"], self, e) -- ./ecs/ecs.can:649 -for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:651 -s:reorder(e) -- ./ecs/ecs.can:652 -end -- ./ecs/ecs.can:652 -end -- ./ecs/ecs.can:652 -if ... then -- ./ecs/ecs.can:655 -return e, self:reorder(...) -- ./ecs/ecs.can:656 -else -- ./ecs/ecs.can:656 -return e -- ./ecs/ecs.can:658 -end -- ./ecs/ecs.can:658 -end, -- ./ecs/ecs.can:658 -["has"] = function(self, e, ...) -- ./ecs/ecs.can:667 -local has -- ./ecs/ecs.can:668 -has = e == nil or not not self["_has"][e] -- ./ecs/ecs.can:668 -if ... then -- ./ecs/ecs.can:669 -return has and self:has(...) -- ./ecs/ecs.can:670 -else -- ./ecs/ecs.can:670 -return has -- ./ecs/ecs.can:672 -end -- ./ecs/ecs.can:672 -end, -- ./ecs/ecs.can:672 -["iter"] = function(self) -- ./ecs/ecs.can:679 -return skipIter(self["_skiplist"]) -- ./ecs/ecs.can:680 -end, -- ./ecs/ecs.can:680 -["get"] = function(self, i) -- ./ecs/ecs.can:687 -return skipIndex(self["_skiplist"], i) -- ./ecs/ecs.can:688 -end, -- ./ecs/ecs.can:688 -["clear"] = function(self) -- ./ecs/ecs.can:693 -for e in skipIter(self["_skiplist"]) do -- ./ecs/ecs.can:694 -self:remove(e) -- ./ecs/ecs.can:695 -end -- ./ecs/ecs.can:695 -for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:697 -s:clear() -- ./ecs/ecs.can:698 -end -- ./ecs/ecs.can:698 -end, -- ./ecs/ecs.can:698 -["update"] = function(self, dt) -- ./ecs/ecs.can:707 -if self["active"] then -- ./ecs/ecs.can:708 -if self["interval"] then -- ./ecs/ecs.can:709 -self["_waited"] = self["_waited"] + (dt) -- ./ecs/ecs.can:710 -if self["_waited"] < self["interval"] then -- ./ecs/ecs.can:711 -return -- ./ecs/ecs.can:712 -end -- ./ecs/ecs.can:712 -end -- ./ecs/ecs.can:712 -self:onUpdate(dt) -- ./ecs/ecs.can:715 -if self["process"] ~= system_mt["process"] then -- ./ecs/ecs.can:716 -for e in skipIter(self["_skiplist"]) do -- ./ecs/ecs.can:717 -self:process(e, e[self["component"]], dt) -- ./ecs/ecs.can:718 -end -- ./ecs/ecs.can:718 -end -- ./ecs/ecs.can:718 -for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:721 -s:update(dt) -- ./ecs/ecs.can:722 +if self["compare"] ~= system_mt["compare"] then -- ./ecs/ecs.can:559 +skipAddLayers(self["_skiplist"]) -- ./ecs/ecs.can:560 +end -- ./ecs/ecs.can:560 +skipInsert(self["_skiplist"], self, e) -- ./ecs/ecs.can:563 +self["entityCount"] = self["entityCount"] + (1) -- ./ecs/ecs.can:565 +self:onAdd(e, e[self["component"]]) -- ./ecs/ecs.can:566 +if self["_has"][e] then -- ./ecs/ecs.can:568 +for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:569 +s:add(e) -- ./ecs/ecs.can:570 +end -- ./ecs/ecs.can:570 +end -- ./ecs/ecs.can:570 +end -- ./ecs/ecs.can:570 +if ... then -- ./ecs/ecs.can:574 +return e, self:add(...) -- ./ecs/ecs.can:575 +else -- ./ecs/ecs.can:575 +return e -- ./ecs/ecs.can:577 +end -- ./ecs/ecs.can:577 +end, -- ./ecs/ecs.can:577 +["remove"] = function(self, e, ...) -- ./ecs/ecs.can:592 +if e ~= nil then -- ./ecs/ecs.can:593 +if self["_has"][e] then -- ./ecs/ecs.can:594 +for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:596 +s:remove(e) -- ./ecs/ecs.can:597 +end -- ./ecs/ecs.can:597 +end -- ./ecs/ecs.can:597 +if self["_has"][e] then -- ./ecs/ecs.can:600 +skipDelete(self["_skiplist"], e) -- ./ecs/ecs.can:601 +self["entityCount"] = self["entityCount"] - (1) -- ./ecs/ecs.can:603 +self:onRemove(e, e[self["component"]]) -- ./ecs/ecs.can:604 +end -- ./ecs/ecs.can:604 +end -- ./ecs/ecs.can:604 +if ... then -- ./ecs/ecs.can:607 +return e, self:remove(...) -- ./ecs/ecs.can:608 +else -- ./ecs/ecs.can:608 +return e -- ./ecs/ecs.can:610 +end -- ./ecs/ecs.can:610 +end, -- ./ecs/ecs.can:610 +["refresh"] = function(self, e, ...) -- ./ecs/ecs.can:622 +if e ~= nil then -- ./ecs/ecs.can:623 +if not self["_has"][e] then -- ./ecs/ecs.can:624 +self:add(e) -- ./ecs/ecs.can:625 +else -- ./ecs/ecs.can:625 +if not self:filter(e) then -- ./ecs/ecs.can:627 +self:remove(e) -- ./ecs/ecs.can:628 +else -- ./ecs/ecs.can:628 +for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:630 +s:refresh(e) -- ./ecs/ecs.can:631 +end -- ./ecs/ecs.can:631 +end -- ./ecs/ecs.can:631 +end -- ./ecs/ecs.can:631 +end -- ./ecs/ecs.can:631 +if ... then -- ./ecs/ecs.can:636 +return e, self:refresh(...) -- ./ecs/ecs.can:637 +else -- ./ecs/ecs.can:637 +return e -- ./ecs/ecs.can:639 +end -- ./ecs/ecs.can:639 +end, -- ./ecs/ecs.can:639 +["reorder"] = function(self, e, ...) -- ./ecs/ecs.can:651 +if e ~= nil and self["_has"][e] then -- ./ecs/ecs.can:652 +skipReorder(self["_skiplist"], self, e) -- ./ecs/ecs.can:653 +for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:655 +s:reorder(e) -- ./ecs/ecs.can:656 +end -- ./ecs/ecs.can:656 +end -- ./ecs/ecs.can:656 +if ... then -- ./ecs/ecs.can:659 +return e, self:reorder(...) -- ./ecs/ecs.can:660 +else -- ./ecs/ecs.can:660 +return e -- ./ecs/ecs.can:662 +end -- ./ecs/ecs.can:662 +end, -- ./ecs/ecs.can:662 +["has"] = function(self, e, ...) -- ./ecs/ecs.can:671 +local has -- ./ecs/ecs.can:672 +has = e == nil or not not self["_has"][e] -- ./ecs/ecs.can:672 +if ... then -- ./ecs/ecs.can:673 +return has and self:has(...) -- ./ecs/ecs.can:674 +else -- ./ecs/ecs.can:674 +return has -- ./ecs/ecs.can:676 +end -- ./ecs/ecs.can:676 +end, -- ./ecs/ecs.can:676 +["iter"] = function(self) -- ./ecs/ecs.can:683 +return skipIter(self["_skiplist"]) -- ./ecs/ecs.can:684 +end, -- ./ecs/ecs.can:684 +["get"] = function(self, i) -- ./ecs/ecs.can:691 +return skipIndex(self["_skiplist"], i) -- ./ecs/ecs.can:692 +end, -- ./ecs/ecs.can:692 +["clear"] = function(self) -- ./ecs/ecs.can:697 +for e in skipIter(self["_skiplist"]) do -- ./ecs/ecs.can:698 +self:remove(e) -- ./ecs/ecs.can:699 +end -- ./ecs/ecs.can:699 +for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:701 +s:clear() -- ./ecs/ecs.can:702 +end -- ./ecs/ecs.can:702 +end, -- ./ecs/ecs.can:702 +["update"] = function(self, dt) -- ./ecs/ecs.can:711 +if self["active"] then -- ./ecs/ecs.can:712 +if self["interval"] then -- ./ecs/ecs.can:713 +self["_waited"] = self["_waited"] + (dt) -- ./ecs/ecs.can:714 +if self["_waited"] < self["interval"] then -- ./ecs/ecs.can:715 +return -- ./ecs/ecs.can:716 +end -- ./ecs/ecs.can:716 +end -- ./ecs/ecs.can:716 +self:onUpdate(dt) -- ./ecs/ecs.can:719 +if self["process"] ~= system_mt["process"] then -- ./ecs/ecs.can:720 +for e in skipIter(self["_skiplist"]) do -- ./ecs/ecs.can:721 +self:process(e, e[self["component"]], dt) -- ./ecs/ecs.can:722 end -- ./ecs/ecs.can:722 -self:onUpdateEnd(dt) -- ./ecs/ecs.can:724 -if self["interval"] then -- ./ecs/ecs.can:725 -self["_waited"] = self["_waited"] - (self["interval"]) -- ./ecs/ecs.can:726 +end -- ./ecs/ecs.can:722 +for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:725 +s:update(dt) -- ./ecs/ecs.can:726 end -- ./ecs/ecs.can:726 -end -- ./ecs/ecs.can:726 -end, -- ./ecs/ecs.can:726 -["draw"] = function(self) -- ./ecs/ecs.can:735 -if self["visible"] then -- ./ecs/ecs.can:736 -self:onDraw() -- ./ecs/ecs.can:737 -if self["render"] ~= system_mt["render"] then -- ./ecs/ecs.can:738 -for e in skipIter(self["_skiplist"]) do -- ./ecs/ecs.can:739 -self:render(e, e[self["component"]]) -- ./ecs/ecs.can:740 -end -- ./ecs/ecs.can:740 -end -- ./ecs/ecs.can:740 -for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:743 -s:draw() -- ./ecs/ecs.can:744 +self:onUpdateEnd(dt) -- ./ecs/ecs.can:728 +if self["interval"] then -- ./ecs/ecs.can:729 +self["_waited"] = self["_waited"] - (self["interval"]) -- ./ecs/ecs.can:730 +end -- ./ecs/ecs.can:730 +end -- ./ecs/ecs.can:730 +end, -- ./ecs/ecs.can:730 +["draw"] = function(self) -- ./ecs/ecs.can:739 +if self["visible"] then -- ./ecs/ecs.can:740 +self:onDraw() -- ./ecs/ecs.can:741 +if self["render"] ~= system_mt["render"] then -- ./ecs/ecs.can:742 +for e in skipIter(self["_skiplist"]) do -- ./ecs/ecs.can:743 +self:render(e, e[self["component"]]) -- ./ecs/ecs.can:744 end -- ./ecs/ecs.can:744 -self:onDrawEnd() -- ./ecs/ecs.can:746 -end -- ./ecs/ecs.can:746 -end, -- ./ecs/ecs.can:746 -["callback"] = function(self, name, e, ...) -- ./ecs/ecs.can:761 -if self["_has"][e] and self[name] then -- ./ecs/ecs.can:763 -self[name](self, e, e[self["component"]], ...) -- ./ecs/ecs.can:764 -end -- ./ecs/ecs.can:764 -if self["_has"][e] then -- ./ecs/ecs.can:767 -for _, ss in ipairs(self["systems"]) do -- ./ecs/ecs.can:768 -ss:callback(name, e, ...) -- ./ecs/ecs.can:769 -end -- ./ecs/ecs.can:769 -end -- ./ecs/ecs.can:769 -end, -- ./ecs/ecs.can:769 -["emit"] = function(self, name, ...) -- ./ecs/ecs.can:795 -local status -- ./ecs/ecs.can:797 -if self[name] then -- ./ecs/ecs.can:798 -status = self[name](self, ...) -- ./ecs/ecs.can:799 -end -- ./ecs/ecs.can:799 -if status ~= "stop" and status ~= "capture" then -- ./ecs/ecs.can:802 -for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:803 -status = s:emit(name, ...) -- ./ecs/ecs.can:804 -if status == "capture" then -- ./ecs/ecs.can:805 -break -- ./ecs/ecs.can:805 -end -- ./ecs/ecs.can:805 -end -- ./ecs/ecs.can:805 -end -- ./ecs/ecs.can:805 -return status -- ./ecs/ecs.can:808 -end, -- ./ecs/ecs.can:808 -["destroy"] = function(self) -- ./ecs/ecs.can:812 -recCallOnRemoveFromWorld(self["world"], { self }) -- ./ecs/ecs.can:813 -recDestroySystems({ ["systems"] = { self } }) -- ./ecs/ecs.can:814 -end -- ./ecs/ecs.can:814 -} -- ./ecs/ecs.can:814 -local alwaysTrue -- ./ecs/ecs.can:819 -alwaysTrue = function() -- ./ecs/ecs.can:819 -return true -- ./ecs/ecs.can:819 -end -- ./ecs/ecs.can:819 -local alwaysFalse -- ./ecs/ecs.can:820 -alwaysFalse = function() -- ./ecs/ecs.can:820 -return false -- ./ecs/ecs.can:820 -end -- ./ecs/ecs.can:820 -local recInstanciateSystems -- ./ecs/ecs.can:825 -recInstanciateSystems = function(world, systems) -- ./ecs/ecs.can:825 -local t -- ./ecs/ecs.can:826 -t = {} -- ./ecs/ecs.can:826 -for _, s in ipairs(systems) do -- ./ecs/ecs.can:827 -local system -- ./ecs/ecs.can:828 -system = setmetatable({ -- ./ecs/ecs.can:830 -["systems"] = recInstanciateSystems(world, s["systems"] or {}), -- ./ecs/ecs.can:831 -["world"] = world, -- ./ecs/ecs.can:832 -["w"] = world, -- ./ecs/ecs.can:833 -["s"] = world["s"], -- ./ecs/ecs.can:834 -["_skiplist"] = skipNew() -- ./ecs/ecs.can:835 -}, { ["__index"] = function(self, k) -- ./ecs/ecs.can:837 -if s[k] ~= nil then -- ./ecs/ecs.can:838 -return s[k] -- ./ecs/ecs.can:839 -else -- ./ecs/ecs.can:839 -return system_mt[k] -- ./ecs/ecs.can:841 -end -- ./ecs/ecs.can:841 -end }) -- ./ecs/ecs.can:841 -system["_has"] = system["_skiplist"]["previous"][1] -- ./ecs/ecs.can:845 -if type(s["filter"]) == "string" then -- ./ecs/ecs.can:847 -system["filter"] = function(_, e) -- ./ecs/ecs.can:848 -return e[s["filter"]] ~= nil -- ./ecs/ecs.can:848 -end -- ./ecs/ecs.can:848 -elseif type(s["filter"]) == "table" then -- ./ecs/ecs.can:849 -system["filter"] = ecs["all"](unpack(s["filter"])) -- ./ecs/ecs.can:850 -elseif type(s["filter"]) == "boolean" then -- ./ecs/ecs.can:851 -if s["filter"] then -- ./ecs/ecs.can:852 -system["filter"] = alwaysTrue -- ./ecs/ecs.can:853 -else -- ./ecs/ecs.can:853 -system["filter"] = alwaysFalse -- ./ecs/ecs.can:855 -end -- ./ecs/ecs.can:855 -end -- ./ecs/ecs.can:855 -if not s["component"] and s["name"] then -- ./ecs/ecs.can:859 -s["component"] = s["name"] -- ./ecs/ecs.can:860 -end -- ./ecs/ecs.can:860 -table["insert"](t, system) -- ./ecs/ecs.can:863 -if s["name"] then -- ./ecs/ecs.can:864 -world["s"][s["name"]] = system -- ./ecs/ecs.can:865 -end -- ./ecs/ecs.can:865 -system:onInstance() -- ./ecs/ecs.can:867 -end -- ./ecs/ecs.can:867 -return t -- ./ecs/ecs.can:869 -end -- ./ecs/ecs.can:869 -local recCallOnAddToWorld -- ./ecs/ecs.can:872 -recCallOnAddToWorld = function(world, systems) -- ./ecs/ecs.can:872 -for _, s in ipairs(systems) do -- ./ecs/ecs.can:873 -recCallOnAddToWorld(world, s["systems"]) -- ./ecs/ecs.can:874 -s:onAddToWorld(world) -- ./ecs/ecs.can:875 -end -- ./ecs/ecs.can:875 -end -- ./ecs/ecs.can:875 -ecs = { -- ./ecs/ecs.can:881 -["world"] = function(...) -- ./ecs/ecs.can:886 -local world -- ./ecs/ecs.can:887 -world = setmetatable({ -- ./ecs/ecs.can:887 -["filter"] = ecs["all"](), -- ./ecs/ecs.can:888 -["s"] = {}, -- ./ecs/ecs.can:889 -["_skiplist"] = skipNew() -- ./ecs/ecs.can:890 -}, { ["__index"] = system_mt }) -- ./ecs/ecs.can:891 -world["_has"] = world["_skiplist"]["previous"][1] -- ./ecs/ecs.can:892 -world["world"] = world -- ./ecs/ecs.can:893 -world["w"] = world -- ./ecs/ecs.can:894 -world["systems"] = recInstanciateSystems(world, { ... }) -- ./ecs/ecs.can:895 -recCallOnAddToWorld(world, world["systems"]) -- ./ecs/ecs.can:896 -return world -- ./ecs/ecs.can:897 -end, -- ./ecs/ecs.can:897 -["all"] = function(...) -- ./ecs/ecs.can:903 -if ... then -- ./ecs/ecs.can:904 -local l -- ./ecs/ecs.can:905 -l = { ... } -- ./ecs/ecs.can:905 -return function(s, e) -- ./ecs/ecs.can:906 -for _, k in ipairs(l) do -- ./ecs/ecs.can:907 -if e[k] == nil then -- ./ecs/ecs.can:908 -return false -- ./ecs/ecs.can:909 -end -- ./ecs/ecs.can:909 -end -- ./ecs/ecs.can:909 -return true -- ./ecs/ecs.can:912 -end -- ./ecs/ecs.can:912 -else -- ./ecs/ecs.can:912 -return alwaysTrue -- ./ecs/ecs.can:915 -end -- ./ecs/ecs.can:915 -end, -- ./ecs/ecs.can:915 -["any"] = function(...) -- ./ecs/ecs.can:922 -if ... then -- ./ecs/ecs.can:923 -local l -- ./ecs/ecs.can:924 -l = { ... } -- ./ecs/ecs.can:924 -return function(s, e) -- ./ecs/ecs.can:925 -for _, k in ipairs(l) do -- ./ecs/ecs.can:926 -if e[k] ~= nil then -- ./ecs/ecs.can:927 -return true -- ./ecs/ecs.can:928 -end -- ./ecs/ecs.can:928 -end -- ./ecs/ecs.can:928 -return false -- ./ecs/ecs.can:931 -end -- ./ecs/ecs.can:931 -else -- ./ecs/ecs.can:931 -return alwaysFalse -- ./ecs/ecs.can:934 -end -- ./ecs/ecs.can:934 -end, -- ./ecs/ecs.can:934 -["scene"] = function(name, systems, entities) -- ./ecs/ecs.can:952 -if systems == nil then systems = {} end -- ./ecs/ecs.can:952 -if entities == nil then entities = {} end -- ./ecs/ecs.can:952 -assert(scene, "ubiquitousse.scene unavailable") -- ./ecs/ecs.can:953 -local s -- ./ecs/ecs.can:954 -s = scene["new"](name) -- ./ecs/ecs.can:954 -local w -- ./ecs/ecs.can:955 -s["enter"] = function(self) -- ./ecs/ecs.can:957 -local sys, ent = systems, entities -- ./ecs/ecs.can:958 -if type(systems) == "function" then -- ./ecs/ecs.can:959 -sys = { systems() } -- ./ecs/ecs.can:959 +end -- ./ecs/ecs.can:744 +for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:747 +s:draw() -- ./ecs/ecs.can:748 +end -- ./ecs/ecs.can:748 +self:onDrawEnd() -- ./ecs/ecs.can:750 +end -- ./ecs/ecs.can:750 +end, -- ./ecs/ecs.can:750 +["callback"] = function(self, name, e, ...) -- ./ecs/ecs.can:765 +return self:callbackFiltered(alwaysTrue, name, e, ...) -- ./ecs/ecs.can:766 +end, -- ./ecs/ecs.can:766 +["callbackFiltered"] = function(self, filter, name, e, ...) -- ./ecs/ecs.can:779 +if filter(self, name, e, ...) then -- ./ecs/ecs.can:780 +if self["_has"][e] and self[name] then -- ./ecs/ecs.can:782 +self[name](self, e, e[self["component"]], ...) -- ./ecs/ecs.can:783 +end -- ./ecs/ecs.can:783 +if self["_has"][e] then -- ./ecs/ecs.can:786 +for _, ss in ipairs(self["systems"]) do -- ./ecs/ecs.can:787 +ss:callbackFiltered(filter, name, e, ...) -- ./ecs/ecs.can:788 +end -- ./ecs/ecs.can:788 +end -- ./ecs/ecs.can:788 +end -- ./ecs/ecs.can:788 +end, -- ./ecs/ecs.can:788 +["emit"] = function(self, name, ...) -- ./ecs/ecs.can:815 +return self:emitFiltered(alwaysTrue, name, ...) -- ./ecs/ecs.can:816 +end, -- ./ecs/ecs.can:816 +["emitFiltered"] = function(self, filter, name, ...) -- ./ecs/ecs.can:828 +if filter(self, name, ...) then -- ./ecs/ecs.can:829 +local status -- ./ecs/ecs.can:831 +if self[name] then -- ./ecs/ecs.can:832 +status = self[name](self, ...) -- ./ecs/ecs.can:833 +end -- ./ecs/ecs.can:833 +if status ~= "stop" and status ~= "capture" then -- ./ecs/ecs.can:836 +for _, s in ipairs(self["systems"]) do -- ./ecs/ecs.can:837 +status = s:emitFiltered(filter, name, ...) -- ./ecs/ecs.can:838 +if status == "capture" then -- ./ecs/ecs.can:839 +break -- ./ecs/ecs.can:839 +end -- ./ecs/ecs.can:839 +end -- ./ecs/ecs.can:839 +end -- ./ecs/ecs.can:839 +return status -- ./ecs/ecs.can:842 +end -- ./ecs/ecs.can:842 +end, -- ./ecs/ecs.can:842 +["destroy"] = function(self) -- ./ecs/ecs.can:847 +recCallOnRemoveFromWorld(self["world"], { self }) -- ./ecs/ecs.can:848 +recDestroySystems({ ["systems"] = { self } }) -- ./ecs/ecs.can:849 +end -- ./ecs/ecs.can:849 +} -- ./ecs/ecs.can:849 +local recInstanciateSystems -- ./ecs/ecs.can:856 +recInstanciateSystems = function(world, systems) -- ./ecs/ecs.can:856 +local t -- ./ecs/ecs.can:857 +t = {} -- ./ecs/ecs.can:857 +for _, s in ipairs(systems) do -- ./ecs/ecs.can:858 +local system -- ./ecs/ecs.can:859 +system = setmetatable({ -- ./ecs/ecs.can:861 +["systems"] = recInstanciateSystems(world, s["systems"] or {}), -- ./ecs/ecs.can:862 +["world"] = world, -- ./ecs/ecs.can:863 +["w"] = world, -- ./ecs/ecs.can:864 +["s"] = world["s"], -- ./ecs/ecs.can:865 +["_skiplist"] = skipNew() -- ./ecs/ecs.can:866 +}, { ["__index"] = function(self, k) -- ./ecs/ecs.can:868 +if s[k] ~= nil then -- ./ecs/ecs.can:869 +return s[k] -- ./ecs/ecs.can:870 +else -- ./ecs/ecs.can:870 +return system_mt[k] -- ./ecs/ecs.can:872 +end -- ./ecs/ecs.can:872 +end }) -- ./ecs/ecs.can:872 +system["_has"] = system["_skiplist"]["previous"][1] -- ./ecs/ecs.can:876 +if type(s["filter"]) == "string" then -- ./ecs/ecs.can:878 +system["filter"] = function(_, e) -- ./ecs/ecs.can:879 +return e[s["filter"]] ~= nil -- ./ecs/ecs.can:879 +end -- ./ecs/ecs.can:879 +elseif type(s["filter"]) == "table" then -- ./ecs/ecs.can:880 +system["filter"] = ecs["all"](unpack(s["filter"])) -- ./ecs/ecs.can:881 +elseif type(s["filter"]) == "boolean" then -- ./ecs/ecs.can:882 +if s["filter"] then -- ./ecs/ecs.can:883 +system["filter"] = alwaysTrue -- ./ecs/ecs.can:884 +else -- ./ecs/ecs.can:884 +system["filter"] = alwaysFalse -- ./ecs/ecs.can:886 +end -- ./ecs/ecs.can:886 +end -- ./ecs/ecs.can:886 +if not s["component"] and s["name"] then -- ./ecs/ecs.can:890 +s["component"] = s["name"] -- ./ecs/ecs.can:891 +end -- ./ecs/ecs.can:891 +table["insert"](t, system) -- ./ecs/ecs.can:894 +if s["name"] then -- ./ecs/ecs.can:895 +world["s"][s["name"]] = system -- ./ecs/ecs.can:896 +end -- ./ecs/ecs.can:896 +system:onInstance() -- ./ecs/ecs.can:898 +end -- ./ecs/ecs.can:898 +return t -- ./ecs/ecs.can:900 +end -- ./ecs/ecs.can:900 +local recCallOnAddToWorld -- ./ecs/ecs.can:903 +recCallOnAddToWorld = function(world, systems) -- ./ecs/ecs.can:903 +for _, s in ipairs(systems) do -- ./ecs/ecs.can:904 +recCallOnAddToWorld(world, s["systems"]) -- ./ecs/ecs.can:905 +s:onAddToWorld(world) -- ./ecs/ecs.can:906 +end -- ./ecs/ecs.can:906 +end -- ./ecs/ecs.can:906 +ecs = { -- ./ecs/ecs.can:912 +["world"] = function(...) -- ./ecs/ecs.can:917 +local world -- ./ecs/ecs.can:918 +world = setmetatable({ -- ./ecs/ecs.can:918 +["filter"] = ecs["all"](), -- ./ecs/ecs.can:919 +["s"] = {}, -- ./ecs/ecs.can:920 +["_skiplist"] = skipNew() -- ./ecs/ecs.can:921 +}, { ["__index"] = system_mt }) -- ./ecs/ecs.can:922 +world["_has"] = world["_skiplist"]["previous"][1] -- ./ecs/ecs.can:923 +world["world"] = world -- ./ecs/ecs.can:924 +world["w"] = world -- ./ecs/ecs.can:925 +world["systems"] = recInstanciateSystems(world, { ... }) -- ./ecs/ecs.can:926 +recCallOnAddToWorld(world, world["systems"]) -- ./ecs/ecs.can:927 +return world -- ./ecs/ecs.can:928 +end, -- ./ecs/ecs.can:928 +["all"] = function(...) -- ./ecs/ecs.can:934 +if ... then -- ./ecs/ecs.can:935 +local l -- ./ecs/ecs.can:936 +l = { ... } -- ./ecs/ecs.can:936 +return function(s, e) -- ./ecs/ecs.can:937 +for _, k in ipairs(l) do -- ./ecs/ecs.can:938 +if e[k] == nil then -- ./ecs/ecs.can:939 +return false -- ./ecs/ecs.can:940 +end -- ./ecs/ecs.can:940 +end -- ./ecs/ecs.can:940 +return true -- ./ecs/ecs.can:943 +end -- ./ecs/ecs.can:943 +else -- ./ecs/ecs.can:943 +return alwaysTrue -- ./ecs/ecs.can:946 +end -- ./ecs/ecs.can:946 +end, -- ./ecs/ecs.can:946 +["any"] = function(...) -- ./ecs/ecs.can:953 +if ... then -- ./ecs/ecs.can:954 +local l -- ./ecs/ecs.can:955 +l = { ... } -- ./ecs/ecs.can:955 +return function(s, e) -- ./ecs/ecs.can:956 +for _, k in ipairs(l) do -- ./ecs/ecs.can:957 +if e[k] ~= nil then -- ./ecs/ecs.can:958 +return true -- ./ecs/ecs.can:959 end -- ./ecs/ecs.can:959 -if type(entities) == "function" then -- ./ecs/ecs.can:960 -ent = { entities() } -- ./ecs/ecs.can:960 -end -- ./ecs/ecs.can:960 -w = ecs["world"](unpack(sys)) -- ./ecs/ecs.can:961 -w:add(unpack(ent)) -- ./ecs/ecs.can:962 +end -- ./ecs/ecs.can:959 +return false -- ./ecs/ecs.can:962 end -- ./ecs/ecs.can:962 -s["exit"] = function(self) -- ./ecs/ecs.can:964 -w:destroy() -- ./ecs/ecs.can:965 +else -- ./ecs/ecs.can:962 +return alwaysFalse -- ./ecs/ecs.can:965 end -- ./ecs/ecs.can:965 -s["suspend"] = function(self) -- ./ecs/ecs.can:967 -w:emit("onSuspend") -- ./ecs/ecs.can:968 -end -- ./ecs/ecs.can:968 -s["resume"] = function(self) -- ./ecs/ecs.can:970 -w:emit("onResume") -- ./ecs/ecs.can:971 -end -- ./ecs/ecs.can:971 -s["update"] = function(self, dt) -- ./ecs/ecs.can:973 -w:update(dt) -- ./ecs/ecs.can:974 -end -- ./ecs/ecs.can:974 -s["draw"] = function(self) -- ./ecs/ecs.can:976 -w:draw() -- ./ecs/ecs.can:977 -end -- ./ecs/ecs.can:977 -return s -- ./ecs/ecs.can:980 -end -- ./ecs/ecs.can:980 -} -- ./ecs/ecs.can:980 -return ecs -- ./ecs/ecs.can:984 +end, -- ./ecs/ecs.can:965 +["scene"] = function(name, systems, entities) -- ./ecs/ecs.can:983 +if systems == nil then systems = {} end -- ./ecs/ecs.can:983 +if entities == nil then entities = {} end -- ./ecs/ecs.can:983 +assert(scene, "ubiquitousse.scene unavailable") -- ./ecs/ecs.can:984 +local s -- ./ecs/ecs.can:985 +s = scene["new"](name) -- ./ecs/ecs.can:985 +local w -- ./ecs/ecs.can:986 +s["enter"] = function(self) -- ./ecs/ecs.can:988 +local sys, ent = systems, entities -- ./ecs/ecs.can:989 +if type(systems) == "function" then -- ./ecs/ecs.can:990 +sys = { systems() } -- ./ecs/ecs.can:990 +end -- ./ecs/ecs.can:990 +if type(entities) == "function" then -- ./ecs/ecs.can:991 +ent = { entities() } -- ./ecs/ecs.can:991 +end -- ./ecs/ecs.can:991 +w = ecs["world"](unpack(sys)) -- ./ecs/ecs.can:992 +w:add(unpack(ent)) -- ./ecs/ecs.can:993 +end -- ./ecs/ecs.can:993 +s["exit"] = function(self) -- ./ecs/ecs.can:995 +w:destroy() -- ./ecs/ecs.can:996 +end -- ./ecs/ecs.can:996 +s["suspend"] = function(self) -- ./ecs/ecs.can:998 +w:emit("onSuspend") -- ./ecs/ecs.can:999 +end -- ./ecs/ecs.can:999 +s["resume"] = function(self) -- ./ecs/ecs.can:1001 +w:emit("onResume") -- ./ecs/ecs.can:1002 +end -- ./ecs/ecs.can:1002 +s["update"] = function(self, dt) -- ./ecs/ecs.can:1004 +w:update(dt) -- ./ecs/ecs.can:1005 +end -- ./ecs/ecs.can:1005 +s["draw"] = function(self) -- ./ecs/ecs.can:1007 +w:draw() -- ./ecs/ecs.can:1008 +end -- ./ecs/ecs.can:1008 +return s -- ./ecs/ecs.can:1011 +end -- ./ecs/ecs.can:1011 +} -- ./ecs/ecs.can:1011 +return ecs -- ./ecs/ecs.can:1015 diff --git a/ecs/timer.lua b/ecs/timer.lua deleted file mode 100644 index a7ee518..0000000 --- a/ecs/timer.lua +++ /dev/null @@ -1,23 +0,0 @@ -local timer -- ./ecs/timer.can:4 -timer = require((...):match("^(.-)ecs%.timer") .. "scene") -- ./ecs/timer.can:4 -return { -- ./ecs/timer.can:6 -["name"] = "timer", -- ./ecs/timer.can:7 -["filter"] = "timer", -- ./ecs/timer.can:8 -["default"] = {}, -- ./ecs/timer.can:9 -["process"] = function(self, t, dt) -- ./ecs/timer.can:12 -t:update(dt) -- ./ecs/timer.can:13 -if t:dead() then -- ./ecs/timer.can:14 -self["world"]:remove(t["entity"]) -- ./ecs/timer.can:15 -end -- ./ecs/timer.can:15 -end, -- ./ecs/timer.can:15 -["run"] = function(self, func) -- ./ecs/timer.can:20 -local t = timer["run"](func) -- ./ecs/timer.can:21 -self["world"]:add({ ["timer"] = t }) -- ./ecs/timer.can:23 -return t -- ./ecs/timer.can:25 -end, -- ./ecs/timer.can:25 -["tween"] = function(self, duration, tbl, to, method) -- ./ecs/timer.can:28 -local t = timer["tween"](duration, tbl, to, method) -- ./ecs/timer.can:29 -self["world"]:add({ ["timer"] = t }) -- ./ecs/timer.can:31 -return t -- ./ecs/timer.can:33 -end -- ./ecs/timer.can:33 -} -- ./ecs/timer.can:33 From 6cf0fa4053132fe97296aabf620f5cbda16a488b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Thu, 13 Oct 2022 00:25:20 +0900 Subject: [PATCH 2/4] ldtk: identify level in error messages --- ldtk/ldtk.can | 8 ++++---- ldtk/ldtk.lua | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ldtk/ldtk.can b/ldtk/ldtk.can index 3c3ac06..18e32ed 100644 --- a/ldtk/ldtk.can +++ b/ldtk/ldtk.can @@ -534,7 +534,7 @@ let level_mt = { -- @number[opt=0] y offset Y position to draw the level at -- @require love draw = :(x=0, y=0) - assert(@loaded == true, "level not loaded") + assert(@loaded == true, ("level %q not loaded"):format(@identifier)) lg.push() lg.translate(x + @x, y + @y) @drawBackground() @@ -554,7 +554,7 @@ let level_mt = { -- @number[opt=0] y offset Y position to draw the backgroud at -- @require love drawBackground = :(x=0, y=0) - assert(@loaded == true, "level not loaded") + assert(@loaded == true, ("level %q not loaded"):format(@identifier)) -- background color lg.setColor(@background.color) lg.rectangle("fill", x, y, @width, @height) @@ -581,7 +581,7 @@ let level_mt = { -- -- @tparam[opt] table callbacks load = :(callbacks={}) - assert(@loaded == false, "level already loaded") + assert(@loaded == false, ("level %q already loaded"):format(@identifier)) if @_json.bgRelPath then let pos = @_json.__bgPos let cropRect = pos.cropRect @@ -623,7 +623,7 @@ let level_mt = { -- -- @tparam[opt] table callbacks unload = :(callbacks={}) - assert(@loaded == true, "level not loaded") + assert(@loaded == true, ("level %q not loaded"):format(@identifier)) let onRemoveLayer = callbacks.onRemoveLayer for _, l in ipairs(@layers) do l:_unloadCallbacks(callbacks) diff --git a/ldtk/ldtk.lua b/ldtk/ldtk.lua index 644513d..375e167 100644 --- a/ldtk/ldtk.lua +++ b/ldtk/ldtk.lua @@ -353,7 +353,7 @@ level_mt = { -- ./ldtk/ldtk.can:525 ["draw"] = function(self, x, y) -- ./ldtk/ldtk.can:536 if x == nil then x = 0 end -- ./ldtk/ldtk.can:536 if y == nil then y = 0 end -- ./ldtk/ldtk.can:536 -assert(self["loaded"] == true, "level not loaded") -- ./ldtk/ldtk.can:537 +assert(self["loaded"] == true, ("level %q not loaded"):format(self["identifier"])) -- ./ldtk/ldtk.can:537 lg["push"]() -- ./ldtk/ldtk.can:538 lg["translate"](x + self["x"], y + self["y"]) -- ./ldtk/ldtk.can:539 self:drawBackground() -- ./ldtk/ldtk.can:540 @@ -365,7 +365,7 @@ end, -- ./ldtk/ldtk.can:545 ["drawBackground"] = function(self, x, y) -- ./ldtk/ldtk.can:556 if x == nil then x = 0 end -- ./ldtk/ldtk.can:556 if y == nil then y = 0 end -- ./ldtk/ldtk.can:556 -assert(self["loaded"] == true, "level not loaded") -- ./ldtk/ldtk.can:557 +assert(self["loaded"] == true, ("level %q not loaded"):format(self["identifier"])) -- ./ldtk/ldtk.can:557 lg["setColor"](self["background"]["color"]) -- ./ldtk/ldtk.can:559 lg["rectangle"]("fill", x, y, self["width"], self["height"]) -- ./ldtk/ldtk.can:560 lg["setColor"](white) -- ./ldtk/ldtk.can:562 @@ -377,7 +377,7 @@ end -- ./ldtk/ldtk.can:565 end, -- ./ldtk/ldtk.can:565 ["load"] = function(self, callbacks) -- ./ldtk/ldtk.can:583 if callbacks == nil then callbacks = {} end -- ./ldtk/ldtk.can:583 -assert(self["loaded"] == false, "level already loaded") -- ./ldtk/ldtk.can:584 +assert(self["loaded"] == false, ("level %q already loaded"):format(self["identifier"])) -- ./ldtk/ldtk.can:584 if self["_json"]["bgRelPath"] then -- ./ldtk/ldtk.can:585 local pos -- ./ldtk/ldtk.can:586 pos = self["_json"]["__bgPos"] -- ./ldtk/ldtk.can:586 @@ -415,7 +415,7 @@ self["loaded"] = true -- ./ldtk/ldtk.can:612 end, -- ./ldtk/ldtk.can:612 ["unload"] = function(self, callbacks) -- ./ldtk/ldtk.can:625 if callbacks == nil then callbacks = {} end -- ./ldtk/ldtk.can:625 -assert(self["loaded"] == true, "level not loaded") -- ./ldtk/ldtk.can:626 +assert(self["loaded"] == true, ("level %q not loaded"):format(self["identifier"])) -- ./ldtk/ldtk.can:626 local onRemoveLayer -- ./ldtk/ldtk.can:627 onRemoveLayer = callbacks["onRemoveLayer"] -- ./ldtk/ldtk.can:627 for _, l in ipairs(self["layers"]) do -- ./ldtk/ldtk.can:628 From d3f86d02755f7209eebc8616560de04629940672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Fri, 11 Jul 2025 15:11:55 +0200 Subject: [PATCH 3/4] util: clean table copy --- util/util.lua | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/util/util.lua b/util/util.lua index e611b5c..1b01f6a 100644 --- a/util/util.lua +++ b/util/util.lua @@ -189,14 +189,11 @@ util = { -- @treturn table the copied table copy = function(t, cache) if cache == nil then cache = {} end + if cache[t] then return cache[t] end local r = {} cache[t] = r for k, v in pairs(t) do - if type(v) == "table" then - r[k] = cache[v] or util.copy(v, cache) - else - r[k] = v - end + r[k] = type(v) == "table" and util.copy(v, cache) or v end return setmetatable(r, getmetatable(t)) end, From 8ca439591c491242759bf5ad61f924fd833d82aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Fri, 11 Jul 2025 15:12:26 +0200 Subject: [PATCH 4/4] input: tweak default deadzone --- input/input.lua | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/input/input.lua b/input/input.lua index aef5a98..38ab8f3 100644 --- a/input/input.lua +++ b/input/input.lua @@ -306,9 +306,9 @@ input_mt = { -- -- The deadzone for analog inputs (e.g. joystick axes): if the input absolute value is strictly below this, it will be considered as 0. 0.05 by default. -- -- This is applied automatically after the evaluation of input expressions. -- deadzone = 0.05, - -- -- The pressed threshold: an input is considered down if above or equal to this value. 0.05 by default. - -- -- This is considered when determining if the input is pressed, odwn and released. - -- threshold = 0.05, + -- -- The pressed threshold: an input is considered down if above or equal to this value. 0.1 by default. + -- -- This is considered when determining if the input is pressed, down and released. + -- threshold = 0.1, -- -- Dimension of the input (i.e. the number of values returned by this input). 1 by default. -- dimension = 1 -- } @@ -371,7 +371,7 @@ input_mt = { -- Cache computed directly from the input config. Recomputed by :reload(). _dimension = 1, -- Dimension of the input. _deadzone = 0.05, -- Deadzone of the input. - _threshold = 0.05, -- Threshold of the input. + _threshold = 0.1, -- Threshold of the input. --- Update the input and its children. -- Should be called every frame, typically _after_ you've done all your input handling @@ -425,7 +425,7 @@ input_mt = { -- get main options self._dimension = self.config.dimension or 1 self._deadzone = self.config.deadzone or 0.05 - self._threshold = self.config.threshold or 0.05 + self._threshold = self.config.threshold or 0.1 -- resize dimensions if #self._value > self._dimension then for i=self._dimension+1, #self._value do @@ -602,8 +602,10 @@ input_mt = { new = filter(self, new, ...) if not new then return end -- filtered out end - s.parentCache[s.lastKey] = new - self._afterFilterEvent:emit(sname, new) + if s.parentCache[s.lastKey] ~= new then -- filter out no-op events + s.parentCache[s.lastKey] = new + self._afterFilterEvent:emit(sname, new) + end end) end self._boundSourceEvents[sname] = true