Reactive Props V2 #71

Merged
thesabinelim merged 1 commits from reactive-props-2 into master 2023-05-13 23:16:54 +08:00
2 changed files with 34 additions and 61 deletions

View File

@@ -3,7 +3,6 @@ local sub,find,reverse,rep,insert,len = string.sub,string.find,string.reverse,st
local function splitString(str, delimiter)
local results = {}
local nResults = 1
if str == "" or delimiter == "" then
return results
end
@@ -11,12 +10,11 @@ local function splitString(str, delimiter)
local delim_start, delim_end = find(str, delimiter, start)
while delim_start do
insert(results, sub(str, start, delim_start - 1))
nResults = nResults + 1
start = delim_end + 1
delim_start, delim_end = find(str, delimiter, start)
end
insert(results, sub(str, start))
return results, nResults
return results
end
local function removeTags(input)

View File

@@ -167,7 +167,32 @@ local function registerFunctionEvent(self, data, event, renderContext)
end
end
local potentialObservers = {}
return {
basalt = function()
local object = {
reactive = function(initialValue)
local internalValue = initialValue
local observers = {}
local getter = function()
if (potentialObservers ~= nil) then
table.insert(observers, potentialObservers[#potentialObservers])
end
return internalValue
end
local setter = function(value)
internalValue = value
for _, updateFn in ipairs(observers) do
updateFn(internalValue)
end
end
return getter, setter
end
}
return object
end,
VisualObject = function(base, basalt)
local object = {
@@ -201,28 +226,14 @@ return {
setValuesByXMLData = function(self, data, renderContext)
renderContext.env[self:getName()] = self
for k,v in pairs(data:reactiveProperties()) do
local parts, nParts = utils.splitString(v, "%.")
if (nParts ~= 2) then
return
end
local tableName = parts[1]
local entryName = parts[2]
if (tableName == "props") then
self:updateValue(k, renderContext.env.props[entryName])
elseif (tableName == "shared") then
self:updateValue(k, renderContext.env.shared[entryName])
local sharedObservers = renderContext.sharedObservers
if (sharedObservers[entryName]) == nil then
sharedObservers[entryName] = {}
end
table.insert(
sharedObservers[entryName],
function(val)
self:updateValue(k, val)
end
)
for prop, expression in pairs(data:reactiveProperties()) do
local update = function()
local value = load("return " .. expression, nil, "t", renderContext.env)()
self:updateValue(prop, value)
end
table.insert(potentialObservers, update)
update()
table.remove(potentialObservers)
end
self:updateSpecifiedValuesByXMLData(data, {
@@ -334,26 +345,9 @@ return {
loadLayout = function(self, path, props)
if(fs.exists(path))then
local renderContext = {}
renderContext.potentialObservers = {}
renderContext.env = _ENV
renderContext.env.basalt = basalt
renderContext.env.props = props
renderContext.env.shared = {}
renderContext.sharedObservers = {}
local shared = {}
setmetatable(renderContext.env.shared, {
__index = function(_, k)
return shared[k]
end,
__newindex = function(_, k, v)
local observers = renderContext.sharedObservers[k]
if observers ~= nil then
for _,observer in pairs(observers) do
observer(v)
end
end
shared[k] = v
end
})
local f = fs.open(path, "r")
local data = XmlParser:ParseXmlText(f.readAll())
f.close()
@@ -434,26 +428,7 @@ return {
if(fs.exists(path))then
local renderContext = {}
renderContext.env = _ENV
renderContext.env.basalt = basalt
renderContext.env.main = self
renderContext.env.props = props
renderContext.env.shared = {}
renderContext.sharedObservers = {}
local shared = {}
setmetatable(renderContext.env.shared, {
__index = function(_, k)
return shared[k]
end,
__newindex = function(_, k, v)
local observers = renderContext.sharedObservers[k]
if observers ~= nil then
for _,observer in pairs(observers) do
observer(v)
end
end
shared[k] = v
end
})
local f = fs.open(path, "r")
local data = XmlParser:ParseXmlText(f.readAll())
f.close()