Rely on newest call of a function

Basically, as of right now, I’m checking whenever a text change happens, and then showing, text before waiting a few seconds to remove it, however, if I click it a lot of times, then the text only shows up for a split second (as time has passed since the first call)

LockedLabel:GetPropertyChangedSignal('Text'):Connect(function()
	wait(3)
	LockedLabel.Text = ''
end)

Is there a better way to do this, so if this is already running (waiting) and it’s called again, to break the original call and only use the newest call

1 Like
local RunService = game:GetService("RunService");
local t = tick();
local change = false;

LockedLabel:GetPropertyChangedSignal('Text'):Connect(function()
	t = tick() + 3;
    change = true;
end)

RunService.Heartbeat:Connect(function()
    if change then
    	if tick() >= t then
            LockedLabel.Text = '';
            change = false;
        end
    end
end)
2 Likes
LockedLabel.Changed:Connect(function(property)
 if property == "Text" then
  wait(3)
  LockedLabel.Text = ''
 end
end)

You need to check what property was changed.

1 Like

That literally does the same thing as what I currently have tho

1 Like

This one is more convenient for me.
What are you trying to do.

1 Like

This may sound way too simple but have you tried maybe using a for loop for the wait and breaking it when another function is called?

1 Like

I would do something like this:

local RunService = game:GetService("RunService");

local heartbeat, latestChange
LockedLabel:GetPropertyChangedSignal('Text'):Connect(function()
	latestChange = tick()
	if not heartbeat then
		heartbeat = RunService.Heartbeat:Connect(function()
			if tick()-latestChange >= 3 then
				LockedLabel.Text = ''
				heartbeat:Disconnect()
				heartbeat=nil
			end
		end)
	end
end)
5 Likes

Here is what I always do. It is very simple.

local clickcounter = 0

LockedLabel:GetPropertyChangedSignal('Text'):Connect(function()
	clickcounter = clickcounter + 1
	local localcounter = clickcounter
	wait(3)
	if localcounter == clickcounter then
	    	LockedLabel.Text = ''
	end
end)
1 Like

personally, this is what i use, it’s just like using delay(t, callback)

local threads = {}

local function nwait(t, f)
	threads[#threads + 1] = tick()
	
	while tick() - threads[#threads] < t do service.RunService.Stepped:wait() end
	
	spawn(f)
	
	table.remove(threads, threads[#threads])
end

I am confused. Why not just use a very simple and efficient debounce?

local LockedLabelDebounce = false
LockedLabel:GetPropertyChangedSignal('Text'):Connect(function()
    if not LockedLabelDebounce then
        LockedLabelDebounce = true
	    wait(3)
	    LockedLabel.Text = ''
        LockedLabelDebounce = false
    end
end)

Because if you call the function and then after 2 seconds you call it again you want it to clear the text 3 seconds after the second call now, not 3 seconds after the first one. So the ‘countdown’ has to be updated and your function does not allow the second call to update the countdown.

I don’t see how nwait could be used in this case as your function makes a queue of calls.
For example:

nwait(1, f)
nwait(1, f)
nwait(1, f)

would execute f three times but we only want to keep the last call.

Try this, no loops or RenderStepped/Heartbeat event handlers.

local mostRecentCall = nil

LockedLabel:GetPropertyChangedSignal('Text'):Connect(function()
	local t = tick()
	mostRecentCall = t
	wait(3)
	if t == mostRecentCall then
		LockedLabel.Text = ''
	end
end)
1 Like