mirror of
https://github.com/appgurueu/modlib.git
synced 2024-11-25 16:53:46 +01:00
Refactor texmod:calc_dims to use a dispatch table
This commit is contained in:
parent
9fc4aaf3b8
commit
b169077a40
@ -8,7 +8,7 @@ end
|
|||||||
local texmod, metatable = component"dsl"
|
local texmod, metatable = component"dsl"
|
||||||
texmod.write = component"write"
|
texmod.write = component"write"
|
||||||
texmod.read = component("read", texmod)
|
texmod.read = component("read", texmod)
|
||||||
texmod.calc_dims = component"calc_dims"
|
texmod.calc_dims = component("calc_dims", texmod)
|
||||||
|
|
||||||
function metatable:__tostring()
|
function metatable:__tostring()
|
||||||
local rope = {}
|
local rope = {}
|
||||||
|
@ -1,54 +1,77 @@
|
|||||||
-- TODO ensure completeness, use table of dim calculation functions
|
local texmod = ...
|
||||||
local base_dims = modlib.table.set({
|
|
||||||
"opacity",
|
local cd = {}
|
||||||
"invert",
|
|
||||||
"brighten",
|
local function calc_dims(self, get_file_dims)
|
||||||
"noalpha",
|
return assert(cd[self.type])(self, get_file_dims)
|
||||||
"makealpha",
|
|
||||||
"lowpart",
|
|
||||||
"mask",
|
|
||||||
"colorize",
|
|
||||||
})
|
|
||||||
local floor, max, clamp = math.floor, math.max, modlib.math.clamp
|
|
||||||
local function next_pow_of_2(x)
|
|
||||||
-- I don't want to use a naive 2^ceil(log(x)/log(2)) due to possible float precision issues.
|
|
||||||
local m, e = math.frexp(x) -- x = _*2^e, _ in [0.5, 1)
|
|
||||||
if m == 0.5 then e = e - 1 end -- x = 2^(e-1)
|
|
||||||
return math.ldexp(1, e) -- 2^e, premature optimization here we go
|
|
||||||
end
|
end
|
||||||
return function(self, get_file_dims)
|
|
||||||
local function calc_dims(self)
|
function cd:file(d)
|
||||||
local type = self.type
|
return d(self.filename)
|
||||||
if type == "filename" then
|
end
|
||||||
return get_file_dims(self.filename)
|
|
||||||
end if base_dims[type] then
|
do
|
||||||
return calc_dims(self.base)
|
local function base_dim(self, get_dims) return calc_dims(self.base, get_dims) end
|
||||||
end if type == "resize" or type == "combine" then
|
cd.opacity = base_dim
|
||||||
return self.w, self.h
|
cd.invert = base_dim
|
||||||
end if type == "overlay" then
|
cd.brighten = base_dim
|
||||||
local base_w, base_h = calc_dims(self.base)
|
cd.noalpha = base_dim
|
||||||
local overlay_w, overlay_h = calc_dims(self.over)
|
cd.makealpha = base_dim
|
||||||
return max(base_w, overlay_w), max(base_h, overlay_h)
|
cd.lowpart = base_dim
|
||||||
end if type == "transform" then
|
cd.mask = base_dim
|
||||||
if self.rotation_deg % 180 ~= 0 then
|
cd.colorize = base_dim
|
||||||
local base_w, base_h = calc_dims(self.base)
|
end
|
||||||
return base_h, base_w
|
|
||||||
end
|
do
|
||||||
return calc_dims(self.base)
|
local function wh(self) return self.w, self.h end
|
||||||
end if type == "inventorycube" then
|
cd.resize = wh
|
||||||
local top_w, top_h = calc_dims(self.top)
|
cd.combine = wh
|
||||||
local left_w, left_h = calc_dims(self.left)
|
end
|
||||||
local right_w, right_h = calc_dims(self.right)
|
|
||||||
local d = clamp(next_pow_of_2(max(top_w, top_h, left_w, left_h, right_w, right_h)), 2, 64)
|
function cd:overlay(get_dims)
|
||||||
return d, d
|
local base_w, base_h = calc_dims(self.base, get_dims)
|
||||||
end if type == "verticalframe" or type == "crack" or type == "cracko" then
|
local over_w, over_h = calc_dims(self.over, get_dims)
|
||||||
local base_w, base_h = calc_dims(self.base)
|
return math.max(base_w, over_w), math.max(base_h, over_h)
|
||||||
return base_w, floor(base_h / self.framecount)
|
end
|
||||||
end if type == "sheet" then
|
|
||||||
local base_w, base_h = calc_dims(self.base)
|
function cd:transform(get_dims)
|
||||||
return floor(base_w / self.w), floor(base_h / self.h)
|
if self.rotation_deg % 180 ~= 0 then
|
||||||
end
|
local base_w, base_h = calc_dims(self.base, get_dims)
|
||||||
error("unsupported texture modifier: " .. type)
|
return base_h, base_w
|
||||||
end
|
end
|
||||||
return calc_dims(self)
|
return calc_dims(self.base, get_dims)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local math_clamp = modlib.math.clamp
|
||||||
|
local function next_pow_of_2(x)
|
||||||
|
-- I don't want to use a naive 2^ceil(log(x)/log(2)) due to possible float precision issues.
|
||||||
|
local m, e = math.frexp(x) -- x = _*2^e, _ in [0.5, 1)
|
||||||
|
if m == 0.5 then e = e - 1 end -- x = 2^(e-1)
|
||||||
|
return math.ldexp(1, e) -- 2^e, premature optimization here we go
|
||||||
|
end
|
||||||
|
function cd:inventorycube(get_dims)
|
||||||
|
local top_w, top_h = calc_dims(self.top, get_dims)
|
||||||
|
local left_w, left_h = calc_dims(self.left, get_dims)
|
||||||
|
local right_w, right_h = calc_dims(self.right, get_dims)
|
||||||
|
local d = math_clamp(next_pow_of_2(math.max(top_w, top_h, left_w, left_h, right_w, right_h)), 2, 64)
|
||||||
|
return d, d
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local function frame_dims(self, get_dims)
|
||||||
|
local base_w, base_h = calc_dims(self.base, get_dims)
|
||||||
|
return base_w, math.floor(base_h / self.framecount)
|
||||||
|
end
|
||||||
|
cd.verticalframe = frame_dims
|
||||||
|
cd.crack = frame_dims
|
||||||
|
cd.cracko = frame_dims
|
||||||
|
end
|
||||||
|
|
||||||
|
function cd:sheet(get_dims)
|
||||||
|
local base_w, base_h = calc_dims(self.base, get_dims)
|
||||||
|
return math.floor(base_w / self.w), math.floor(base_h / self.h)
|
||||||
|
end
|
||||||
|
|
||||||
|
return calc_dims
|
@ -12,7 +12,7 @@ setmetatable(texmod, {__call = new})
|
|||||||
|
|
||||||
function texmod.file(filename)
|
function texmod.file(filename)
|
||||||
return new{
|
return new{
|
||||||
type = "filename",
|
type = "file",
|
||||||
filename = filename
|
filename = filename
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -143,7 +143,7 @@ return function(self, write_str)
|
|||||||
w.str(("%d"):format(int))
|
w.str(("%d"):format(int))
|
||||||
end
|
end
|
||||||
function w.tex(tex)
|
function w.tex(tex)
|
||||||
if tex.type == "filename" then
|
if tex.type == "file" then
|
||||||
assert(not tex.filename:find"[:^\\&{[]", "invalid character in filename")
|
assert(not tex.filename:find"[:^\\&{[]", "invalid character in filename")
|
||||||
w.str(tex.filename)
|
w.str(tex.filename)
|
||||||
return
|
return
|
||||||
@ -153,7 +153,7 @@ return function(self, write_str)
|
|||||||
w.hat()
|
w.hat()
|
||||||
end
|
end
|
||||||
if tex.type == "overlay" then
|
if tex.type == "overlay" then
|
||||||
if tex.over.type ~= "filename" then -- TODO also exclude [png, [combine and [inventorycube (generators)
|
if tex.over.type ~= "file" then -- TODO also exclude [png, [combine and [inventorycube (generators)
|
||||||
w.str"("; w.tex(tex.over); w.str")"
|
w.str"("; w.tex(tex.over); w.str")"
|
||||||
else
|
else
|
||||||
w.tex(tex.over)
|
w.tex(tex.over)
|
||||||
|
Loading…
Reference in New Issue
Block a user