implement StatefulElement
This commit is contained in:
parent
0e8181baf3
commit
fdff65d94d
@ -3,12 +3,14 @@ local Element = require "lib.simple_ui.core.element"
|
|||||||
--- Объект, который отвечает за работу с элементами интерфейса одного экрана
|
--- Объект, который отвечает за работу с элементами интерфейса одного экрана
|
||||||
--- @class UIBuilder
|
--- @class UIBuilder
|
||||||
--- @field builder fun(): UIElement
|
--- @field builder fun(): UIElement
|
||||||
|
--- @field private states {string: table}
|
||||||
--- @field private elementTree UIElement
|
--- @field private elementTree UIElement
|
||||||
local builder = {}
|
local builder = {}
|
||||||
builder.__index = builder
|
builder.__index = builder
|
||||||
|
|
||||||
--- @return UIBuilder
|
--- @return UIBuilder
|
||||||
local function new(from)
|
local function new(from)
|
||||||
|
from.states = {}
|
||||||
setmetatable(from, builder)
|
setmetatable(from, builder)
|
||||||
return from
|
return from
|
||||||
end
|
end
|
||||||
@ -36,7 +38,19 @@ end
|
|||||||
--- @private
|
--- @private
|
||||||
function builder:build_step(cur)
|
function builder:build_step(cur)
|
||||||
-- Самоприсваивания должны вырезаться компилятором, я в это верю
|
-- Самоприсваивания должны вырезаться компилятором, я в это верю
|
||||||
cur = cur --[[@as SingleChildElement | MultiChildElement]]
|
cur = cur --[[@as SingleChildElement | StatefulElement | MultiChildElement]]
|
||||||
|
|
||||||
|
local key = self:makeKey(cur)
|
||||||
|
if key then
|
||||||
|
cur = cur --[[@as StatefulElement]]
|
||||||
|
local storedState = self.states[key]
|
||||||
|
if not storedState then
|
||||||
|
self.states[key] = cur.state
|
||||||
|
else
|
||||||
|
cur.state = storedState
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local buildRes = cur:build()
|
local buildRes = cur:build()
|
||||||
if not buildRes then return end
|
if not buildRes then return end
|
||||||
|
|
||||||
|
|||||||
@ -24,12 +24,6 @@ function element:update(dt) end
|
|||||||
|
|
||||||
function element:draw() end
|
function element:draw() end
|
||||||
|
|
||||||
--- @param values {[string]: any}
|
|
||||||
--- @return UIElement
|
|
||||||
function element:new(values)
|
|
||||||
return setmetatable(values, self)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Рекурсивно обходит дерево элементов вверх, начиная с первого родителя.
|
--- Рекурсивно обходит дерево элементов вверх, начиная с первого родителя.
|
||||||
---
|
---
|
||||||
--- К каждому посещенному элементу применяет функцию visitor.
|
--- К каждому посещенному элементу применяет функцию visitor.
|
||||||
@ -42,4 +36,10 @@ function element:traverseUp(visitor)
|
|||||||
return self._parent_:traverseUp(visitor)
|
return self._parent_:traverseUp(visitor)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param values {[string]: any}
|
||||||
|
--- @return UIElement
|
||||||
|
function element:new(values)
|
||||||
|
return setmetatable(values, self)
|
||||||
|
end
|
||||||
|
|
||||||
return element
|
return element
|
||||||
|
|||||||
17
lib/simple_ui/core/stateful_element.lua
Normal file
17
lib/simple_ui/core/stateful_element.lua
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
local SingleChildElement = require "lib.simple_ui.core.single_child_element"
|
||||||
|
|
||||||
|
--- @generic T : table
|
||||||
|
--- @class StatefulElement<T> : SingleChildElement
|
||||||
|
--- @field state T
|
||||||
|
local element = setmetatable({}, SingleChildElement)
|
||||||
|
element.__index = element
|
||||||
|
element.type = "StatefulElement"
|
||||||
|
element.state = {}
|
||||||
|
|
||||||
|
--- @return StatefulElement<T>
|
||||||
|
--- @param values {key: any, state: T?, child: UIElement?}
|
||||||
|
function element:new(values)
|
||||||
|
return SingleChildElement.new(self, values)
|
||||||
|
end
|
||||||
|
|
||||||
|
return element
|
||||||
@ -5,28 +5,23 @@ local Builder = require "lib.simple_ui.core.builder"
|
|||||||
local Flex = require "lib.simple_ui.elements.flex"
|
local Flex = require "lib.simple_ui.elements.flex"
|
||||||
local Center = require "lib.simple_ui.elements.center"
|
local Center = require "lib.simple_ui.elements.center"
|
||||||
local SizedBox = require "lib.simple_ui.elements.sized_box"
|
local SizedBox = require "lib.simple_ui.elements.sized_box"
|
||||||
local SingleChildElement = require "lib.simple_ui.core.single_child_element"
|
local StatefulElement = require "lib.simple_ui.core.stateful_element"
|
||||||
|
|
||||||
|
|
||||||
local MyWidget = setmetatable({}, SingleChildElement)
|
local MyWidget = setmetatable({}, StatefulElement)
|
||||||
MyWidget.__index = MyWidget
|
MyWidget.__index = MyWidget
|
||||||
MyWidget.type = "MyWidget"
|
MyWidget.type = "MyWidget"
|
||||||
|
|
||||||
local Canary = setmetatable({}, SingleChildElement)
|
local Canary = setmetatable({}, StatefulElement)
|
||||||
Canary.__index = Canary
|
Canary.__index = Canary
|
||||||
Canary.type = "Canary"
|
Canary.type = "Canary"
|
||||||
|
|
||||||
local reported = false
|
--- @class CanaryState
|
||||||
|
Canary.state = { i = 0 }
|
||||||
|
|
||||||
function Canary:build()
|
function Canary:build()
|
||||||
-- self.i = self.i and self.i + 1 or 0
|
self.state.i = self.state.i and self.state.i + 1 or 0
|
||||||
-- print(self.i)
|
print(self.state.i)
|
||||||
if not reported then
|
|
||||||
self:traverseUp(function(element)
|
|
||||||
print(element.type)
|
|
||||||
return true
|
|
||||||
end)
|
|
||||||
reported = true
|
|
||||||
end
|
|
||||||
|
|
||||||
return Placeholder:new {}
|
return Placeholder:new {}
|
||||||
end
|
end
|
||||||
@ -56,11 +51,20 @@ function MyWidget:build()
|
|||||||
child = Placeholder:new {}
|
child = Placeholder:new {}
|
||||||
},
|
},
|
||||||
SizedBox:new {
|
SizedBox:new {
|
||||||
key = "mybox",
|
|
||||||
width = 100,
|
width = 100,
|
||||||
height = 100,
|
height = 100,
|
||||||
child = Canary:new {
|
child = Canary:new {
|
||||||
i = 0
|
key = "canary1",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
SizedBox:new {
|
||||||
|
width = 100,
|
||||||
|
height = 100,
|
||||||
|
child = Canary:new {
|
||||||
|
key = "canary2",
|
||||||
|
state = {
|
||||||
|
i = 100
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user