Instance.Event:Wait(n) with n being time till timeout function

I highly recommend stop using BindableEvents for manual resumption of threads, you can check out FastSignal’s :Wait implementation, it uses task.spawn, coroutine.running, and coroutine.yield to achieve that, it is faster, and also uses way less memory, not having to create an instance, and not having to create a table for arguments.

Which by the way, if you were to stay with BindableEvents, these args arent being handled in the best way, as having a nil argument can make any arguments after that disappear.

You can look into how table.pack and table.unpack works by seeing Nevermore’s Signal implementation.

-- Quick rewrite:

-- Should not *break* with deferred events
local function WaitUntil(
    event: RBXScriptSignal | any,
    timeOut: number
): (boolean, ...any)

    local thread = coroutine.running()

    local connection = nil
    connection = event:Connect(function(...)
        if connection == nil then
            return
        end

        connection:Disconnect()
        connection = nil

        task.spawn(thread, false, ...)
    end)

    task.delay(timeOut, function()
        if connection == nil then
            return
        end

        connection:Disconnect()
        connection = nil

        task.spawn(thread, true)
    end)

    return coroutine.yield()
end
2 Likes