Help with best practice to keep generic textures loaded between storyboard scenes

If I have many storyboard scenes and one or two textures and sounds that are common to all of them… what is the best practice to keep the common stuff loaded and available for use by all of the scenes? [import]uid: 126708 topic_id: 23543 reply_id: 323543[/import]

You can load them on main.lua as global variables.

image = display.newSomething(...)  
sound = audio.load(...)  

They become available on the whole project.

You have to keep in mind that if you’re talking about images, they will be showing on screen during the whole app, so you’ll have to hide them when not needed. If it’s a imagesheet, it should be fine as that doesn’t have any visual representation. [import]uid: 61899 topic_id: 23543 reply_id: 94510[/import]

Everywhere I look I see talk about how global vars are bad.
What exactly is the bad thing (if any) when doing it this way? [import]uid: 126708 topic_id: 23543 reply_id: 94512[/import]

There’s nothing wrong with global variables. I think people exagerate a lot about them!

They are a bit slower to access. Accesing a global variable require an extra table lookup than a local variable. But if you think how significant this is compared to all the rest of the thousand lines of code… it’s quite irrelevant, unless you use it all the time!

If you want so bad to have the images or sounds referenced by a local variables, you can do as I said and then in each scene you do:

local sound = sound  

So now, that “sound” variable which was global, has a local reference to it that uses the same name so you don’t even have to change anything.

Your solution is an overkill! In Lua when you require something, the result of the require goes into a special table of requires. If you require twice a certain file it will not do anything as it already has a reference to that module on the requires table. There is no object notion in Lua, so a certain module is unique, you can’t require it twice and get 2 copies of it, you require it once and then you can use it. And unless you unrequire it, it will be there ready for later use.

So basically what you did in your example was that you created a whole complex structure just to save a value inside a table (result of requiring that module).

So now, instead of having an extra cost of a table lookup, for using a global variable, you have a require of that module, and that implies file I/O for reading it, you have 11 new lines of code to be parsed, you have during that require 2 attributions of functions to the M table which means another table lookup for each, then from the outside of the module, when you call for setResult, it needs another table lookup to find “setResult” inside the M table, then when retrieving it, you’ll need that much for the getResult once again.

See… Going miles to have everything local, sometimes actualy makes the code itself go miles too. [import]uid: 61899 topic_id: 23543 reply_id: 94528[/import]

Excellent explanation. Thanks very much. [import]uid: 126708 topic_id: 23543 reply_id: 94542[/import]

Not really expected as it wouldn’t work like this in normal programming, but trying the following actually worked…

[lua]local M = {}

local result = ‘blah’

local GetResult = function()
return result
end
M.GetResult = GetResult

local SetResult = function(s)
result = s
end
M.SetResult = SetResult

return M[/lua]

“require” the above in two different scenes, set the result to ‘Hello’ in the first scene, destroy the scene then load the second scene and show the result… the result is still changed to ‘Hello’, it does not return back to ‘blah’.

A variation on the above to store images and so on looks like a neater and non-global way to do this.

Any comments from the Corona pros? [import]uid: 126708 topic_id: 23543 reply_id: 94518[/import]

The way Corona handles images in memory is that images are cached according to the file name the first time you load it.

So if in scene1 you have

[lua]local _g = display.newImage( “blah.png” )[/lua]

and in scene2 you do

[lua]local _h = display.newImage(“blah.png”)[/lua]

The image “blah.png” is already in memory and isn’t loaded again.

What I do is preFetch some images in my first scene and put them off screen somewhere. You don’t have to use globals to take advantage of image memory caches. [import]uid: 44647 topic_id: 23543 reply_id: 94545[/import]

OK, that actually answers another of my questions.

Curious though, how does Corona deal with the following then…?

Image.png (50x50)
ImageX2.png (100x100)
[lua]local _g = display.newImageRect(“Image.png”, 80, 80)[/lua]and then in scene 2…
[lua]local _h = display.newImageRect(“Image.png”, 30, 30)[/lua]I really hope that in this case _h will NOT use a scaled down version of the 100x100 or already scaled 80x80 image, but that it rather loads a new scaled version of the 50x50 image. [import]uid: 126708 topic_id: 23543 reply_id: 94724[/import]

Creating global vars and textures etc in my main.lua file… I take it I don’t have to free them then?

(Since I can’t see a way to free them) [import]uid: 126708 topic_id: 23543 reply_id: 94749[/import]

If you simply cache images in memory but then keep asking for newImageRect, while you will get rid of the loading to memory of the image, you will still call for a recreation of the display object table in Lua, in every scene.

Asking for this newImageRect is WAY more expensive than just using a simple global variable that already has the whole display object structure created and that you reuse every time.

It is more expensive even before you actualy start doing anything, as “display” is also a global variable, so just accessing it already has the same overhead as accessing the global variable which would hold the display object. Then you have to access the “newImageRect” field, which is another table lookup, so by the time Lua finds out where the function “newImageRect” from the table “display” exists in memory, you’ve already wasted twice the work of accessing an already created display object, referenced using a global variable. [import]uid: 61899 topic_id: 23543 reply_id: 94752[/import]

I will answer to your question about using 2 different images and using them with different sizes and such later, after I confirm some things, so I don’t say anything wrong.

About freeing the memory used by the images, you can do it as you do with any other:

Display Objects:

image:removeSelf()  
image = nil  

Sounds:

audio.dispose(sound)  
sound = nil  

If you use the images/sounds during the whole app, you have no need of freeing it. Just let them be. When the app is closed, they will be removed automaticaly. [import]uid: 61899 topic_id: 23543 reply_id: 94753[/import]