Still have questions? Join our Discord server and get real time help.
2

# How can I prevent a callback from yielding?

eLunate 5112
4 years ago

So, because I develop Valkyrie I have to consider all of the consequences of allowing external code and callbacks. One of the issues I've run into is that I have a callback which can be run before events to cancel them, but the callback mustn't yield so that the event connections can be fired off at the same time as the event is fired off.

How am I able to detect if a function would yield in this case, without having to actually wait through a yield? My original thoughts were to use pcall, but I've been told that pcall was changed a while ago to accept yielding just as ypcall did.

As a side note, using it as a callback for a C function has been considered however I need the returns from the callbacks to be returned back through the source function. Tricky.

0
I know how to use coroutines but I don't see the usefulness in this case where I need the callback to be a blocking action. eLunate 5112 — 4y
0
you went to school right? then you should know the answer x_adams 4 — 1y

1
BlueTaslem 17978
4 years ago

You can use a C callback to prevent yields, but still get return values. Something like this:

function noyield(f)
local t = {1, 2}
local r
pcall(function()
table.sort(t, function()
r = {f()}
end)
end)
if type(r) == "table" then
return unpack(r)
end
end


Unfortunately, if f calls wait() or one of it's friends, you'll get an error message after ROBLOX tries to resume it. This doesn't actually affect the script as far as I can tell, but might be clutter in the output you don't want.

00:04:44.804 - cannot resume non-suspended coroutine 00:04:44.804 - Script 'ServerScriptService.Script', Line 18 - upvalue f 00:04:44.805 - Script 'ServerScriptService.Script', Line 6 00:04:44.805 - Script 'ServerScriptService.Script', Line 5 00:04:44.805 - Stack End

EDIT: I consider the second error message to be a bug, and have reported it to ROBLOX. Hopefully it will eventually be fixed.

0
I ideally didn't want to use a wrapper function, but it's better than the alternative where I use metamethods to do it. Plus I don't think there's any other way. The clutter isn't an issue as I can just echo it all out. eLunate 5112 — 4y