Queuing Events

Hello currently I am working on a UI tween with functions going across to a module and for there it runs the tween, but I am sending over different info every time for example ‘Reveal UI’, ‘unBlurScreen’ ect.

But one thing I have tried and had a look around was trying to put the functions into a queue. For example - With debounce you can only run the tween when debounce == false. But I would like it, some how, where I could put the functions into a queue while debounce is on so it runs one at a time, and it runs in the order I click it.

Eg - Click a button on a GUI and tween begins, but at the same time i click a button on a brick in the world while the tween is still active.
Is there anyway to make it wait till the tween has finished and then it runs the block clicked function?

Sorry if this was confusing and always willing to try to explain it more. Thank you in advance.

1 Like

Please read category guidelines before posting threads. Cool Creations is for showcasing creations you’ve made and for getting feedback on them, not for requesting help with development issues. The Help and Feedback category has other subcategories you can search through to check if your thread more appropriately fits there.

I’ve moved this to Scripting Support which is where you can get help on programming-related troubles.

When I picked my category, I am pretty sure I picked help and feedback but I am unsure, thank you anyway.

It’s pretty simple actually:
First we need metatables so we have a “changed” event.
Then we use some events
and we end up with this:

-- this code moves a part up and down, but both tweens can be added to the queue at the same time.
local TweenService = game:GetService("TweenService")
local Info = TweenInfo.new(10) -- 10 second tween
local Queue -- create a queue variable
local CurrentRunning -- make a variable for what we're currently running in the queue
local CurConnection -- prevent memory leaks

function UpdateQueue()
	print("Running")
	CurrentRunning = Queue[1]
	CurrentRunning:Play() -- be wary, no type checking so it could call :Play() on a non tween object.
	CurConnection = CurrentRunning.Completed:Connect(function()
		CurrentRunning:Destroy() -- destroy the tween object
		CurConnection:Disconnect()
		table.remove(Queue, 1) -- remove it
		if Queue[1] ~= nil then
			UpdateQueue()
		end
	end)
end

local QueueMeta = {
	__newindex = function(tableAccessed,key,value) -- Used for firing the "changed" event
		rawset(tableAccessed,key,value) -- IMPORTAINT! Rawset does not fire the metamethod, if you simply set, it will break and fall into an infinite loop
		print(key, value, "Added")
		if CurrentRunning == nil then
			UpdateQueue()
		end
	end,
}
Queue = setmetatable({}, QueueMeta)

local Tween1 = TweenService:Create(workspace.Part, Info, {Position = Vector3.new(0,50,0)})
local Tween2 = TweenService:Create(workspace.Part, Info, {Position = Vector3.new(0,15,0)})
-- small thing with metatables, you cannot use table.insert.
Queue[#Queue + 1] = Tween1 -- add Tween1 to the queue at the back, which in this case is #1
Queue[#Queue + 1] = Tween2 -- again, add a tween to the back of the queue
1 Like

Thank you very much! Worked as expected.

First of all, sorry for bumping this topic. I have a similar problem but I can’t seem to figure out the concept behind meta tables. Can you help me a little? This is my code:

local debounce = false
local function add (message)
	while debounce  do
		wait(.1)
	end
	debounce = true

    --ui stuff below--

	local cloned = addFrame:Clone()
    addFrame.TextLabel.Text = message
	cloned.Parent = frame
	local targetPosition = UDim2.new(0, 0, 0.5, 0)
	local tweenInfo = TweenInfo.new(
		1,
		Enum.EasingStyle.Quint,
		Enum.EasingDirection.Out
	)
	local theTween = TweenService:Create(cloned, tweenInfo, {Position = targetPosition})
	theTween:Play()
	local conn
	conn = theTween.Completed:Connect(function()
		print("complete ")
		debounce = false
	    cloned:Destroy()
		conn:Disconnect()
	end)

    --ui stuff above
	
end
game.ReplicatedStorage.Add.OnClientEvent:Connect(add)

So basically, the remote event is allowed to fire anytime. The client side should display a ui using tween, which all works perfectly fine. I used the debounce to make sure that all the events from the server are not lost. But the order will get mixed up. How do I make it have queue so that the order won’t be mixed up? Thank you so much!

Use tables and recursion:

local Queue = {}

function add (message, Recursion)
	if not Recursion then
		table.insert(Queue, message)
	elseif #Queue == 0 then
		return
	end
	if #Queue ~= 1 and not Recursion then
		return 
	end
	
	--ui stuff below--

	task.wait(1)
	print("waited", message)
	
	--ui stuff above
	table.remove(Queue, 1)
	add(Queue[1], true)
end
game.ReplicatedStorage.RemoteEvent.OnClientEvent:Connect(add)

Imo, this is simpler to understand.
Apologies for my late reply, I don’t often check the devforum now haha.

thx‎‎‎‎‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎