local Element = require "lib.simple_ui.core.element" --- Объект, который отвечает за работу с элементами интерфейса одного экрана --- @class UIBuilder --- @field private _cache UIElement[] --- @field elementTree UIElement --- @field private shadowTree UIElement local builder = {} builder.__index = builder --- @return UIBuilder local function new(from) from._cache = {} from.shadowTree = Element:new {} 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 newNode UIElement? --- @param oldNode UIElement? --- @private function builder:didChange(newNode, oldNode) if not oldNode or not newNode then return true end if oldNode.type ~= newNode.type then return true end if oldNode.key ~= newNode.key then return true end return false 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 --- @param cur UIElement --- @private function builder:build_step(cur) cur = cur --[[@as SingleChildElement | MultiChildElement]] if cur.build then cur = cur --[[@as SingleChildElement]] local child = cur:build() if not child then return end -- local oldChild = cur._child_ -- if oldChild then -- for key, value in pairs(oldChild) do -- if (not Element[key]) then child[key] = value end -- end -- end cur._child_ = child child._parent_ = cur self:build_step(cur._child_) elseif cur.children then cur = cur --[[@as MultiChildElement]] for _, child in ipairs(cur.children) do child._parent_ = cur self:build_step(child) end end end --- Этот метод раскрывает всех отложенных (через build) детей в дереве и хитро их кэширует, чтобы не перестраивались постоянно --- --- Благодаря этому можно каждый раз создавать новые элементы в верстке, а получать старые :) function builder:build() local root = 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