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 Jun 4, 2021
2 parents 8cdcafd + 0cc06c8 commit 44c16ac
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 43 deletions.
9 changes: 8 additions & 1 deletion docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
## [2.2.1] - May 7 2021
## [2.2.2] - June 4 2021
### Improved
- The accounting of character parts when removed/added via systems like HumanoidDescriptions.



--------
## [2.2.1] - May 21 2021
### Added
- Compatibility for Deferred Events

Expand Down
91 changes: 57 additions & 34 deletions src/Zone/Signal.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
--[[
This is a simplified version of Quenty's Nevemore Signal Class.
I've stripped this down for improved traceback debugging as I don't mind if the table received is not the same which was passed.
If passing the same table is important for you, see: https://github.com/Quenty/NevermoreEngine/blob/a98f213bb46a3c1dbe311b737689c5cc820a4901/Modules/Shared/Events/Signal.lua
--]]



local HttpService = game:GetService("HttpService")
local RunService = game:GetService("RunService")
local heartbeat = RunService.Heartbeat
local Signal = {}
Signal.__index = Signal
Signal.ClassName = "Signal"
Expand All @@ -14,67 +9,95 @@ Signal.totalConnections = 0


-- CONSTRUCTOR
function Signal.new(trackConnectionsChanged)
function Signal.new(createConnectionsChangedSignal)
local self = setmetatable({}, Signal)

self._bindableEvent = Instance.new("BindableEvent")
if trackConnectionsChanged then

if createConnectionsChangedSignal then
self.connectionsChanged = Signal.new()
end

self.connections = {}
self.totalConnections = 0
self.waiting = {}
self.totalWaiting = 0

return self
end



-- METHODS
function Signal:Fire(...)
self._bindableEvent:Fire(...)
for _, connection in pairs(self.connections) do
connection.Handler(...)
end
if self.totalWaiting > 0 then
local packedArgs = table.pack(...)
for waitingId, _ in pairs(self.waiting) do
self.waiting[waitingId] = packedArgs
end
end
end
Signal.fire = Signal.Fire

function Signal:Connect(handler)
if not (type(handler) == "function") then
error(("connect(%s)"):format(typeof(handler)), 2)
end

local connection = self._bindableEvent.Event:Connect(function(...)
handler(...)
end)

-- If ``true`` is passed for trackConnectionsChanged within the constructor this will track the amount of active connections
local signal = self
local connectionId = HttpService:GenerateGUID(false)
local connection = {}
connection.Connected = true
connection.ConnectionId = connectionId
connection.Handler = handler
self.connections[connectionId] = connection

function connection:Disconnect()
signal.connections[connectionId] = nil
connection.Connected = false
signal.totalConnections -= 1
if signal.connectionsChanged then
signal.connectionsChanged:Fire(-1)
end
end
connection.Destroy = connection.Disconnect
connection.destroy = connection.Disconnect
connection.disconnect = connection.Disconnect
self.totalConnections += 1
if self.connectionsChanged then
self.totalConnections += 1
self.connectionsChanged:Fire(1)
local heartbeatConection
heartbeatConection = game:GetService("RunService").Heartbeat:Connect(function()
if connection.Connected == false then
heartbeatConection:Disconnect()
if self.connectionsChanged then
self.totalConnections -= 1
self.connectionsChanged:Fire(-1)
end
end
end)
end

return connection
end
Signal.connect = Signal.Connect

function Signal:Wait()
local args = self._bindableEvent.Event:Wait()
local waitingId = HttpService:GenerateGUID(false)
self.waiting[waitingId] = true
self.totalWaiting += 1
repeat heartbeat:Wait() until self.waiting[waitingId] ~= true
self.totalWaiting -= 1
local args = self.waiting[waitingId]
self.waiting[waitingId] = nil
return unpack(args)
end
Signal.wait = Signal.Wait

function Signal:Destroy()
if self._bindableEvent then
self._bindableEvent:Destroy()
self._bindableEvent = nil
if self.bindableEvent then
self.bindableEvent:Destroy()
self.bindableEvent = nil
end
if self.connectionsChanged then
self.connectionsChanged:Fire(-self.totalConnections)
self.connectionsChanged:Destroy()
self.connectionsChanged = nil
self.totalConnections = 0
end
self.totalConnections = 0
for connectionId, connection in pairs(self.connections) do
self.connections[connectionId] = nil
end
end
Signal.destroy = Signal.Destroy
Expand Down
2 changes: 1 addition & 1 deletion src/Zone/VERSION.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
-- v2.2.1
-- v2.2.2
52 changes: 45 additions & 7 deletions src/Zone/ZoneController.lua
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,33 @@ local heartbeatActions = {
-- CHARACTER HANDLER
-- This enables character data (volume, HumanoidRootParts, etc) to be handled on
-- an event-basis, instead of being retrieved every interval
local function updateCharactersTotalVolume()
local function preventMultiFrameUpdates(func)
-- This prevents the funtion being called twice within a single frame
-- If called more than once, the function will initally be delayed again until the next frame, then all others cancelled
local callsThisFrame = 0
local updatedThisFrame = false
local newFunc = function(...)
callsThisFrame += 1
if not updatedThisFrame then
local args = table.pack(...)
coroutine.wrap(function()
heartbeat:Wait()
updatedThisFrame = false
if callsThisFrame > 1 then
callsThisFrame = 1
return func(unpack(args))
end
callsThisFrame = 0
end)()
updatedThisFrame = true
return func(...)
end
end
return newFunc
end

local updateCharactersTotalVolume
updateCharactersTotalVolume = preventMultiFrameUpdates(function()
charactersTotalVolume = 0
bodyParts = {}
-- We ignore these due to their insignificance (e.g. we ignore the lower and
Expand All @@ -131,13 +157,21 @@ local function updateCharactersTotalVolume()
for _, part in pairs(plr.Character:GetChildren()) do
if part:IsA("BasePart") and not bodyPartsToIgnore[part.Name] then
table.insert(bodyParts, part)
local connection
connection = part:GetPropertyChangedSignal("Parent"):Connect(function()
if part.Parent == nil then
connection:Disconnect()
updateCharactersTotalVolume()
end
end)
end
end
end
end
end
players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
end)

local function playerAdded(player)
player.CharacterAdded:Connect(function(char)
local humanoid = char:WaitForChild("Humanoid", 3)
if humanoid then
updateCharactersTotalVolume()
Expand All @@ -150,10 +184,14 @@ players.PlayerAdded:Connect(function(plr)
end
end
end)
end)
players.PlayerRemoving:Connect(function(plr)
end
players.PlayerAdded:Connect(playerAdded)
for _, player in pairs(players:GetPlayers()) do
playerAdded(player)
end
players.PlayerRemoving:Connect(function(player)
updateCharactersTotalVolume()
playerExitDetections[plr] = nil
playerExitDetections[player] = nil
end)


Expand Down

0 comments on commit 44c16ac

Please sign in to comment.