Created
July 6, 2019 16:56
-
-
Save howmanysmall/cad01277443d25493e578e44d4ada8b7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local FastSpawn = require(script.FastSpawn).SAFE | |
local newproxy = newproxy | |
local setmetatable = setmetatable | |
local typeof = typeof | |
local next = next | |
local wait = wait | |
local Instance_new = Instance.new | |
local LinkToInstanceIndex = newproxy(false) | |
local Janitors = setmetatable({ }, { __mode = "k" }) | |
local Janitor = { } | |
Janitor.__index = { } | |
Janitor.__index.CurrentlyCleaning = true | |
local TypeDefaults = { | |
["function"] = true; --end | |
["RBXScriptConnection"] = "Disconnect"; | |
} | |
function Janitor.new() | |
return setmetatable({ CurrentlyCleaning = false }, Janitor) | |
end | |
function Janitor.__index:Add(Object, MethodName, Index) | |
if Index then | |
self:Remove(Index) | |
local this = Janitors[self] | |
if not this then | |
this = { } | |
Janitors[self] = this | |
end | |
this[Index] = Object | |
end | |
self[Object] = MethodName or TypeDefaults[typeof(Object)] or "Destroy" | |
return Object | |
end | |
function Janitor.__index:Remove(Index) | |
local this = Janitors[self] | |
if this then | |
local Object = this[Index] | |
if Object then | |
local MethodName = self[Object] | |
if MethodName then | |
if MethodName == true then | |
Object() | |
else | |
Object[MethodName](Object) | |
end | |
self[Object] = nil | |
end | |
this[Index] = nil | |
end | |
end | |
end | |
function Janitor.__index:Cleanup() | |
if not self.CurrentlyCleaning then | |
self.CurrentlyCleaning = nil -- A little trick to exclude the Debouncer from the loop below AND set it to true via __index :) | |
for Object, MethodName in next, self do | |
if MethodName == true then | |
Object() | |
else | |
Object[MethodName](Object) | |
end | |
self[Object] = nil | |
end | |
local this = Janitors[self] | |
if this then | |
for Index in next, this do | |
this[Index] = nil | |
end | |
Janitors[self] = nil | |
end | |
self.CurrentlyCleaning = false | |
end | |
end | |
function Janitor.__index:Destroy() | |
self:Cleanup() | |
setmetatable(self, nil) | |
end | |
Janitor.__call = Janitor.__index.Cleanup | |
--- Makes the Janitor clean up when the instance is destroyed | |
-- @param Instance Instance The Instance the Janitor will wait for to be Destroyed | |
-- @returns Disconnectable table to stop Janitor from being cleaned up upon Instance Destroy (automatically cleaned up by Janitor, btw) | |
-- @author Corecii | |
local Disconnect = { } | |
Disconnect.Connected = true | |
Disconnect.__index = Disconnect | |
function Disconnect:Disconnect() | |
self.Connected = false | |
self.Connection:Disconnect() | |
end | |
function Janitor.__index:LinkToInstance(Object, AllowMultiple) | |
local Reference = Instance_new("ObjectValue") | |
Reference.Value = Object | |
local ManualDisconnect = setmetatable({ }, Disconnect) | |
local Connection | |
local function ChangedFunction(Obj, Par) | |
if not Reference.Value then | |
ManualDisconnect.Connected = false | |
return self:Cleanup() | |
elseif Obj == Reference.Value and not Par then | |
Obj = nil | |
wait() | |
if (not Reference.Value or not Reference.Value.Parent) and ManualDisconnect.Connected then | |
if not Connection.Connected then | |
ManualDisconnect.Connected = false | |
return self:Cleanup() | |
else | |
while true do | |
wait(0.2) | |
if not ManualDisconnect.Connected then | |
return | |
elseif not Connection.Connected then | |
ManualDisconnect.Connected = false | |
return self:Cleanup() | |
elseif Reference.Value.Parent then | |
return | |
end | |
end | |
end | |
end | |
end | |
end | |
Connection = Object.AncestryChanged:Connect(ChangedFunction) | |
ManualDisconnect.Connection = Connection | |
Object = nil | |
FastSpawn(ChangedFunction, Reference.Value, Reference.Value.Parent) | |
if AllowMultiple then | |
self:Add(ManualDisconnect, "Disconnect") | |
else | |
self:Add(ManualDisconnect, "Disconnect", LinkToInstanceIndex) | |
end | |
return ManualDisconnect | |
end | |
return Janitor |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment