mirror of
https://github.com/littensy/charm.git
synced 2026-10-20 17:51:37 +00:00
fix: allow dispose in observers
This commit is contained in:
parent
d890f4fc2c
commit
fdc598f6e6
2 changed files with 53 additions and 4 deletions
|
|
@ -132,4 +132,40 @@ test("should handle self removal", function()
|
||||||
assert(table.concat(edits) == "+1+2+3+4-1-2-3-4", `bad edits: {table.concat(edits)}`)
|
assert(table.concat(edits) == "+1+2+3+4-1-2-3-4", `bad edits: {table.concat(edits)}`)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
test("should allow disposal during addition", function()
|
||||||
|
local items, setItems = signal({})
|
||||||
|
local edits = {}
|
||||||
|
local dispose
|
||||||
|
|
||||||
|
dispose = observe(items, function(item)
|
||||||
|
if item == 1 then
|
||||||
|
dispose()
|
||||||
|
end
|
||||||
|
table.insert(edits, `+{item}`)
|
||||||
|
return function()
|
||||||
|
table.insert(edits, `-{item}`)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
setItems({ 1, 2, 3, 4 })
|
||||||
|
assert(table.concat(edits) == "+1-1", `bad edits: {table.concat(edits)}`)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("should allow disposal during removal", function()
|
||||||
|
local items, setItems = signal({ 1, 2, 3, 4 })
|
||||||
|
local edits = {}
|
||||||
|
local dispose
|
||||||
|
|
||||||
|
dispose = observe(items, function(item)
|
||||||
|
table.insert(edits, `+{item}`)
|
||||||
|
return function()
|
||||||
|
dispose()
|
||||||
|
table.insert(edits, `-{item}`)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
setItems({ 1, 2, 3, nil :: any, 5 })
|
||||||
|
assert(table.concat(edits) == "+1+2+3+4-1-2-3-4", `bad edits: {table.concat(edits)}`)
|
||||||
|
end)
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,16 @@ local recursive = core.recursive
|
||||||
--- @see https://github.com/littensy/charm?tab=readme-ov-file#observegetter-callback
|
--- @see https://github.com/littensy/charm?tab=readme-ov-file#observegetter-callback
|
||||||
local function observe<K, V>(getter: () -> { [K]: V }, callback: (item: V, key: K) -> ...(() -> ())?): () -> ()
|
local function observe<K, V>(getter: () -> { [K]: V }, callback: (item: V, key: K) -> ...(() -> ())?): () -> ()
|
||||||
local innerScopes: { [K]: () -> () } = {}
|
local innerScopes: { [K]: () -> () } = {}
|
||||||
|
local disposed = false
|
||||||
|
|
||||||
local function updateScopes(data: { [K]: V })
|
local function updateScopes(data: { [K]: V })
|
||||||
for key, dispose in innerScopes do
|
for key, dispose in innerScopes do
|
||||||
if data[key] == nil then
|
if data[key] == nil then
|
||||||
innerScopes[key] = nil
|
innerScopes[key] = nil
|
||||||
dispose()
|
dispose()
|
||||||
|
if disposed then
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -32,9 +36,15 @@ local function observe<K, V>(getter: () -> { [K]: V }, callback: (item: V, key:
|
||||||
if innerScopes[key] == nil then
|
if innerScopes[key] == nil then
|
||||||
-- Detach the inner scope from the parent effect to prevent
|
-- Detach the inner scope from the parent effect to prevent
|
||||||
-- disposing when the effect re-runs.
|
-- disposing when the effect re-runs.
|
||||||
innerScopes[key] = effectScope(function()
|
local stopScope = effectScope(function()
|
||||||
return callback(value, key)
|
return callback(value, key)
|
||||||
end, true)
|
end, true)
|
||||||
|
|
||||||
|
if disposed then
|
||||||
|
return stopScope()
|
||||||
|
else
|
||||||
|
innerScopes[key] = stopScope
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -51,10 +61,13 @@ local function observe<K, V>(getter: () -> { [K]: V }, callback: (item: V, key:
|
||||||
end)
|
end)
|
||||||
|
|
||||||
return function()
|
return function()
|
||||||
for _, dispose in innerScopes do
|
if not disposed then
|
||||||
dispose()
|
disposed = true
|
||||||
|
for key, dispose in innerScopes do
|
||||||
|
innerScopes[key] = nil
|
||||||
|
dispose()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
table.clear(innerScopes)
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue