DEBOUNCE FUNCTION CLASS Important
When testing the debounce function in my own project. I noticed that arguments were not being passed. Though I tested it, it was tested with a function that did not require arguments. I forgot the three dots “…” I have updated the code accordingly to account for arguments.
local DebounceFunction = {}
function DebounceFunction.new(func, debounceTime)
local debounce = false
local debounceTime = debounceTime
return function(...)
if debounce then return end
debounce = true
func(...)
coroutine.wrap(function()
wait(debounceTime)
debounce = false
end)()
end
end
return DebounceFunction
In order to use this and create a debounce function, there are two preameters
x = DebounceFunction.new(function() print("hi") end, 1)
Conclusion
In summary, this is a simple utility module to make debounce functions look less like a mess.
Important Notes
The debounce handling is handled in another thread. In other words, the function supplied in the first will cause yielding whilst the debounce timer will not cause any yielding.
This has been tested, and it works. If there are any issues or suggestions, please leave a reply.
I recommend using this after having learned what a debounce function is and how to implement it.
avoid messing with function environments using getfenv() or setfenv(), disables some luau optimizations
The use of any of these functions performs a dynamic deoptimization, marking the affected environment as “impure”. The optimizations are only in effect on functions with “pure” environments - because of this, the use of loadstring / getfenv / setfenv is not recommended. Note that getfenv deoptimizes the environment even if it’s only used to read values from the environment.
Similarly, avoid using spawn() or delay() as they use the same internal mechanics as wait() . Uses of spawn() are generally better served with coroutine.wrap() and coroutine.resume() of the coroutine library.
with the use of metatables, you’re making a simple task unnecessarily complicated. by adding a ton of extra instructions, you’re making the code less performant and more difficult to maintain. the methods I show below don’t even need a cleanup function
simpler and more performant solutions below
local function debounce(callback)
local running = false
return function(...)
if running then return end
running = true
callback(...)
running = false
end
end
local function timedDebounce(callback, limit)
local previous = 0
return function(...)
local current = os.clock()
if current - previous <= limit then return end
previous = current
callback(...)
end
end
return { debounce, timedDebounce }
This looks like a lazy attempt at showing off your code by overcomplicating it. I have no clue why you’re excessively using rawget/rawset and metatable magic other than a childish attempt to assert your knowledge dominance to inexperienced programmers who have found this thread.
You’re also using spawn instead of coroutines which is known to cause yielding issues.
I can write the same class without using setfenv and getfenv, and therefore make use of the Luau optimizations.
local dbClass = {}
dbClass.__index = class
function dbClass.new(callback, debounceTime)
local self = setmetatable({
["func"] = callback
}, dbClass)
coroutine.wrap(function()
wait(debounceTime)
if self.func then
self.func()
else
warn("Not running debounce callback because cleanup was called prior to the debounceTime being finished")
end
end)()
return self
end
function dbClass:clean()
self.func = nil
end
The main goal is to return a function rather than a table. As such, objects are unnecessary in this context. I have simplified it down and will update the post accordingly.
local DebounceFunction = {}
function DebounceFunction.new(func, debounceTime)
local debounce = false
local debounceTime = debounceTime
return function()
if debounce then return end
debounce = true
func()
coroutine.wrap(function()
wait(debounceTime)
debounce = false
end)()
end
end
return DebounceFunction