local N=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")):WaitForChild("\078\101\118\101\114\109\111\114\101"))local C=game:GetService("\082\117\110\083\101\114\118\105\099\101")local F=N("\077\097\105\100")local h=N("\079\098\106\101\099\116\084\119\101\101\110\101\114")local d={}d.ClassName="\079\098\106\101\099\116\084\119\101\101\110\077\097\110\097\103\101\114"d.__index=d function d.new()local N=setmetatable({},d)N._maid=F.new()N._objects={}N._activeObjects={}if C:IsServer()then warn("\079\098\106\101\099\116\084\119\101\101\110\077\097\110\097\103\101\114 \105\115 \105\110\116\101\110\100\101\100 \102\111\114 \115\101\114\118\101\114 \117\115\101")end return N end function d.TweenProperty(K,N,C,F,h,d)local a=K:_getTweener(F)a:TweenProperty(N,C,h,d)K._activeObjects[F]=a K:_startUpdate()return a end function d.TweenProperties(d,N,C,F,h)assert(N)assert(C)assert(F)assert(h)local K=d:_getTweener(F)K:TweenProperties(N,C,h)d._activeObjects[F]=K d:_startUpdate()return K end function d.RemoveTween(F,N,C)assert(typeof(C)=="\073\110\115\116\097\110\099\101")local h=F._objects[C]if not h then return end h:RemoveTween(N)if h:HasTweens()then F._activeObjects[C]=h F:_startUpdate()else F._objects[C]=nil F._activeObjects[C]=nil end end function d._getTweener(C,N)if C._objects[N]then return C._objects[N]else local F=h.new(N)C._objects[N]=F return F end end function d._startUpdate(N)local F=N._maid._stepped if F and F.Connected then return end N._maid._stepped=C.Stepped:Connect(function()local C=N:_update()if not C then N:_stopUpdate()end end)end function d._stopUpdate(N)N._maid._stepped=nil end function d._update(N)local C=false local F={}for N,h in pairs(N._activeObjects)do if h:Update()then C=true else F[N]=true end end for C,F in pairs(F)do N._activeObjects[C]=nil end return C end function d.Destroy(N)N._maid:DoCleaning()setmetatable(N,nil)end return d
--- Manager to tween properties on objects. Intended for use on client.
-- @classmod ObjectTweenManager

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))

local RunService = game:GetService("RunService")

local Maid = require("Maid")
local ObjectTweener = require("ObjectTweener")

local ObjectTweenManager = {}
ObjectTweenManager.ClassName = "ObjectTweenManager"
ObjectTweenManager.__index = ObjectTweenManager

function ObjectTweenManager.new()
	local self = setmetatable({}, ObjectTweenManager)

	self._maid = Maid.new()
	self._objects = {}
	self._activeObjects = {} -- [object] = tweener

	if RunService:IsServer() then
		warn("ObjectTweenManager is intended for server use")
	end

	return self
end

--- Tweens a single property on an object
function ObjectTweenManager:TweenProperty(priority, key, object, property, value)
	local tweener = self:_getTweener(object)
	tweener:TweenProperty(priority, key, property, value)
	self._activeObjects[object] = tweener
	self:_startUpdate()

	return tweener
end

--- Tweens multiple properties on an object
function ObjectTweenManager:TweenProperties(priority, key, object, properties)
	assert(priority)
	assert(key)
	assert(object)
	assert(properties)

	local tweener = self:_getTweener(object)
	tweener:TweenProperties(priority, key, properties)
	self._activeObjects[object] = tweener
	self:_startUpdate()

	return tweener
end

function ObjectTweenManager:RemoveTween(key, object)
	assert(typeof(object) == "Instance")

	local tweener = self._objects[object]
	if not tweener then
		return
	end

	tweener:RemoveTween(key)
	if tweener:HasTweens() then
		self._activeObjects[object] = tweener
		self:_startUpdate()
	else
		self._objects[object] = nil
		self._activeObjects[object] = nil

	end
end

function ObjectTweenManager:_getTweener(object)
	if self._objects[object] then
		return self._objects[object]
	else
		local tweener = ObjectTweener.new(object)
		self._objects[object] = tweener
		return tweener
	end
end

function ObjectTweenManager:_startUpdate()
	-- Don't reconnect if already connected
	local conn = self._maid._stepped
	if conn and conn.Connected then
		return
	end

	self._maid._stepped = RunService.Stepped:Connect(function()
		local updating = self:_update()
		if not updating then
			self:_stopUpdate()
		end
	end)
end

function ObjectTweenManager:_stopUpdate()
	self._maid._stepped = nil
end

function ObjectTweenManager:_update()
	local updating = false
	local to_remove = {}
	for object, tweener in pairs(self._activeObjects) do
		if tweener:Update() then
			updating = true
		else
			to_remove[object] = true
		end
	end

	for obj, _ in pairs(to_remove) do
		self._activeObjects[obj] = nil
	end
	return updating
end

function ObjectTweenManager:Destroy()
	self._maid:DoCleaning()
	setmetatable(self, nil)
end

return ObjectTweenManager