-- Compiled with roblox-ts v3.0.0 local TS = _G[script] local _services = TS.import(script, TS.getModule(script, "@rbxts", "services")) local RunService = _services.RunService local TweenService = _services.TweenService local TweenTools = TS.import(script, script.Parent.Parent.Parent, "tween_tools").TweenTools local FrameTimer local Builder do Builder = setmetatable({}, { __tostring = function() return "Builder" end, }) Builder.__index = Builder function Builder.new(...) local self = setmetatable({}, Builder) return self:constructor(...) or self end function Builder:constructor() self.timer_ = FrameTimer.new() self.auto_start_ = false end function Builder:Create() return FrameTimer.Builder.new() end function Builder:WithTimer(callback) callback(self.timer_) return self end function Builder:WithWaitTime(value) self.timer_.WaitTime = value return self end function Builder:WithOneShot(value) self.timer_.OneShot = value return self end function Builder:WithUpdateCallback(callback) self.timer_:SetUpdateCallback(callback) return self end function Builder:WithTimeOutCallback(callback, with_connection) local connection connection = self.timer_.OnTimeOut:Connect(function() return callback(connection) end) local _result = with_connection if _result ~= nil then _result(connection) end return self end function Builder:WithAutoStart() self.auto_start_ = true return self end function Builder:WithSteppingMethod(stepping_event) self.timer_:SetSteppingEvent(stepping_event) end function Builder:Build() if self.auto_start_ then self.timer_:Start() end return self.timer_ end end setmetatable(Builder, { __call = function() return Builder.new() end, }) do FrameTimer = setmetatable({}, { __tostring = function() return "FrameTimer" end, }) FrameTimer.__index = FrameTimer function FrameTimer.new(...) local self = setmetatable({}, FrameTimer) return self:constructor(...) or self end function FrameTimer:constructor() self.WaitTime = 1 self.time_left_ = 0 self.initialized_wait_time_ = 0 self.OneShot = true self.Paused = false self.stopped_ = true self.time_out_event_ = Instance.new("BindableEvent") self.OnTimeOut = self.time_out_event_.Event self.update_callback_ = function() end self.stepping_event_ = RunService.Heartbeat end function FrameTimer:CreateCustomTweenTemplate(start_value, target_value, wait_time, create_new_alpha_generator, auto_start) return function(callback) return self:CreateCustomTween(start_value, target_value, wait_time, create_new_alpha_generator, callback, auto_start) end end function FrameTimer:CreateTweenTemplate(start_value, target_value, wait_time, auto_start, easing_style, easing_direction) return function(callback) return self:CreateTween(start_value, target_value, wait_time, callback, auto_start, easing_style, easing_direction) end end function FrameTimer:CreateTween(start_value, target_value, wait_time, set_function, auto_start, easing_style, easing_direction) if auto_start == nil then auto_start = false end if easing_style == nil then easing_style = Enum.EasingStyle.Cubic end if easing_direction == nil then easing_direction = Enum.EasingDirection.InOut end return FrameTimer:CreateCustomTween(start_value, target_value, wait_time, function() return function(alpha) return TweenService:GetValue(alpha, easing_style, easing_direction) end end, set_function, auto_start) end function FrameTimer:CreateCustomTween(start_value, target_value, wait_time, create_new_alpha_generator, set_function, auto_start) if auto_start == nil then auto_start = true end local timer = FrameTimer.new() timer.WaitTime = wait_time local alpha_generator = create_new_alpha_generator() timer:SetUpdateCallback(function(time_passed, delta_time) local alpha = time_passed / wait_time local new_alpha = alpha_generator(alpha, delta_time, time_passed, wait_time) local new_value = TweenTools.LerpValue(start_value, target_value, new_alpha) set_function(new_value) end) if auto_start then timer:Start() end return timer end function FrameTimer:GetTimeLeft() return self.time_left_ end function FrameTimer:IsStopped() return self.stopped_ end function FrameTimer:SetUpdateCallback(callback) self.update_callback_ = callback return self end function FrameTimer:SetSteppingEvent(stepping_event) self.stepping_event_ = stepping_event return self end function FrameTimer:Start(time_sec) if time_sec == nil then time_sec = -1 end if time_sec > 0 then self.WaitTime = time_sec end --stops the existing timer self:Stop() self.time_left_ = self.WaitTime --saves the time to calculate time passed self.initialized_wait_time_ = self.WaitTime --takes stopped flag away self.stopped_ = false self.update_connection_ = self.stepping_event_:Connect(function(delta_time) return self:Update(delta_time) end) return self end function FrameTimer:Await(ignore_if_stopped) if ignore_if_stopped == nil then ignore_if_stopped = true end if ignore_if_stopped and self.stopped_ then return self end self.OnTimeOut:Wait() return self end function FrameTimer:Update(delta_time) --dont update if paused if self.Paused then return nil end self.time_left_ -= delta_time --clamps to wait time local time_passed = math.min(self.initialized_wait_time_ - self.time_left_, self.WaitTime) self.update_callback_(time_passed, delta_time) if self.time_left_ > 0 then return nil end self.time_out_event_:Fire() if not self.OneShot then --restarts the time if not oneshot self.time_left_ = self.WaitTime return nil end --stops if one shot self:Stop() end function FrameTimer:Stop() if self.stopped_ then return nil end --clamps the time self.time_left_ = math.max(self.time_left_, 0) local _result = self.update_connection_ if _result ~= nil then _result:Disconnect() end self.Paused = false self.stopped_ = true return self end function FrameTimer:Destroy() self:Stop() self.time_out_event_:Destroy() end FrameTimer.Builder = Builder end return { FrameTimer = FrameTimer, }