Last active
December 20, 2023 22:39
-
-
Save MaximumADHD/538f0ab2541ef98912a2694dd8d274e7 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
-------------------------------------------------------------------------- | |
-- @ CloneTrooper1019, 2020-2021 | |
-- Thread.lua | |
-------------------------------------------------------------------------- | |
local Thread = {} | |
-------------------------------------------------------------------------- | |
-- Task Scheduler | |
-------------------------------------------------------------------------- | |
local RunService = game:GetService("RunService") | |
local front | |
-- use array indices for speed | |
-- and avoiding lua hash tables | |
local THREAD = 1 | |
local RESUME = 2 | |
local NEXT = 3 | |
local function pushThread(thread: thread, resume: number) | |
local node = | |
{ | |
[THREAD] = thread; | |
[RESUME] = resume; | |
} | |
if front then | |
if front[RESUME] >= resume then | |
node[NEXT] = front | |
front = node | |
else | |
local prev = front | |
while prev[NEXT] and prev[NEXT][RESUME] < resume do | |
prev = prev[NEXT] | |
end | |
node[NEXT] = prev[NEXT] | |
prev[NEXT] = node | |
end | |
else | |
front = node | |
end | |
end | |
local function popThreads() | |
local now = os.clock() | |
while front do | |
-- Resume if we're reasonably close enough. | |
if front[RESUME] - now < (1 / 120) then | |
local thread = front[THREAD] | |
front = front[NEXT] | |
coroutine.resume(thread, now) | |
else | |
break | |
end | |
end | |
end | |
RunService.Heartbeat:Connect(popThreads) | |
-------------------------------------------------------------------------- | |
-- Thread | |
-------------------------------------------------------------------------- | |
local errorStack = "ERROR: %s\nStack Begin\n%sStack End" | |
local function HandleError(err) | |
local trace = debug.traceback() | |
warn(errorStack:format(err, trace)) | |
end | |
function Thread:Wait(t: number?) | |
local t = tonumber(t) | |
if t then | |
local start = os.clock() | |
pushThread(coroutine.running(), start + t) | |
return coroutine.yield() - start | |
else | |
return RunService.Heartbeat:Wait() | |
end | |
end | |
function Thread:Spawn(func: any, ...) | |
local args = { ... } | |
local numArgs = select('#', ...) | |
local bindable = Instance.new("BindableEvent") | |
bindable.Event:Connect(function (stack) | |
xpcall(func, HandleError, stack()) | |
end) | |
bindable:Fire(function () | |
return unpack(args, 1, numArgs) | |
end) | |
end | |
function Thread:Delay(t: number, callback: any) | |
self:Spawn(function () | |
local delayTime, elapsed = self:Wait(t) | |
xpcall(callback, HandleError, delayTime, elapsed) | |
end) | |
end | |
-------------------------------------------------------------------------- | |
return Thread |
Hopefully yeah, I'm glad to see a first party solution to the problems that necessitated this module.
Hopefully yeah, I'm glad to see a first party solution to the problems that necessitated this module.
on 1 test i did with task.wait, it was 3ms off, wait() is also optimized a bit now, its nice to see this
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
task.wait() and some other stuff is released now, task.wait is very accurate and its 1/60, so this module probaly isnt needed for most people anymore