Waiting to Fire

So I have an announcement system where the maximum in the scroll frame is 5, how to make if an admin make an announcement but the scroll frame children is 5 already, it will wait until scroll frame children below 5 and fire the announcement automatically.

1 Like

Use :GetChildren like so:

while #Frame:GetChildren() >= 5 do task.wait() end
-- Fire the announcement
1 Like

Is it gonna affect the performance? I mean we’re talking let’s say about massive players doing it.

You can use get children like above, except before the
#Frame:GetChildren
make sure to put
if 5>=
This way it checks if there is less or the same as 5 frames. If there is more than you can do an else function and make it wait until that does equal true.

Edit:

Turns out the first code should work fine…

task.wait should be fast enough, but if there is a significant drop in performance, you could use Instance.ChildRemoved:

Frame.ChildRemoved:Connect(function()
    if #Frame:GetChildren() < 5 then
        -- Fire the anouncement
    end
end)

Yup, well why I said wait until below 5, because obviously the announcement has time, but you know all players / admin maybe they don’t know right, so I always put my situation in the worst case when more than 5 people fire announcement at the same time.

Either way, it should be fine. You should only be worried if you’re not properly cleaning up after your code.

I think it would be better to use repeat in this context

repeat task.wait() until #Frame:GetChildren() >= 5
1 Like

Do you mean until <= 5? Does it affect much performance, I mean if it’s just a little bit, it doesn’t really matter tho.

1 Like

Like using :Destroy() that kind of thing?

1 Like

You could possibly have your system work like this:

  • Admin requests to make announcement
  • Attempt to broadcast announcement if there are less than 5 visible announcements at the time
  • If there are 5+ visible announcements already, add the announcement to a queue (table)
  • Upon an announcement finishing/removing, if there is an announcement in the queue, remove it from the queue and broadcast it

This method also is great performance-wise as you do not have any waiting loops.

Yes this is how I want, but how to make if there are 5+ visible ad to queue table, is it the same like above or you have different method? and also your fourth point how to make if there is a queue, remove it from the queue and broadcast it.

Yes, :Destroy() for instances, :Disconnect() for connections, etc.

Here’s an example script:

local broadcasted = 0
local queue = {}

function broadcast(message,duration)
 -- broadcast using your code
 broadcasted += 1
 task.wait(duration)
 broadcasted -= 1
 local n = queue[1]
 if n then
  table.remove(queue,1)
  broadcast(n,duration)
 end
end

function request(message)
 if broadcasted < 5 then
  broadcast(message,10)
 else
  table.insert(queue,message)
 end
end

Wait then how to use the request function?

Ah nvm. Char…. I’ll try. Thank you.

But where should I put this, because I use FireAllClients on Server Script and OnClientEvent on Local Script.

This is my latest script, I think I got error because it’s always looping.

-- Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Events
local eventsFolder = ReplicatedStorage.Events
local announcementEvent = eventsFolder.Announcement

-- Modules
local modulesFolder = ReplicatedStorage.Modules

-- Prefix
local Prefix = "!"

local broadcasted = 0
local queue = {}

local function getKeyFromId(keyId)
	for key, keyTable in pairs(queue) do -- iterate over myTable
		if keyTable == keyId then
			return key
		end
	end
end

function announcement(player, message)
	broadcasted += 1
	print(broadcasted)
	announcementEvent:FireAllClients(player, message)
	task.wait(6)
	broadcasted -= 1
	print(broadcasted)
	local message = queue[player]
	local playerName = getKeyFromId(message)
	if message then
		announcement(playerName, message)
		table.remove(queue, table.find(queue, message))
	end
end

function requested(player, message)
	if broadcasted < 1 then
		announcement(player, message)
	else
		table.insert(queue, message)
		queue[player] = queue[1]
		queue[1] = nil
	end
end


Players.PlayerAdded:Connect(function(Player)
	Player.Chatted:Connect(function(Chat)
		local Split = Chat:split(" ")
		local Command = Split[1]
		if Command == Prefix.."n" then
			local Arguments = string.sub(Chat, string.len(tostring(Prefix).."n".."  "))
			if Arguments then
				requested(Player, Arguments)
			end
		end
	end)
end)

Why it’s still firing up even if child is above that amount.