mapPixel in thread 0.9.1

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Ryan1729
Prole
Posts: 2
Joined: Sun Feb 23, 2014 8:17 am

mapPixel in thread 0.9.1

Post by Ryan1729 »

Hi. I'm trying to use ImageData:mapPixel in a thread.

main.lua

Code: Select all

function love.load()
    -- setup thread
    thread = love.thread.newThread("thread.lua")
    toThreadChannel = love.thread.getChannel("toThread")
    fromThreadChannel = love.thread.getChannel("fromThread")
    
    thread:start()
    
    winW = love.graphics.getWidth()
    winH = love.graphics.getHeight()
    imageData = love.image.newImageData(winW, winH)
    
    image = love.graphics.newImage( imageData )
    
    toThreadChannel:push(imageData)
    
    print("loaded")
end

function love.draw()
   
    local tempImageData = fromThreadChannel:pop()
    print("popped")
    if tempImageData then
        print("recieved Image")
        imageData = tempImageData
        image = love.graphics.newImage( imageData )
    else 
        print("no image recieved")
    end
    
    love.graphics.setColor(255,255,255,128)
    love.graphics.draw(image)
    
end

function love.keypressed(key)
    if  key == "q" or key == "escape" then
        love.event.push('quit')
    end 
    
end
thread.lua

Code: Select all

print("thread started")

toThreadChannel = love.thread.getChannel("toThread")
fromThreadChannel = love.thread.getChannel("fromThread")

function drawFunction(x, y, r, g, b, a)
-- perform computations giving the new values for r, g, b and a
    a = 255 
    r = x*y
    g = x*y
    b = x*y  
    return r, g, b, a
end

print("waiting on imageData")
imageData = toThreadChannel:demand()
print("got it: ".. type(imageData))

imageData:mapPixel( drawFunction )

print("sending image")
fromThreadDataChannel:push(imageData)
print("sent")
When I run it I get the following output:

Code: Select all

thread started
waiting on imageData
loaded
got it: userdata
popped
no image recieved
popped
no image recieved
popped
no image recieved
popped
no image recieved
popped
no image recieved
popped
no image recieved
popped
no image recieved
... and so on. Basically, everything is working until the actual imageData:mapPixel( drawFunction ) call. And since it's in a thread apparently that means no error message at all. :ehem:
Attachments
testthread.love
(1.77 KiB) Downloaded 123 times
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: mapPixel in thread 0.9.1

Post by bartbes »

You can use the love.threaderror callback to get any error messages in a thread.
User avatar
slime
Solid Snayke
Posts: 3162
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: mapPixel in thread 0.9.1

Post by slime »

You need to explicitly require love modules you want to use in a thread (aside from love.thread itself). require("love.image") in this case.

As bartbes mentioned, adding something like this to main.lua will help with debugging:

Code: Select all

function love.threaderror(thread, err)
    error(err)
end
Ryan1729
Prole
Posts: 2
Joined: Sun Feb 23, 2014 8:17 am

Re: mapPixel in thread 0.9.1

Post by Ryan1729 »

It all works now. Thanks for the help!
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: mapPixel in thread 0.9.1

Post by Ref »

Failed to point out that you not only added require '"love.image" but changed
:

Code: Select all

fromThreadDataChannel:push(imageData)
to

Code: Select all

fromThreadChannel:push(imageData)
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: mapPixel in thread 0.9.1

Post by Ref »

Wondering if anyone has a better thread handshake library?
This is what I've hacked together so far:

Code: Select all

local threadcode	= {}

threadcode.thread = {}
threadcode.thread.ReceiveChannel	= love.thread.getChannel( 'toThread' )
threadcode.thread.SendChannel		= love.thread.getChannel( 'fromThread' )

function threadcode.thread.receive()	-- thread loops until data received
	print( 'thread: waiting' )
	local dat	= nil
	while not dat do dat = threadcode.thread.ReceiveChannel:demand() end
	print( 'thread: received '.. type( dat ) )
	threadcode.thread.SendChannel:push( dat )	-- confirm receiving without expecting response
	return dat
	end

function threadcode.thread.send( dat )
	print( 'thread: sending '..type( dat ) )
	threadcode.thread.SendChannel:push( dat )
	print( 'thread: '..type( dat )..' sent' )
	local Received = false		-- delay until received
	while not Received do Received = threadcode.thread.receive() end
	end

threadcode.main = {}
threadcode.main.SendChannel	= love.thread.getChannel( 'toThread' )
threadcode.main.ReceiveChannel	= love.thread.getChannel( 'fromThread' )

function threadcode.main.send( dat )
	print( 'main: sending '..type( dat ) )
	threadcode.main.SendChannel:push( dat )
	print( 'main: '..type( dat )..' sent' )
	threadcode.main.receiveConfirmation()	-- main blocked
	end

function threadcode.main.requestData()		-- non-blocking, checking availability
	print( 'main: waiting for reply' )
	local data = threadcode.main.ReceiveChannel:pop()
	if data then
		print( 'main: '..type(data)..' received' )
		threadcode.main.send( true )		-- confirm reception
		end
	return data
	end

function threadcode.main.receiveConfirmation()	-- blocking until transfer confirmed
	print( 'main: waiting confirmation' )
	dat	= nil
	while not dat do dat = threadcode.main.ReceiveChannel:demand() end
	print('main: Glad to hear thread received '..type( dat ))
	return dat
	end

return threadcode
Attached demo really not a good example of what a thread should be used for.
Note: addition of collectgarbage( 'collect' ) need to compensate for memory leak.
EDIT: Attached file does not run via forum. Runs fine if download to my computer - a window machine. Cause unknown????
EDIT: Only runs in original folder. All components present in zip. All files lower case. Doing something obviously wrong! Help!
EDIT: For some reason, didn't like my require in the thread? Replaced thread functions directly into thread. Reloaded demo.
EDIT: Dumb mistake. In thread, I required 'love.filesystem' AFTER require 'threadcode'.
Attachments
threadtest.love
Simple test of a thread.
(110.31 KiB) Downloaded 111 times
Last edited by Ref on Wed Jun 18, 2014 11:04 pm, edited 1 time in total.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: mapPixel in thread 0.9.1

Post by bartbes »

Something like my async library? The docs aren't really there yet, but the example pretty much shows all of it.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: mapPixel in thread 0.9.1

Post by Ref »

Thanks bartbes!
Will have to see how your code works.
Look forward for some docs.
Best!
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 3 guests