Implement effects
This commit is contained in:
@@ -167,27 +167,56 @@ local function registerFunctionEvent(self, data, event, renderContext)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local potentialObservers = {}
|
local clearEffectDependencies = function(effect)
|
||||||
|
for _, dependency in ipairs(effect.dependencies) do
|
||||||
|
for index, backlink in ipairs(dependency) do
|
||||||
|
if (backlink == effect) then
|
||||||
|
table.remove(dependency, index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
effect.dependencies = {};
|
||||||
|
end
|
||||||
|
|
||||||
|
local effectStack = {}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
basalt = function()
|
basalt = function()
|
||||||
local object = {
|
local object = {
|
||||||
reactive = function(initialValue)
|
reactive = function(initialValue)
|
||||||
local internalValue = initialValue
|
local value = initialValue
|
||||||
local observers = {}
|
local observerEffects = {}
|
||||||
local getter = function()
|
local getter = function()
|
||||||
if (potentialObservers ~= nil) then
|
local invokingEffect = effectStack[#effectStack]
|
||||||
table.insert(observers, potentialObservers[#potentialObservers])
|
if (invokingEffect ~= nil) then
|
||||||
|
table.insert(observerEffects, invokingEffect)
|
||||||
|
table.insert(invokingEffect.dependencies, observerEffects)
|
||||||
end
|
end
|
||||||
return internalValue
|
return value
|
||||||
end
|
end
|
||||||
local setter = function(value)
|
local setter = function(newValue)
|
||||||
internalValue = value
|
value = newValue
|
||||||
for _, updateFn in ipairs(observers) do
|
local observerEffectsCopy = {}
|
||||||
updateFn(internalValue)
|
for index, effect in ipairs(observerEffects) do
|
||||||
|
observerEffectsCopy[index] = effect
|
||||||
|
end
|
||||||
|
for _, effect in ipairs(observerEffectsCopy) do
|
||||||
|
effect.execute()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return getter, setter
|
return getter, setter
|
||||||
|
end,
|
||||||
|
|
||||||
|
effect = function(effectFn)
|
||||||
|
local effect = {dependencies = {}}
|
||||||
|
local execute = function()
|
||||||
|
clearEffectDependencies(effect)
|
||||||
|
table.insert(effectStack, effect)
|
||||||
|
effectFn()
|
||||||
|
table.remove(effectStack)
|
||||||
|
end
|
||||||
|
effect.execute = execute
|
||||||
|
effect.execute()
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
return object
|
return object
|
||||||
@@ -231,9 +260,7 @@ return {
|
|||||||
local value = load("return " .. expression, nil, "t", renderContext.env)()
|
local value = load("return " .. expression, nil, "t", renderContext.env)()
|
||||||
self:updateValue(prop, value)
|
self:updateValue(prop, value)
|
||||||
end
|
end
|
||||||
table.insert(potentialObservers, update)
|
basalt.effect(update)
|
||||||
update()
|
|
||||||
table.remove(potentialObservers)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self:updateSpecifiedValuesByXMLData(data, {
|
self:updateSpecifiedValuesByXMLData(data, {
|
||||||
@@ -345,7 +372,6 @@ return {
|
|||||||
loadLayout = function(self, path, props)
|
loadLayout = function(self, path, props)
|
||||||
if(fs.exists(path))then
|
if(fs.exists(path))then
|
||||||
local renderContext = {}
|
local renderContext = {}
|
||||||
renderContext.potentialObservers = {}
|
|
||||||
renderContext.env = _ENV
|
renderContext.env = _ENV
|
||||||
renderContext.env.props = props
|
renderContext.env.props = props
|
||||||
local f = fs.open(path, "r")
|
local f = fs.open(path, "r")
|
||||||
@@ -475,6 +501,7 @@ return {
|
|||||||
Button = function(base, basalt)
|
Button = function(base, basalt)
|
||||||
local object = {
|
local object = {
|
||||||
updateValue = function(self, name, value)
|
updateValue = function(self, name, value)
|
||||||
|
basalt.log("Updating value, " .. name .. " = " .. value)
|
||||||
if (value == nil) then return end
|
if (value == nil) then return end
|
||||||
base.updateValue(self, name, value)
|
base.updateValue(self, name, value)
|
||||||
if (name == "text") then
|
if (name == "text") then
|
||||||
|
|||||||
Reference in New Issue
Block a user