Last active
November 16, 2021 02:53
-
-
Save lucasmz-dev/c8f08dbd1a84c60513cb991b2836c99a to your computer and use it in GitHub Desktop.
Proper BindToClose implementation
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
--[[ | |
A custom BindToClose implementation which fixes these issues: | |
* Has a :Disconnect method | |
* Listeners run in a different order: | |
Which is: First connected -> Last connected | |
This order fixes a lot of hidden issues, particularly with requiring. | |
]] | |
local RunService = game:GetService("RunService") | |
local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
local ScriptSignal = require(ReplicatedStorage.Utils.Signal.Immediate) | |
-- Must be an immediate mode signal! I am using FastSignal Immediate, you can use GoodSignal. | |
local BindToClose = ScriptSignal.new() | |
local HandlerClosed = ScriptSignal.new() | |
local ActiveHandlers = 0 | |
game:BindToClose(function() | |
BindToClose:Fire() | |
while ActiveHandlers > 0 do | |
HandlerClosed:Wait() | |
end | |
end) | |
return function( | |
handler: () -> () | |
): ScriptSignal.ScriptConnection | |
return BindToClose:Connect(function() | |
ActiveHandlers += 1 | |
local connection | |
local thread | |
local hasThreadDied = false | |
task.spawn(function() | |
thread = coroutine.running() | |
handler() | |
hasThreadDied = true | |
ActiveHandlers -= 1 | |
HandlerClosed:Fire() | |
end) | |
connection = RunService.Heartbeat:Connect(function() | |
if hasThreadDied then | |
connection:Disconnect() | |
return | |
end | |
if coroutine.status(thread) == 'dead' and hasThreadDied == false then | |
-- This is used to detect when a thread errors | |
connection:Disconnect() | |
ActiveHandlers -= 1 | |
HandlerClosed:Fire() | |
return | |
end | |
end) | |
end) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment