Skip to content

Instantly share code, notes, and snippets.

@hello-42
Last active October 6, 2022 13:29
Show Gist options
  • Save hello-42/f231c05a0ec52599bdaa224ce1017ad8 to your computer and use it in GitHub Desktop.
Save hello-42/f231c05a0ec52599bdaa224ce1017ad8 to your computer and use it in GitHub Desktop.
--[=[
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