add gs
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
--[[
|
||||
An interface to have one event listener at a time on an event.
|
||||
|
||||
One listener can be registered per SingleEventManager/Instance/Event triple.
|
||||
|
||||
For example:
|
||||
|
||||
myManager:connect(myPart, "Touched", touchedListener)
|
||||
myManager:connect(myPart, "Touched", otherTouchedListener)
|
||||
|
||||
If myPart is touched, only `otherTouchedListener` will fire, because the
|
||||
first listener was disconnected during the second connect call.
|
||||
|
||||
The hooks provided by SingleEventManager pass the associated Roblox object
|
||||
as the first parameter to the callback. This differs from normal
|
||||
Roblox events.
|
||||
]]
|
||||
|
||||
local SingleEventManager = {}
|
||||
|
||||
SingleEventManager.__index = SingleEventManager
|
||||
|
||||
local function createHook(rbx, key, method)
|
||||
local hook = {
|
||||
method = method,
|
||||
connection = rbx[key]:Connect(function(...)
|
||||
method(rbx, ...)
|
||||
end)
|
||||
}
|
||||
|
||||
return hook
|
||||
end
|
||||
|
||||
local function createChangeHook(rbx, key, method)
|
||||
local hook = {
|
||||
method = method,
|
||||
connection = rbx:GetPropertyChangedSignal(key):Connect(function(...)
|
||||
method(rbx, ...)
|
||||
end)
|
||||
}
|
||||
|
||||
return hook
|
||||
end
|
||||
|
||||
local function formatChangeKey(key)
|
||||
return ("!PropertyChangeEvent:%s"):format(key)
|
||||
end
|
||||
|
||||
function SingleEventManager.new()
|
||||
local self = {}
|
||||
|
||||
self._hookCache = {}
|
||||
|
||||
setmetatable(self, SingleEventManager)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function SingleEventManager:connect(rbx, key, method)
|
||||
local rbxHooks = self._hookCache[rbx]
|
||||
|
||||
if rbxHooks then
|
||||
local existingHook = rbxHooks[key]
|
||||
|
||||
if existingHook then
|
||||
if existingHook.method == method then
|
||||
return
|
||||
end
|
||||
|
||||
existingHook.connection:Disconnect()
|
||||
end
|
||||
|
||||
rbxHooks[key] = createHook(rbx, key, method)
|
||||
else
|
||||
rbxHooks = {}
|
||||
rbxHooks[key] = createHook(rbx, key, method)
|
||||
|
||||
self._hookCache[rbx] = rbxHooks
|
||||
end
|
||||
end
|
||||
|
||||
function SingleEventManager:connectProperty(rbx, key, method)
|
||||
local rbxHooks = self._hookCache[rbx]
|
||||
local formattedKey = formatChangeKey(key)
|
||||
|
||||
if rbxHooks then
|
||||
local existingHook = rbxHooks[formattedKey]
|
||||
|
||||
if existingHook then
|
||||
if existingHook.method == method then
|
||||
return
|
||||
end
|
||||
|
||||
existingHook.connection:Disconnect()
|
||||
end
|
||||
|
||||
rbxHooks[formattedKey] = createChangeHook(rbx, key, method)
|
||||
else
|
||||
rbxHooks = {}
|
||||
rbxHooks[formattedKey] = createChangeHook(rbx, key, method)
|
||||
|
||||
self._hookCache[rbx] = rbxHooks
|
||||
end
|
||||
end
|
||||
|
||||
function SingleEventManager:disconnect(rbx, key)
|
||||
local rbxHooks = self._hookCache[rbx]
|
||||
|
||||
if not rbxHooks then
|
||||
return
|
||||
end
|
||||
|
||||
local existingHook = rbxHooks[key]
|
||||
|
||||
if not existingHook then
|
||||
return
|
||||
end
|
||||
|
||||
existingHook.connection:Disconnect()
|
||||
rbxHooks[key] = nil
|
||||
|
||||
if next(rbxHooks) == nil then
|
||||
self._hookCache[rbx] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function SingleEventManager:disconnectProperty(rbx, key)
|
||||
self:disconnect(rbx, formatChangeKey(key))
|
||||
end
|
||||
|
||||
function SingleEventManager:disconnectAll(rbx)
|
||||
local rbxHooks = self._hookCache[rbx]
|
||||
|
||||
if not rbxHooks then
|
||||
return
|
||||
end
|
||||
|
||||
for _, hook in pairs(rbxHooks) do
|
||||
hook.connection:Disconnect()
|
||||
end
|
||||
|
||||
self._hookCache[rbx] = nil
|
||||
end
|
||||
|
||||
return SingleEventManager
|
||||
Reference in New Issue
Block a user