77 lines
2.1 KiB
Lua
77 lines
2.1 KiB
Lua
--- Объект, который отвечает за работу с элементами интерфейса одного экрана
|
||
--- @class UIBuilder
|
||
--- @field private _cache UIElement[]
|
||
--- @field elementTree UIElement
|
||
local builder = {}
|
||
builder.__index = builder
|
||
|
||
--- @return UIBuilder
|
||
local function new(from)
|
||
from._cache = {}
|
||
|
||
setmetatable(from, builder)
|
||
return from
|
||
end
|
||
|
||
--- @param element? UIElement
|
||
--- @private
|
||
function builder:_get(element)
|
||
if not element then return nil end
|
||
|
||
local key = builder:_makeKey(element)
|
||
if not key then return element end
|
||
|
||
local cached = self._cache[key]
|
||
if cached then return cached end
|
||
|
||
self._cache[key] = element
|
||
return element
|
||
end
|
||
|
||
--- @param element UIElement
|
||
--- @private
|
||
function builder:_makeKey(element)
|
||
if not element.key then return nil end
|
||
if type(element.key) == "string" then return element.key end
|
||
element.key = element.type .. "<" .. tostring(element.key) .. ">"
|
||
return element.key
|
||
end
|
||
|
||
--- @private
|
||
function builder:build_step(cur)
|
||
if not cur then return end
|
||
if cur.build then
|
||
cur.child = self:_get(cur:build())
|
||
self:build_step(cur.child)
|
||
elseif cur.children then
|
||
for _, child in ipairs(cur.children) do
|
||
self:build_step(self:_get(child))
|
||
end
|
||
else
|
||
cur.child = self:_get(cur.child)
|
||
self:build_step(cur.child)
|
||
end
|
||
end
|
||
|
||
--- Этот метод раскрывает всех отложенных (через build) детей в дереве и хитро их кэширует, чтобы не перестраивались постоянно
|
||
---
|
||
--- Благодаря этому можно каждый раз создавать новые элементы в верстке, а получать старые :)
|
||
function builder:build()
|
||
local root = self:_get(self.elementTree)
|
||
self:build_step(root)
|
||
end
|
||
|
||
function builder:layout()
|
||
self.elementTree:layout()
|
||
end
|
||
|
||
function builder:update(dt)
|
||
self.elementTree:update(dt)
|
||
end
|
||
|
||
function builder:draw()
|
||
self.elementTree:draw()
|
||
end
|
||
|
||
return new
|