mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
40 lines
1.3 KiB
Lua
40 lines
1.3 KiB
Lua
if not game then script = require "test/relative-string" end
|
|
|
|
local flags = require(script.Parent.flags)
|
|
local throw = require(script.Parent.throw)
|
|
|
|
|
|
-- array of all cleanup callbacks
|
|
local cleanup_callbacks = {} :: { [number]: () -> () } -- always dense
|
|
-- weak array of all cleanup lifetimes
|
|
local cleanup_lifetime = {} :: { [number]: unknown } -- can be sparse
|
|
setmetatable(cleanup_lifetime :: any, { __mode = "v" })
|
|
|
|
local function on_gc(lifetime: unknown, callback: () -> ())
|
|
local id = #cleanup_callbacks + 1
|
|
cleanup_lifetime[id :: any] = lifetime -- todo
|
|
cleanup_callbacks[id] = callback
|
|
end
|
|
|
|
local function sweep()
|
|
for id = #cleanup_callbacks, 1, -1 do
|
|
if cleanup_lifetime[id] == nil then -- lifetime was garbage collected
|
|
local callback = cleanup_callbacks[id]
|
|
|
|
do -- swap and pop
|
|
local max_id = #cleanup_callbacks
|
|
|
|
cleanup_callbacks[id] = cleanup_callbacks[max_id]
|
|
cleanup_callbacks[max_id] = nil
|
|
|
|
cleanup_lifetime[id] = cleanup_lifetime[max_id]
|
|
cleanup_lifetime[max_id] = nil
|
|
end
|
|
|
|
local ok, err: string? = pcall(callback)
|
|
if not ok then warn(`error occured during cleanup: {err}`) end
|
|
end
|
|
end
|
|
end
|
|
|
|
return function() return on_gc, sweep end
|