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.
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.