Cleanup helper for instances

Closes #19
This commit is contained in:
Aaron Smith 2023-09-26 14:34:27 +01:00
parent d1f86a3f9e
commit 32fa44f4c5
3 changed files with 47 additions and 4 deletions

View file

@ -1,19 +1,43 @@
if not game then script = require "test/relative-string" end if not game then script = require "test/relative-string" end
local typeof = game and typeof or require "test/mock".typeof :: never
local throw = require(script.Parent.throw) local throw = require(script.Parent.throw)
local graph = require(script.Parent.graph) local graph = require(script.Parent.graph)
local get_scope = graph.get_scope local get_scope = graph.get_scope
local add_cleanup = graph.add_cleanup local add_cleanup = graph.add_cleanup
local function cleanup(callback: () -> ()) local function helper(obj: any)
return
if typeof(obj) == "RBXScriptConnection" then function() obj:Disconnect() end
elseif typeof(obj) == "Instance" then function() obj:Destroy() end
elseif obj.destroy then function() obj:destroy() end
elseif obj.disconnect then function() obj:disconnect() end
elseif obj.Destroy then function() obj:Destroy() end
elseif obj.Disconnect then function() obj:Disconnect() end
else throw("cannot cleanup given object")
end
local function cleanup(value: unknown)
local scope = get_scope() local scope = get_scope()
if not scope then if not scope then
throw "cannot cleanup in a non-reactive scope" throw "cannot cleanup in a non-reactive scope"
end; assert(scope) end; assert(scope)
add_cleanup(scope, callback) if type(value) == "function" then
add_cleanup(scope, value :: () -> ())
else
add_cleanup(scope, helper(value))
end
end end
return cleanup type Destroyable = { destroy: (any) -> () } | { Destroy: (any) -> () }
type Disconnectable = { disconnect: (any) -> () } | { Disconnect: (any) -> () }
return cleanup ::
( (callback: () -> ()) -> () ) &
( (instance: Destroyable) -> () ) &
( (connection: Disconnectable) -> () ) &
( (instance: Instance) -> () ) &
( (connection: RBXScriptConnection) -> () )

View file

@ -1,6 +1,5 @@
if not game then script = require "test/relative-string" end if not game then script = require "test/relative-string" end
local throw = require(script.Parent.throw)
local graph = require(script.Parent.graph) local graph = require(script.Parent.graph)
type Node<T> = graph.Node<T> type Node<T> = graph.Node<T>
local get_scope = graph.get_scope local get_scope = graph.get_scope

View file

@ -691,6 +691,7 @@ TEST("effect()", wrap_root(function()
end)) end))
TEST("cleanup()", wrap_root(function() TEST("cleanup()", wrap_root(function()
local root = vide.root
local source = vide.source local source = vide.source
local effect = vide.effect local effect = vide.effect
local cleanup = vide.cleanup local cleanup = vide.cleanup
@ -749,6 +750,25 @@ TEST("cleanup()", wrap_root(function()
src(3) src(3)
CHECK(testkit.seq(queue, { 1, 2, 1, 2 })) CHECK(testkit.seq(queue, { 1, 2, 1, 2 }))
end end
do CASE "cleanup objects"
local ran = {}
root(function(destroy)
effect(function()
cleanup { disconnect = function() ran.disconnect = true end }
cleanup { Disconnect = function() ran.Disconnect = true end }
cleanup { destroy = function() ran.destroy = true end }
cleanup { Destroy = function() ran.Destroy = true end }
destroy()
end)
end)
CHECK(ran.disconnect)
CHECK(ran.Disconnect)
CHECK(ran.destroy)
CHECK(ran.Destroy)
end
end)) end))
TEST("create()", wrap_root(function() TEST("create()", wrap_root(function()