Page 1 of 1

Attempt to yield across C-call boundary

Posted: Sat Jul 04, 2015 2:24 pm
by DataBrain
So I'm trying to make a global function _G.wait(sTime), and it does the same thing as love.timer.sleep, only it will hault the current thread running rather than the whole window. This allows my to yield the main thread, but not love.draw or love.update. Here's what's going on:

Code: Select all

_G.GlobalData = {}

MainWaiting = false
MainWaitingTimer = 0

_G.wait = function(sTime)
	MainWaitingTimer = sTime or 1 / 30
	MainWaiting = true
	coroutine.yield()
end

function love.load(arg)
	GlobalData.MainThread = coroutine.create(function() -- This will separate the game from the main thread calling love.update and love.draw. 
		wait(2)
		require("MainMenu")()
	end)
	coroutine.resume(GlobalData.MainThread)
end

function love.update(deltaTime)
	if MainWaiting then
		MainWaitingTimer = MainWaitingTimer - deltaTime
		if MainWaitingTimer < 0 then
			MainWaiting = false
			coroutine.resume(GlobalData.MainThread)
		end
	end
end
MainMenu.lua:

Code: Select all

return function()
	print("Hello, World!")
end
This code will, successfully, wait two seconds before starting up the main menu.

However, when I try waiting inside the main menu file, rather than inside main.lua, it will give me this error:
Error: Attempt to yield across C-call boundary.

Debugging the traceback of the callstack, I've pinpointed the problem.
traceback.png
traceback.png (3.76 KiB) Viewed 3020 times
The problem, I found was that that the require() function is a C function, meaning when I try yielding, it will halt the thread past a C function.

Is there any good way to get around this? I want to be able to use multiple files in order to organize my game efficiently. And I also want to run the game's thread separate from the thread that love.draws and love.updates in order to time my game into a certain sequence (For cutscenes and such) within the same function.

Re: Attempt to yield across C-call boundary

Posted: Sat Jul 04, 2015 3:49 pm
by Xgoff
move the require outside of the coroutine, save its result into a local, then call that result from inside the coroutine instead

Re: Attempt to yield across C-call boundary

Posted: Sat Jul 04, 2015 5:02 pm
by DataBrain
Xgoff wrote:move the require outside of the coroutine, save its result into a local, then call that result from inside the coroutine instead
Thank you. This works perfectly.

I rewrote the require script to wait for the main thread to require the script on love.update, then resume it with the required variable returned.

It seems a bit hacky, but it works, so whatever.