Page 1 of 1

Threads on 0.9.0

Posted: Sat Dec 28, 2013 10:41 pm
by fede0d
Hello everybody!
I'm making a game in which the world is generated randomly and it's infinite. I generate a 640x480 level png image when I need to and save it to a local folder.
The problem is that I need to reload these images on the fly as the game is running.
I figured out I need to use threads to load this images. The problem is that I don't know much about threads on LÖVE.

I have this on my main.lua

Code: Select all

channel = love.thread.getChannel("CHAN1");
	thread = love.thread.newThread("thread.lua"); 
	thread:start(); channel:push("uno.png");
	IMG = channel:demand();
	print(IMG);
And this on my thread.lua

Code: Select all

local channel = love.thread.getChannel("CHAN1");
local file = channel:demand();
local img = love.graphics.newImage(file);
channel:push(img);
I create a channel and a thread. I start the thread which is waiting for the filepath of the image. I push "uno.png" to the channel. This should trigger the demand() in the thread and should pop the value from the channel. Next the main file is waiting for a value on the channel, which I push in the thread file.
So the IMG variable should contain an image object.
But the print in the main.lua file it's printing "uno.png", as no thread loaded any image.

What am I doing wrong?

Re: Threads on 0.9.0

Posted: Sat Dec 28, 2013 11:30 pm
by DaedalusYoung
In thread.lua, you need to add the line

Code: Select all

require "love.graphics"
to be able to access graphics functions.

I only just started using threads today myself, so I may be wrong, but by having channel:demand(), you're basically still pausing code execution, so you might as well just load the image in the main thread. It'll be quick enough anyway.

Re: Threads on 0.9.0

Posted: Sun Dec 29, 2013 12:42 am
by fede0d
I tought channel:demand() paused the excecution of the thread only, not the main program.

Re: Threads on 0.9.0

Posted: Sun Dec 29, 2013 1:22 am
by DaedalusYoung
Well, I could be wrong, but I did found that channel:supply() halts the thread, so following that logic, calling channel:demand() from the main thread would halt the program.

The way I'm working with it now is having a loop checking for anything in the channel stack, that keeps the program going while the thread works and updates as soon as the thread is ready.
Kinda like this:

Code: Select all

if Channel:getCount() > 0 then
    value = Channel:pop()
end

Re: Threads on 0.9.0

Posted: Sun Dec 29, 2013 9:08 am
by bartbes
fede0d wrote:I tought channel:demand() paused the excecution of the thread only, not the main program.
.. what. It suspends whatever you run it in, why would it not demand when run in the main thread?
DaedalusYoung wrote: The way I'm working with it now is having a loop checking for anything in the channel stack, that keeps the program going while the thread works and updates as soon as the thread is ready.
Hello, race condition!
You probably just want to pop and see if you got a non-nil value.

Back to the topic, you do need to require love.graphics, and you can see this because the thread errors, the easiest way to develop with threads, in my experience is by adding this to your main.lua:

Code: Select all

function love.threaderror(t, e)
    return error(e)
end
Also important, as the giant warning says on the wiki DO NOT USE LOVE.GRAPHICS FROM ANYTHING BUT THE MAIN THREAD.

Re: Threads on 0.9.0

Posted: Sun Dec 29, 2013 3:40 pm
by fede0d
Thanks guys. I was wondering how to debug the threads.
Is this is the best way to load images on the fly?

Should I store the levels in another format? I'm using png images becouse it saves a lot of time. I just need to know the position and color of each pixel to know if its a solid wall or ground or part of the background with no collision.

Re: Threads on 0.9.0

Posted: Sun Dec 29, 2013 6:00 pm
by Robin
Just use a single thread. It won't slow down your game (unless you load an image every frame or something, but you shouldn't do that anyway, even with threads).