Last active
October 6, 2022 13:29
-
-
Save hello-42/f231c05a0ec52599bdaa224ce1017ad8 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
--[=[ | |
Copyright (c) 2022- https://github.com/hello-42 | |
MIT Licensing. All rights reserved. | |
]=] | |
local Toggler = {} | |
-- Services | |
local RunService = game:GetService("RunService") | |
-- Libraries | |
local require = require(script.Parent.loader).load(script) | |
local Signal = require("Signal") | |
local BaseClass = require("BaseClass") | |
-- setmetatable | |
setmetatable(Toggler, BaseClass) | |
Toggler.__index = Toggler | |
-- Constants | |
local STEP = RunService.Stepped | |
-- Internal | |
function validateState(state, ...) | |
local functions, running, step = {}, true, STEP | |
if typeof(state) == "function" then | |
functions = { state, ... } | |
elseif typeof(state) == "table" then | |
functions, running, step = | |
{ table.unpack(state) }, | |
if state.running ~= nil then state.running else running, | |
if state.step ~= nil then state.step else step | |
table.insert(functions, state["function"]) | |
if state.functions then | |
for _, fn in state.functions do | |
table.insert(functions, fn) | |
end | |
end | |
for _, arg in { ... } do | |
table.insert(functions, arg) | |
end | |
end | |
for i = #functions, 1, -1 do | |
if typeof(functions[i]) == "function" or (#validateState(functions[i]) > 0) then | |
continue | |
end | |
table.remove(functions, i) | |
end | |
return functions, step, running | |
end | |
function Toggler.new(...) | |
local self = setmetatable(BaseClass.new(), Toggler) | |
self.signal = Signal.new() | |
self:setState(...) | |
return self | |
end | |
function Toggler:setState(...) | |
self.maid:Destroy() | |
self.functions, self.step, self.running = validateState(...) | |
self:_setupShared() | |
end | |
function Toggler:_setupShared() | |
self.maid:GiveTask(self.signal:Connect(function(bool) | |
self.running = if #self.functions > 0 then if bool then bool else not self.running else false | |
if self.connection then | |
self.connection:Disconnect() | |
self.connection = nil | |
end | |
if self.running == true then | |
self.connection = self:_resolveStep() | |
self.maid:GiveTask(self.connection) | |
end | |
end)) | |
if self.running then | |
self:toggle(true) | |
end | |
end | |
function Toggler:_resolveStep() | |
local lastStep = os.clock() | |
local stepEventSignal = if typeof(self.step) == "RBXScriptSignal" then self.step else STEP | |
return stepEventSignal:Connect(function(...) | |
local deltaTime = (os.clock() - lastStep) | |
if typeof(self.step) == "number" then | |
if (os.clock() - lastStep) <= self.step then | |
return | |
end | |
end | |
lastStep = os.clock() | |
for _, fn in self.functions do | |
fn(self, deltaTime, ...) | |
end | |
end) | |
end | |
function Toggler:toggle(bool) | |
self.signal:Fire(bool) | |
end | |
function Toggler:Destroy() | |
self.maid:GiveTask(self.signal) | |
self.maid:Destroy() | |
setmetatable(self, nil) | |
end | |
return Toggler |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment