local J={}J.__index=J function J.new(Y,U,u)local e={Timeout=Y;Generate=U,Cleanup=u,All={};Free={};InUse={},LastUse={}}return setmetatable(e,J)end function J.Release(Y,J)local U=tick()Y.LastUse[J]=U coroutine.resume(coroutine.create(function()wait(Y.Timeout)if Y.LastUse[J]==U then Y:Remove(J)end end))Y.Cleanup(J)Y.InUse[J]=nil Y.Free[J]=true end function J.Get(J)local Y=next(J.Free)or J.Generate()J.Free[Y]=nil J.LastUse[Y]=nil J.All[Y]=true J.InUse[Y]=true return Y end function J.Remove(Y,J)Y.Free[J]=nil Y.InUse[J]=nil Y.LastUse[J]=nil Y.All[J]=nil J:Destroy()end function J.ReleaseAll(J)for Y in pairs(J.InUse)do J:Release(Y)end end function J.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
-- Create class
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
