diff --git a/Basalt/libraries/utils.lua b/Basalt/libraries/utils.lua index f998686..4fc0812 100644 --- a/Basalt/libraries/utils.lua +++ b/Basalt/libraries/utils.lua @@ -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) diff --git a/Basalt/plugins/xml.lua b/Basalt/plugins/xml.lua index 4afa123..83500a1 100644 --- a/Basalt/plugins/xml.lua +++ b/Basalt/plugins/xml.lua @@ -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()