local k={}k.__index=k function k.new(J,g,b)local I={Timeout=J,Generate=g;Cleanup=b;All={};Free={},InUse={},LastUse={}}return setmetatable(I,k)end function k.Release(J,k)local g=tick()J.LastUse[k]=g coroutine.resume(coroutine.create(function()wait(J.Timeout)if J.LastUse[k]==g then J:Remove(k)end end))J.Cleanup(k)J.InUse[k]=nil J.Free[k]=true end function k.Get(k)local J=next(k.Free)or k.Generate()k.Free[J]=nil k.LastUse[J]=nil k.All[J]=true k.InUse[J]=true return J end function k.Remove(J,k)J.Free[k]=nil J.InUse[k]=nil J.LastUse[k]=nil J.All[k]=nil k:Destroy()end function k.ReleaseAll(k)for J in pairs(k.InUse)do k:Release(J)end end function k.Generate()error("\078\111 \105\110\115\116\097\110\099\101 \103\101\110\101\114\097\116\105\111\110 \099\097\108\108\098\097\099\107 \115\112\101\099\105\102\105\101\100",2)end

local InstancePool = {}
InstancePool.__index = InstancePool

function InstancePool.new(Timeout, GenerateCallback, CleanupCallback)

    -- Prepare new pool
    local self = {
        Timeout = Timeout,
        Generate = GenerateCallback,
        Cleanup = CleanupCallback,
        All = {},
        Free = {},
        InUse = {},
        LastUse = {}
    }

    -- Return pool
    return setmetatable(self, InstancePool)

end

function InstancePool:Release(Instance)

    -- Log the last use of this instance
    local ReleaseTime = tick()
    self.LastUse[Instance] = ReleaseTime

    -- Remove instance if not used after timeout
    coroutine.resume(coroutine.create(function ()
        wait(self.Timeout)
        if self.LastUse[Instance] == ReleaseTime then
            self:Remove(Instance)
        end
    end))

    -- Run cleanup routine on instance
    self.Cleanup(Instance)

    -- Free instance
    self.InUse[Instance] = nil
    self.Free[Instance] = true

end

function InstancePool:Get()

    -- Get free instance, or generate a new one
    local Instance = next(self.Free) or self.Generate()

    -- Reserve instance
    self.Free[Instance] = nil
    self.LastUse[Instance] = nil
    self.All[Instance] = true
    self.InUse[Instance] = true

    -- Return instance
    return Instance

end

function InstancePool:Remove(Instance)
    self.Free[Instance] = nil
    self.InUse[Instance] = nil
    self.LastUse[Instance] = nil
    self.All[Instance] = nil
    Instance:Destroy()
end

function InstancePool:ReleaseAll()
    for Instance in pairs(self.InUse) do
        self:Release(Instance)
    end
end

function InstancePool.Generate()
    error('No instance generation callback specified', 2)
end
