Page 1 of 1

Threads Coroutine and Other [SOLVED]

Posted: Sun Jan 20, 2013 12:42 am
by Kjell Granlund
Ok well I have dived into the deep end without knowing how to swim. I had a simple issue that I wanted to fix and now I have a few questions. First the issue was that when I ran my .love the screen would be white for 4 seconds or so. Not that much of a problem since it was loading everything. But rather than have a white screen, I wanted to have a loading screen. Thats where I took a dive into the deep end by googling and finally going to the irc channel. There I was told about roroutines. I have been programming for about two weeks now and reading the lua wiki I discovered I might be in over my head. Through more searching I found out about loves thread function. I read through that and looked onto the forums for examples. Again this seemed a bit much for what I was doing. So finally I thought on it for a simple 'fix'. I came up with this bit of code:

main.lua

Code: Select all

-- Battle System Concept v1.31
local loading = false
local loaded = true
local gameReady = false

function love.load()
	
end

function love.draw() -- main drawing function
	if loading == false then
		love.graphics.draw(love.graphics.newImage( "loading.jpg"),0,0)
		loaded = false
	end
	if gameReady == true then
		
		
		love.graphics.draw(gfx[1][1],0,0)
		love.graphics.draw(gfx[5][1],0,0)
		
		
	end
end

function love.update(dt) -- main updating function
	if loaded == false then
			dt = love.timer.getDelta( )
			require("Sounds.sound_loading")
			require("Objects.object_loading")
			require("Graphics.graphic_loading")
			require("Libraries.TLTools.tltools")
			require("Libraries.AnAL.AnAL")
			require("loveglobals")
			
			load_graphics()
			loading = true
			loaded = true
			gameReady = true
	end
	if gameReady == true then
	
	
	
	
	
	
	
	end
end
loveglobals.lua

Code: Select all

-- a suite of functions for graphics
lg = love.graphics
-- a suite of functions for keyboard input
lk = love.keyboard
-- a suite of functions for mouse input
lm = love.mouse
-- a suite of functions for playing audio
la = love.audio
-- a suite of functions for dealing with the file system
lf = love.filesystem
-- a suite of functions for working with images
li = love.image
-- a suite of functions for working with sounds
ls = love.sound
-- a suite of functions for working with threads
lt = love.thread
--a suite of functions for physics simulation
lp = love.physics
graphic_loading.lua

Code: Select all

-- gfx is shorthand for Graphics for the following

local files = " "
local gfx_background_table = {}
local gfx_button_table = {}
local gfx_effect_table = {}
local gfx_healthbox_table = {}
local gfx_hud_table = {}
local gfx_icon_table = {}
local gfx_ship_table = {}

function load_graphics()																								-- ** MIAN LOAD **

	-- table to contain graphics
	gfx = {}
		  
	-- each folder has its own function
	load_ships()
	load_buttons()
	load_effects()
	load_backgrounds()
	load_huds()
	load_icons()
	load_healthBox()

	-- holds all of the graphics in a table
	gfx = {	
		[1] = gfx_background_table,
		[2] = gfx_button_table,
		[3] = gfx_effect_table,
		[4] = gfx_healthbox_table,
		[5] = gfx_hud_table,
		[6] = gfx_icon_table,
		[7] = gfx_ship_table
		  }
	
end

function load_ships() 																									-- ** SHIPS **	
	files = love.filesystem.enumerate("Graphics/Ships/Small") -- makes a numbered list of the images
	for k, files in ipairs(files) do -- goes through the list in order
		gfx_ship_table[k] = love.graphics.newImage("Graphics/Ships/Small/" .. k .. ".png") -- sets each image to table
	end
end

function load_buttons()																									-- ** BUTTONS **
	files = love.filesystem.enumerate("Graphics/Buttons") -- makes a numbered list of the images
	for k, files in ipairs(files) do -- goes through the list in order
		gfx_button_table[k] = love.graphics.newImage("Graphics/Buttons/" .. k .. ".png") -- sets each image to table
	end
end	

function load_healthBox()																								-- ** HEALTHBOX **
	files = love.filesystem.enumerate("Graphics/Effects") -- makes a numbered list of the images 
	for k, files in ipairs(files) do -- goes through the list in order
		gfx_effect_table[k] = love.graphics.newImage("Graphics/Effects/" .. k .. ".png") -- sets each image to table
	end	
end

function load_effects()																									-- ** EFFECTS **
	files = love.filesystem.enumerate("Graphics/Effects") -- makes a numbered list of the images	 
	for k, files in ipairs(files) do -- goes through the list in order
		gfx_effect_table[k] = love.graphics.newImage("Graphics/Effects/" .. k .. ".png") -- sets each image to table
	end	
end

function load_backgrounds()																								-- ** BACKGROUND **
	files = love.filesystem.enumerate("Graphics/Backgrounds") -- makes a numbered list of the images	 
	for k, files in ipairs(files) do -- goes through the list in order
		gfx_background_table[k] = love.graphics.newImage("Graphics/Backgrounds/" .. k .. ".png") -- sets each image to table
	end
end

function load_huds()																									-- ** HUDS **	
	files = love.filesystem.enumerate("Graphics/Huds") -- makes a numbered list of the images	 
	for k, files in ipairs(files) do -- goes through the list in order
		gfx_hud_table[k] = love.graphics.newImage("Graphics/Huds/" .. k .. ".png") -- sets each image to table
	end	
end

function load_icons()																									-- ** ICONS **
	files = love.filesystem.enumerate("Graphics/Icons") -- makes a numbered list of the images	 
	for k, files in ipairs(files) do -- goes through the list in order
		gfx_icon_table[k] = love.graphics.newImage("Graphics/Icons/" .. k .. ".png") -- sets each image to table
	end	
end

function love.update(dt)																								-- ** MAIN UPDATE **

--[[	Examples of using animations
  
	gfx_effect_table[1]:update(dt)		-- Updating Animations
	gfx_effect_table[2]:update(dt)		-- Updating Animations
	gfx_effect_table[3]:update(dt)		-- Updating Animations
	gfx_effect_table[4]:update(dt)		-- Updating Animations
	gfx_effect_table[5]:update(dt)		-- Updating Animations
	gfx_effect_table[6]:update(dt)		-- Updating Animations
  
]]--
  
end
I know it is still a bit of a mess, though it is ALOT better than how I had it earlier. So this basically draws the loading image then 'freezes' while it actually loads the data. I think it is a poor solution for my problem, nut indeed it does what was intended. Now for my questions.

Seeing the code above you can tell I am loading the images into a master table for graphics. This allows me to call upon graphics pretty fast (draw a background with lg.draw(gfx[1][1],0,0) and there is the background or with lg.draw(gfx[1][x],0,0) so I can change x to what ever background depending on what is going on in the game). So which would be better? To use threads to run and return the gfx table or to use coroutine to again run and return the table. The reason is so I can have a small animated loading screen. Since I will have alot more calculations to do at the begining of the game, the load wait might become 10 seconds and thats a long time with no loading bar. Or perhaps I am going about this all wrong.

I hope most of this makes sense. Also as a side note, the graphic_loading.lua was made before the loveglobals.lua so that is why I am not utilizing it in there. I am also planning the creat a function to shorten the graphic_loading.lua. I know right not it repeats many times over. I will clean it up more soon. I hope I am posting this in the right place too...

Thanks

Re: Threads Coroutine and Other [UNSOLVED]

Posted: Sun Jan 20, 2013 1:24 am
by ejmr
The functions load_healthbox() and load_effects() both store images in the gfx_effects_table, which I am guessing is a bug.

If you use love.thread you will have limited communication between your thread(s) and the main thread, and on top of that not every love.graphic function will work in the extra thread you create. The wiki talks about this in the love.thread section. But I believe using love.thread results in better performance than coroutines. However, I do not have hard data to support that, only anectdotes of personal experience. If you use coroutines that would make the code more simple in my opinion and easier to follow. Those are some of the important things you should consider when deciding between the two approaches.

Re: Threads Coroutine and Other [UNSOLVED]

Posted: Sun Jan 20, 2013 1:46 am
by Kjell Granlund
ejmr wrote:The functions load_healthbox() and load_effects() both store images in the gfx_effects_table, which I am guessing is a bug.

If you use love.thread you will have limited communication between your thread(s) and the main thread, and on top of that not every love.graphic function will work in the extra thread you create. The wiki talks about this in the love.thread section. But I believe using love.thread results in better performance than coroutines. However, I do not have hard data to support that, only anectdotes of personal experience. If you use coroutines that would make the code more simple in my opinion and easier to follow. Those are some of the important things you should consider when deciding between the two approaches.
Thanks for the bug report. Fixed that. Well I see what you are talking about on the wiki about love.graphics. Perhaps to get by that I could create the table with all of the data in it and then pass that table into a string and send that string back to my main thread and convert the string into a table again. I am assuming that storing a function in a tables does not mean running that function. I do not know how to return data from a second thread though. As far as coroutine, I am just lost on how to use it from reading the wiki. Perhaps there is a better place to see code in use to learn from. As an added problem, my entities code is not working anymore. I will upload the .love that I have. I have not been able to figure out why the enemy is not moving. It creates it but for some reason it will not move. The code is not changed from earlier releases as far as that section is concerned...

** EDIT **
I am an idiot. I fixed the issue. I have the love.update function set in the graphic_load.lua such a fail...

Re: Threads Coroutine and Other [UNSOLVED]

Posted: Sun Jan 20, 2013 8:31 pm
by ejmr
Kjell Granlund wrote:Well I see what you are talking about on the wiki about love.graphics. Perhaps to get by that I could create the table with all of the data in it and then pass that table into a string and send that string back to my main thread and convert the string into a table again. I am assuming that storing a function in a tables does not mean running that function.
That is correct. Assigning a function does not execute it.

Note: A programmer could use metatables so that assigning a function to a table does call that function. But the only reason I can think of to do this is to make other programmers angry with you, lol.

If you want to pass that table information with Thread:set() you will need to serialize it into a string. There are various ways to do this, with different pros and cons. Here is a good list:

http://lua-users.org/wiki/TableSerialization

Sorry I cannot recommend what would be best for your needs though. All I can say is that if your table includes functions then that is going to complicate any serialization efforts. It is not impossible to do, just more difficult.
As far as coroutine, I am just lost on how to use it from reading the wiki. Perhaps there is a better place to see code in use to learn from.
The ‘Programming in Lua’ book has a chapter on coroutines:

http://www.lua.org/pil/9.html

The online version discusses Lua 5.0 though. So be sure to cross-reference that information with the Lua 5.1 manual on the subject:

http://www.lua.org/manual/5.1/manual.html#2.11