From 71f7f4b0fa386d8b6e2ca3fa3b27ac88d272e6c2 Mon Sep 17 00:00:00 2001 From: 1ForeverHD Date: Fri, 21 May 2021 13:31:39 +0100 Subject: [PATCH 1/2] Provided Deferred Event support for Signal --- src/Zone/Signal.lua | 157 ++++++++++++++++++++++++++++++++------------ 1 file changed, 116 insertions(+), 41 deletions(-) diff --git a/src/Zone/Signal.lua b/src/Zone/Signal.lua index 29b8330..7a5135f 100644 --- a/src/Zone/Signal.lua +++ b/src/Zone/Signal.lua @@ -1,47 +1,120 @@ -- Signal --- Author: Quenty --- Source: https://github.com/Quenty/NevermoreEngine/blob/1bed579e0fc63cf4124a1e50c2379b8a7dc9ed1d/Modules/Shared/Events/Signal.lua --- License: MIT (https://github.com/Quenty/NevermoreEngine/blob/version2/LICENSE.md) +-- Author: Stephen Leitnick +-- Source: https://github.com/Sleitnick/AeroGameFramework/blob/43e4e02717e36ac83c820abc4461fb8afa2cd967/src/ReplicatedStorage/Aero/Shared/Signal.lua +-- License: MIT (https://github.com/Sleitnick/AeroGameFramework/blob/master/LICENSE) +-- Modified for use in Nanoblox +local Connection = {} +Connection.__index = Connection + +function Connection.new(signal, connection) + local self = setmetatable({ + _signal = signal; + _conn = connection; + Connected = true; + }, Connection) + return self +end + +function Connection:Disconnect() + if (self._conn) then + self._conn:Disconnect() + self._conn = nil + end + if (not self._signal) then return end + self.Connected = false + local connections = self._signal._connections + local connectionIndex = table.find(connections, self) + if (connectionIndex) then + local n = #connections + connections[connectionIndex] = connections[n] + connections[n] = nil + end + self._signal = nil +end + +function Connection:IsConnected() + if (self._conn) then + return self._conn.Connected + end + return false +end + +Connection.Destroy = Connection.Disconnect + +-------------------------------------------- + local Signal = {} -Signal.__index = Signal -Signal.ClassName = "Signal" Signal.totalConnections = 0 +Signal.__index = Signal -function Signal.new(trackConnectionsChanged) - local self = setmetatable({}, Signal) - self._bindableEvent = Instance.new("BindableEvent") - self._argData = nil - self._argCount = nil -- Prevent edge case of :Fire("A", nil) --> "A" instead of "A", nil +function Signal.new(trackConnectionsChanged) + local self = setmetatable({ + _bindable = Instance.new("BindableEvent"); + _connections = {}; + _args = {}; + _threads = 0; + _id = 0; + }, Signal) if trackConnectionsChanged then self.connectionsChanged = Signal.new() end - return self end +function Signal:_setProxy(rbxScriptSignal) + assert(typeof(rbxScriptSignal) == "RBXScriptSignal", "Argument #1 must be of type RBXScriptSignal") + self:_clearProxy() + self._proxyHandle = rbxScriptSignal:Connect(function(...) + self:Fire(...) + end) +end + + +function Signal:_clearProxy() + if (self._proxyHandle) then + self._proxyHandle:Disconnect() + self._proxyHandle = nil + end +end + + function Signal:Fire(...) - self._argData = {...} - self._argCount = select("#", ...) - self._bindableEvent:Fire() - self._argData = nil - self._argCount = nil + local totalListeners = (#self._connections + self._threads) + if (totalListeners == 0) then return end + local id = self._id + self._id += 1 + self._args[id] = {totalListeners, {n = select("#", ...), ...}} + self._threads = 0 + self._bindable:Fire(id) end -function Signal:Connect(handler) - if not (type(handler) == "function") then - error(("connect(%s)"):format(typeof(handler)), 2) + +function Signal:Wait() + self._threads += 1 + local id = self._bindable.Event:Wait() + local args = self._args[id] + args[1] -= 1 + if (args[1] <= 0) then + self._args[id] = nil end - -- Slightly modified this to account for very rare times - -- when an event is duplo-called and both _argData and - -- _argCount == nil - local connection = self._bindableEvent.Event:Connect(function() - if self._argData ~= nil then - handler(unpack(self._argData, 1, self._argCount)) + return table.unpack(args[2], 1, args[2].n) +end + + +function Signal:Connect(handler) + local connection = Connection.new(self, self._bindable.Event:Connect(function(id) + local args = self._args[id] + args[1] -= 1 + if (args[1] <= 0) then + self._args[id] = nil end - end) + handler(table.unpack(args[2], 1, args[2].n)) + end)) + table.insert(self._connections, connection) + -- -- this enables us to determine when a signal is connected to from an outside source self.totalConnections += 1 if self.connectionsChanged then @@ -57,34 +130,36 @@ function Signal:Connect(handler) end end) end - + -- return connection end -function Signal:Wait() - self._bindableEvent.Event:Wait() - assert(self._argData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.") - return unpack(self._argData, 1, self._argCount) + +function Signal:DisconnectAll() + for _,c in ipairs(self._connections) do + if (c._conn) then + c._conn:Disconnect() + end + end + self._connections = {} + self._args = {} end + function Signal:Destroy() - if self._bindableEvent then - self._bindableEvent:Destroy() - self._bindableEvent = nil - end + self:DisconnectAll() + self:_clearProxy() + self._bindable:Destroy() if self.connectionsChanged then self.connectionsChanged:Fire(-self.totalConnections) self.connectionsChanged:Destroy() self.connectionsChanged = nil self.totalConnections = 0 end - - self._argData = nil - self._argCount = nil end +Signal.destroy = Signal.Destroy +Signal.Disconnect = Signal.Destroy +Signal.Disconnect = Signal.Destroy -function Signal:Disconnect() - self:Destroy() -end return Signal \ No newline at end of file From 8f963449700e0f7727c5e583d0a63181806ffa21 Mon Sep 17 00:00:00 2001 From: 1ForeverHD Date: Fri, 21 May 2021 13:33:50 +0100 Subject: [PATCH 2/2] Updated logs --- docs/changelog.md | 7 +++++++ src/Zone/VERSION.lua | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 40d7262..93ff813 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,10 @@ +## [2.2.1] - May 7 2021 +### Added +- Compatibility for Deferred Events + + + +-------- ## [2.1.3] - May 7 2021 ### Fixed - A bug that occured when disconnecting localPlayer events diff --git a/src/Zone/VERSION.lua b/src/Zone/VERSION.lua index 26b2c18..b83e6b8 100644 --- a/src/Zone/VERSION.lua +++ b/src/Zone/VERSION.lua @@ -1 +1 @@ --- v2.1.3 \ No newline at end of file +-- v2.2.1 \ No newline at end of file