Skip to content

Instantly share code, notes, and snippets.

@Reselim
Last active April 24, 2021 06:41
Show Gist options
  • Select an option

  • Save Reselim/1ee3e50ae773cd6ca6dfd53811963ec2 to your computer and use it in GitHub Desktop.

Select an option

Save Reselim/1ee3e50ae773cd6ca6dfd53811963ec2 to your computer and use it in GitHub Desktop.

Revisions

  1. Reselim renamed this gist Apr 24, 2021. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. Reselim revised this gist Apr 24, 2021. No changes.
  3. Reselim created this gist Nov 11, 2020.
    73 changes: 73 additions & 0 deletions ImmutableMaid.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    local LOCKED_ERROR = "Maid no longer usable, create a new maid if you wish to add events"

    local TABLE_SEARCH_FUNCTIONS = {
    "Destroy", "destroy",
    "Disconnect", "disconnect"
    }

    local function dispose(object)
    local objectType = typeof(object)

    if objectType == "function" then
    object()
    elseif objectType == "table" or objectType == "userdata" then
    for _, functionName in ipairs(TABLE_SEARCH_FUNCTIONS) do
    local disposeFunction = object[functionName]
    if disposeFunction then
    disposeFunction(object)
    return
    end
    end
    elseif objectType == "Instance" then
    object:Destroy()
    elseif objectType == "RBXScriptConnection" then
    object:Disconnect()
    end
    end

    local Maid = {}
    Maid.__index = Maid

    function Maid.new(tasks)
    local self = setmetatable({
    _tasks = {},
    _locked = false
    }, Maid)

    if tasks then
    self:giveTasks(tasks)
    end

    return self
    end

    function Maid:giveTask(task)
    assert(not self._locked, LOCKED_ERROR)
    table.insert(self._tasks, task)
    end

    function Maid:giveTasks(tasks)
    assert(not self._locked, LOCKED_ERROR)
    for _, task in pairs(tasks) do
    self:giveTask(task)
    end
    end

    function Maid:clean()
    -- Calling Maid:clean() multiple times is okay; it shouldn't error

    -- Example case: Disconnecting any input listeners when a Roact component is unmounted
    -- that may otherwise be disconnected when the input is ended.

    if not self._locked then
    self._locked = true

    for _, task in pairs(self._tasks) do
    dispose(task)
    end

    self._tasks = nil
    end
    end

    return Maid