Help with cancelling a wait

Hello.

Basically, I’m trying to do something really simple, When a value is changed, it waits 4 seconds and resets the value, but i want so it wont reset if the value was changed (even if its the same value) while it was waiting (so it doesn’t mess up timing) is there some sort of way to cancel the wait? I don’t really see much about it here on the dev forum.

Script:

ValueThing.Changed:Connect(function)
	ClearValue(ValueThing.Value)
end)

function ClearValue(Val)
	if ValueThing then
		wait(4)

		if ValueThing.Value == Val then
			ValueThing.Value = ""
		end
	end
end

Any help?

3 Likes

something like this should work

ValueThing.Changed:Connect(function)
	ClearValue(ValueThing.Value)
end)

function ClearValue(Val)
	if ValueThing then
		local StartTick = os.time()
		
		repeat 
			task.wait()
		until (os.time()-StartTick >= 4) or (ValueThing.Value ~= Val)

		if ValueThing.Value == Val then
			ValueThing.Value = ""
		end
	end
end
4 Likes

Completely forgot to mention (My bad.) but i’d also need so if the value is changed right before the 4 seconds are up, and its the same value, i still want it to reset the value, sorry, should’ve mentioned that.

2 Likes

Usually i would add threading:

ValueThing.Changed:Connect(function()
   ClearValue()
end)

local waitingThread
function ClearValue()
   if waitingThread then
      task.cancel(waitingThread)
   end
   waitingThread = coroutine.running()
   task.wait(4) -- when the waiting thread gets "cancelled", it won't run past this line.
   ValueThing.Value = ""
   waitingThread = nil
end
3 Likes

Times like this you would need to create a timer and update it every time “ValueThing” is changed.
Instead you are creating a new timer every time “ValueThing” is changed.

local valueThingTable = {}

ValueThing.Changed:Connect(function()
	ClearValue(ValueThing.Value)
end)

function ClearValue(Val)
	if not valueThingTable.Timer then
		valueThingTable.Timer = 4
		valueThingTable.Val = Val
		repeat
			valueThingTable.Timer -= 1
			task.wait(1)
		until valueThingTable.Timer <= 0
		valueThingTable.Timer = nil
		if ValueThing.Value == valueThingTable.Val then
			ValueThing.Value = ""
		end
	else
		valueThingTable.Timer = 4
		valueThingTable.Val = Val
	end
end

Try this. Now every time ClearValue() is called, it will create a timer if there is no current timer. But if there is already a timer still counting, it will just update that timer instead.

3 Likes

It returns an error saying that it cannot cancel the thread, I barely use threading so I’m not sure how to fix it.

2 Likes
local thread = task.spawn(ClearValue, Val)

--when you want to stop it before wait(4) finishes:
task.cancel(thread)

Also use task.wait, wait is deprecated.

3 Likes

I forgot that coroutine and task libraries doesn’t mix well…
Here’s the fixed version.

local waitingThread
ValueThing.Changed:Connect(function()
   if waitingThread then
      task.cancel(waitingThread)
   end
   waitingThread = task.delay(4,ClearValue)
end)

function ClearValue()
   ValueThing.Value = ""
   waitingThread = nil
end
3 Likes

It gave the same error, stating that the thread cannot be canceled, sorry for bothering alot, i just never made something to what im currently making

2 Likes

I’m a bit confused, I don’t usually use threading, so I don’t know how to set it up.

2 Likes

Not sure if you tried it but I had a typo and fixed it. Mb for that

3 Likes

That’s odd, thought it would work…
In that case, i’ll use benchmarking similar to the other examples:

ValueThing.Changed:Connect(function()
   ClearValue()
end)

local timerStart
function ClearValue()
   if timerStart then
      timerStart = os.clock()
      return -- just resets the timer and does nothing
   end -- otherwise performs a delayed clear.
   timerStart = os.clock()
   while os.clock() - timerStart < 4 do
      task.wait()
   end
   ValueThing.Value = ""
   timerStart = nil
end
3 Likes

“Val” Is not a number, its a string, I’m kinda of confused of what the code is supposed to do.
Its giving the error “attempt to perform arithmetic (sub) on string and number”

I believe its because the Timer value is set to Val for some reason, but in the script, timer is referenced to be a number.

2 Likes

It seems to still run the wait even when the value is changed, Is there something else i should add to it to stop the wait?

2 Likes

oh I didnt know that. I changed it so you can check it to see if it works as intended

2 Likes

Still didn’t stop the wait, i really don’t know what im doing wrong here.

1 Like

Im a bit confused. So you want it to just stop the old timer and create a new one?

3 Likes

I’ll kind of just explain what im going for in general.

I want so when the value is changed, it waits 4 seconds, if the value was changed again (even if its the same value) while the wait was running, then the wait will not proceed, if nothing changed during the wait running, then set the value to " ".

2 Likes

Just use task.delay()?

1 Like

task.delay() where? i don’t understand what you mean.

1 Like