Ez task.wait() from ground up

local thread = coroutine.running() 
local start = os.clock() 
task.delay(2, function() 
  local finish = os.clock() 
  task.spawn(thread, finish - start) 
end) 

local passed = coroutine.yield(thread) 
print("Nya!", passed)

^
For the people who dont know how to stop and resume the thread. E.g. for custom BindableEvent:Wait()

6 Likes

why would this be used? just use task.wait()

5 Likes

i mean yeah, for funzies prob >.<, and for learning

2 Likes

That’s too overcomplicated for negative gain.
Just use regular task.wait, or in case you want to run code in deferred time:

task.defer(coroutine.running())
coroutine.yield()

Way too short of a tutorial anyway
I suggest you expand on explaining how coroutine.running and coroutine.yield work for beginners so your post has any value.

Creation and use of custom signals is way too niche anyway, and I find the only use of them inside games that support modding; otherwise, this paradigm is just straight-up bloatware that slows down the game for no benefit.

1 Like

about bloat is also true, the one i made is a short form for task.wait(2) with full task.wait functionality. task.wait apparently returns time passed

1 Like

I agree, there’s a lack of actual “tutorial” here, its more or less just a code drop with very little explanation

1 Like

:collision:Used to break the wait.

local thread = coroutine.running() 
local stopped = false
task.delay(5, function() 
	if not stopped then
		coroutine.resume(thread)
		print("After 5s")
	end
end) 
somePart.Touched:Once(function()
	stopped = true
	coroutine.resume(thread) 
	print("interrupted")
end)
coroutine.yield(thread) 

No one saw it coming.

1 Like

Am I missing context here? What’s the point in resuming a variable named thread with coroutine.running()? What does coroutine.running() do when you resume it?

coroutine.running() apparently returns the current thread which is being executed. if you do coroutine.yield(), it will block the execution of the current thread, but you can wake it up by calling it with coroutine.resume() or task.spawn()

1 Like

so if you resume thread in that scenario you’re returning the task.delay function?

i didnt quite get what you mean

in the scenario lumizk sent

local thread = coroutine.running() 
local stopped = false
task.delay(5, function() 
	if not stopped then
		coroutine.resume(thread)
		print("After 5s")
	end
end) 
somePart.Touched:Once(function()
	stopped = true
	coroutine.resume(thread) 
	print("interrupted")
end)
coroutine.yield(thread) 

code does
task.wait(5) or Touched wakeup (what comes first)

just to simplify

somePart.Touched:Timeout(5):Wait() --just in case Timeout(5) doesnt exist

Oh okay, so coroutine.running() returns the most active thread that is currently running, that makes sense now. Idk what would happen if you had 2 simultaneous threads at once. And then the script is just to make the code interrupt itself within 5 seconds if touched before then so you can make things happen early or stop code from commencing after a duration.

usually you have 1 thread all the time. I think you create other thread when you do smth like task.spawn .delay, Event connection, separate script.

luau is singlethreaded, meaning each thread is going to be executed somewhat fully before going to the next thread, or when the thread yields, it’s going to go to the next one i think.

with this code

local thread = coroutine.running()  -- get reference to the current thread
task.delay(2, function()  -- create new thread that will resume the current thread
  task.spawn(thread) -- use the saved reference to unpause this thread
end) 

coroutine.yield(thread) -- stop the current thread
1 Like

about being single threaded meaning no matter how hard / big / complex the function is, it’s going to execute it fully before going to the other functions i think

so

task.spawn(function() --eventho it's a separate thread, and the function is expensive
  -- it's going to execute it fully before continuing to the line with print
  -- because it doesnt yield (smth like calling task.wait() inside will yield it)
  local result = SomeExpensiveFunction()
end)

print("Hi")

it sucks that i cant task.cancel the thread unless i reference it as a variable, instead i have to use coroutine.running() on a coroutine thread, then i have to yield it afterwards. but the new systems like task.delay and task.spawn dont support canceling them unless you reference them as variables

e.g

-- with coroutine

coroutine.create(function()
	task.wait(5)
	print("Hello World!")
end)

local thread = coroutine.running()
coroutine.yield(thread)


-- with task.delay

local referenced
referenced = task.delay(5, function()
	print("Hello World")
end)
task.cancel(referenced)

-- coroutine
local delay_thread = coroutine.create(function()
	task.wait(5)
	print("Hello World!")
end)
-- after creation, you have to resume it when using coroutine library
coroutine.resume(delay_thread); 
task.wait(.2);
task.cancel(delay_thread)


-- with task.delay

local referenced = task.delay(5, function()
	print("Hello World")
end)
task.wait(.2)
task.cancel(referenced)

apparently coroutines produce the same threads as task.spawn, delay etc., but i think task library simplified some stuff

i’m so dissapointed that you cant just unwait the function

1 Like

well task.delay doesn’t actually start a thread until the delay time is up, it simply tells the task scheduler to start X thread at X frame, while task.spawn instantly splits into another thread

Hmm, interesting. I think it’s a bit different, but i might be be wrong.
print(coroutine.status(task.delay(5, function() end)))
^ returns a new thread that is suspended

type of code i’d make if i got paid per line of code bro