mirror of
https://github.com/Reuh/ubiquitousse.git
synced 2025-10-27 17:19:31 +00:00
Code reorganization, added uqt.ecs, removed LÖVE duplicates (uqt.audio, uqt.draw, uqt.filesystem)
This commit is contained in:
parent
523c5d36c0
commit
16e533d176
28 changed files with 2544 additions and 2107 deletions
336
util/util.lua
Normal file
336
util/util.lua
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
--- ubiquitousse.util
|
||||
-- No dependency.
|
||||
|
||||
--- Various functions useful for game developement.
|
||||
local util, group_mt
|
||||
util = {
|
||||
-------------------
|
||||
--- Basic maths ---
|
||||
-------------------
|
||||
|
||||
--- AABB collision check.
|
||||
-- @tparam number x1 first rectangle top-left x coordinate
|
||||
-- @tparam number y1 first rectangle top-left y coordinate
|
||||
-- @tparam number w1 first rectangle width
|
||||
-- @tparam number h1 first rectangle height
|
||||
-- @tparam number x2 second rectangle top-left x coordinate
|
||||
-- @tparam number y2 second rectangle top-left y coordinate
|
||||
-- @tparam number w2 second rectangle width
|
||||
-- @tparam number h2 second rectangle height
|
||||
-- @treturn true if the objects collide, false otherwise
|
||||
aabb = function(x1, y1, w1, h1, x2, y2, w2, h2)
|
||||
if w1 < 0 then x1 = x1 + w1; w1 = -w1 end
|
||||
if h1 < 0 then y1 = y1 + h1; h1 = -h1 end
|
||||
if w2 < 0 then x2 = x2 + w2; w2 = -w2 end
|
||||
if h2 < 0 then y2 = y2 + h2; h2 = -h2 end
|
||||
return x1 + w1 >= x2 and x1 <= x2 + w2 and
|
||||
y1 + h1 >= y2 and y1 <= y2 + h2
|
||||
end,
|
||||
|
||||
-----------------------
|
||||
--- List operations ---
|
||||
-----------------------
|
||||
|
||||
--- Remove the first occurence of an element in a list.
|
||||
-- @tparam table t the list
|
||||
-- @param x the element to remove
|
||||
-- @tparam[opt=#t] number n the number of expected elements in the list, including nil values
|
||||
-- @return x
|
||||
remove = function(t, x, n)
|
||||
n = n or #t
|
||||
for i=1, n do
|
||||
if t[i] == x then
|
||||
table.remove(t, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
return x
|
||||
end,
|
||||
|
||||
--- Extract the list of elements with a specific key from a list of tables
|
||||
-- @tparam table t the list of tables
|
||||
-- @param k the chosen key
|
||||
-- @tparam[opt=#t] number n the number of expected elements in the list, including nil values
|
||||
-- @treturn the extracted table
|
||||
extract = function(t, k, n)
|
||||
n = n or #t
|
||||
local r = {}
|
||||
for i=1, n do
|
||||
r[i] = t[i][k]
|
||||
end
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Applies a function to every item in list t.
|
||||
-- The function receive two argument: the value and then the key.
|
||||
-- @tparam table t initial list
|
||||
-- @tparam function fn the function to apply
|
||||
-- @tparam[opt=#t] number n the number of expected elements in the list, including nil values
|
||||
-- @treturn table the initial list
|
||||
each = function(t, fn, n)
|
||||
n = n or #t
|
||||
for i=1, n do
|
||||
fn(t[i], i)
|
||||
end
|
||||
return t
|
||||
end,
|
||||
|
||||
--- Applies a function to every item in list t and returns the associated new list.
|
||||
-- The function receive two argument: the value and then the key.
|
||||
-- @tparam table t initial list
|
||||
-- @tparam function fn the function to apply
|
||||
-- @tparam[opt=#t] number n the number of expected elements in the list, including nil values
|
||||
-- @treturn table the new list
|
||||
map = function(t, fn, n)
|
||||
n = n or #t
|
||||
local r = {}
|
||||
for i=1, n do
|
||||
r[i] = fn(t[i], i)
|
||||
end
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Test if all the values in the list are true. Optionnaly applies a function to get the truthness.
|
||||
-- The function receive two argument: the value and then the key.
|
||||
-- @tparam table t initial list
|
||||
-- @tparam function fn the function to apply
|
||||
-- @tparam[opt=#t] number n the number of expected elements in the list, including nil values
|
||||
-- @treturn boolean result
|
||||
all = function(t, fn, n)
|
||||
n = n or #t
|
||||
fn = fn or function(v) return v end
|
||||
local r = true
|
||||
for i=1, n do
|
||||
r = r and fn(t[i], i)
|
||||
end
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Test if at least one value in the list is true. Optionnaly applies a function to get the truthness.
|
||||
-- The function receive two argument: the value and then the key.
|
||||
-- @tparam table t initial list
|
||||
-- @tparam function fn the function to apply
|
||||
-- @tparam[opt=#t] number n the number of expected elements in the list, including nil values
|
||||
-- @treturn boolean result
|
||||
any = function(t, fn, n)
|
||||
n = n or #t
|
||||
fn = fn or function(v) return v end
|
||||
for i=1, n do
|
||||
if fn(t[i], i) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
-----------------------------
|
||||
--- Dictionary operations ---
|
||||
-----------------------------
|
||||
|
||||
--- Returns a new table where the keys and values have been inverted.
|
||||
-- @tparam table t the table
|
||||
-- @treturn table the inverted table
|
||||
invert = function(t)
|
||||
local r = {}
|
||||
for k, v in pairs(t) do
|
||||
r[v] = k
|
||||
end
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Perform a deep copy of a table.
|
||||
-- The copied table will keep the share the same metatable as the original table.
|
||||
-- Note this uses pairs() to perform the copy, which will honor the __pairs methamethod if present.
|
||||
-- @tparam table t the table
|
||||
-- @treturn table the copied table
|
||||
copy = function(t, cache)
|
||||
if cache == nil then cache = {} 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
|
||||
end
|
||||
return setmetatable(r, getmetatable(t))
|
||||
end,
|
||||
|
||||
-----------------------
|
||||
--- Random and UUID ---
|
||||
-----------------------
|
||||
|
||||
--- Generate a UUID v4.
|
||||
-- @treturn string the UUID in its canonical representation
|
||||
uuid4 = function()
|
||||
return ("xxxxxxxx-xxxx-4xxx-Nxxx-xxxxxxxxxxxx") -- version 4
|
||||
:gsub("N", math.random(0x8, 0xb)) -- variant 1
|
||||
:gsub("x", function() return ("%x"):format(math.random(0x0, 0xf)) end) -- random hexadecimal digit
|
||||
end,
|
||||
|
||||
-----------------------
|
||||
--- Object grouping ---
|
||||
-----------------------
|
||||
|
||||
--- Groups objects in a meta-object-proxy-thingy.
|
||||
-- Works great with Lua 5.2+. LuaJit requires to be built with Lua 5.2 compatibility enabled to support group comparaison.
|
||||
-- @tparam table list of objects
|
||||
-- @tparam[opt=#t] number n the number of expected elements in the list, including nil values
|
||||
-- @tparam[opt=nil] table p list of parents. Used to find the first arguments of method calls.
|
||||
-- @treturn group object
|
||||
group = function(t, n, p)
|
||||
n = n or #t
|
||||
return setmetatable({ _n = n, _t = t, _p = p or false }, group_mt)
|
||||
end
|
||||
}
|
||||
|
||||
group_mt = {
|
||||
--- Everything but comparaison: returns a new group
|
||||
__add = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.group(util.map(self._t, function(v, i) return v + other._t[i] end, self._n), self._n)
|
||||
else
|
||||
return util.group(util.map(other._t, function(v) return self + v end, self._n), self._n)
|
||||
end
|
||||
else
|
||||
return util.group(util.map(self._t, function(v) return v + other end, self._n), self._n)
|
||||
end
|
||||
end,
|
||||
__sub = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.group(util.map(self._t, function(v, i) return v - other._t[i] end, self._n), self._n)
|
||||
else
|
||||
return util.group(util.map(other._t, function(v) return self - v end, self._n), self._n)
|
||||
end
|
||||
else
|
||||
return util.group(util.map(self._t, function(v) return v - other end, self._n), self._n)
|
||||
end
|
||||
end,
|
||||
__mul = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.group(util.map(self._t, function(v, i) return v * other._t[i] end, self._n), self._n)
|
||||
else
|
||||
return util.group(util.map(other._t, function(v) return self * v end, self._n), self._n)
|
||||
end
|
||||
else
|
||||
return util.group(util.map(self._t, function(v) return v * other end, self._n), self._n)
|
||||
end
|
||||
end,
|
||||
__div = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.group(util.map(self._t, function(v, i) return v / other._t[i] end, self._n), self._n)
|
||||
else
|
||||
return util.group(util.map(other._t, function(v) return self / v end, self._n), self._n)
|
||||
end
|
||||
else
|
||||
return util.group(util.map(self._t, function(v) return v / other end, self._n), self._n)
|
||||
end
|
||||
end,
|
||||
__mod = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.group(util.map(self._t, function(v, i) return v % other._t[i] end, self._n), self._n)
|
||||
else
|
||||
return util.group(util.map(other._t, function(v) return self % v end, self._n), self._n)
|
||||
end
|
||||
else
|
||||
return util.group(util.map(self._t, function(v) return v % other end, self._n), self._n)
|
||||
end
|
||||
end,
|
||||
__pow = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.group(util.map(self._t, function(v, i) return v ^ other._t[i] end, self._n), self._n)
|
||||
else
|
||||
return util.group(util.map(other._t, function(v) return self ^ v end, self._n), self._n)
|
||||
end
|
||||
else
|
||||
return util.group(util.map(self._t, function(v) return v ^ other end, self._n), self._n)
|
||||
end
|
||||
end,
|
||||
__unm = function(self)
|
||||
return util.group(util.map(self._t, function(v) return -v end, self._n), self._n)
|
||||
end,
|
||||
__concat = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.group(util.map(self._t, function(v, i) return v .. other._t[i] end, self._n), self._n)
|
||||
else
|
||||
return util.group(util.map(other._t, function(v) return self .. v end, self._n), self._n)
|
||||
end
|
||||
else
|
||||
return util.group(util.map(self._t, function(v) return v .. other end, self._n), self._n)
|
||||
end
|
||||
end,
|
||||
__len = function(self)
|
||||
return util.group(util.map(self._t, function(v) return #v end, self._n), self._n)
|
||||
end,
|
||||
__index = function(self, k)
|
||||
return util.group(util.extract(self._t, k, self._n), self._n, self._t)
|
||||
end,
|
||||
|
||||
--- Comparaison: returns true if true for every object of the group
|
||||
__eq = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.all(self._t, function(v, i) return v == other._t[i] end, self._n)
|
||||
else
|
||||
return util.all(other._t, function(v) return self == v end, self._n)
|
||||
end
|
||||
else
|
||||
return util.all(self._t, function(v) return v == other end, self._n)
|
||||
end
|
||||
end,
|
||||
__lt = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.all(self._t, function(v, i) return v < other._t[i] end, self._n)
|
||||
else
|
||||
return util.all(other._t, function(v) return self < v end, self._n)
|
||||
end
|
||||
else
|
||||
return util.all(self._t, function(v) return v < other end, self._n)
|
||||
end
|
||||
end,
|
||||
__le = function(self, other)
|
||||
if getmetatable(other) == group_mt then
|
||||
if getmetatable(self) == group_mt then
|
||||
return util.all(self._t, function(v, i) return v <= other._t[i] end, self._n)
|
||||
else
|
||||
return util.all(other._t, function(v) return self <= v end, self._n)
|
||||
end
|
||||
else
|
||||
return util.all(self._t, function(v) return v <= other end, self._n)
|
||||
end
|
||||
end,
|
||||
|
||||
--- Special cases
|
||||
__newindex = function(self, k, v)
|
||||
if getmetatable(v) == group_mt then -- unpack
|
||||
util.each(self._t, function(t, i) t[k] = v._t[i] end, self._n)
|
||||
else
|
||||
util.each(self._t, function(t) t[k] = v end, self._n)
|
||||
end
|
||||
end,
|
||||
__call = function(self, selfArg, ...)
|
||||
if getmetatable(selfArg) == group_mt and self._p then -- method call
|
||||
local a = {...}
|
||||
return util.group(util.map(self._t, function(v, i) return v(self._p[i], unpack(a)) end, self._n), self._n)
|
||||
else
|
||||
local a = {selfArg, ...}
|
||||
return util.group(util.map(self._t, function(v) return v(unpack(a)) end, self._n), self._n)
|
||||
end
|
||||
end,
|
||||
|
||||
--- Full-blown debugger
|
||||
__tostring = function(self)
|
||||
return ("group{%s}"):format(table.concat(util.map(self._t, tostring, self._n), ", "))
|
||||
end
|
||||
}
|
||||
|
||||
return util
|
||||
Loading…
Add table
Add a link
Reference in a new issue