Skip to content

Commit

Permalink
Merge branch 'development' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
1ForeverHD committed May 21, 2021
2 parents 08ffa35 + 8f96344 commit fc3d298
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 42 deletions.
7 changes: 7 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
157 changes: 116 additions & 41 deletions src/Zone/Signal.lua
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
2 changes: 1 addition & 1 deletion src/Zone/VERSION.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
-- v2.1.3
-- v2.2.1

0 comments on commit fc3d298

Please sign in to comment.