reload tImages at runtime

BlitzMax Forums/BlitzMax Programming/reload tImages at runtime

z4g0(Posted 2008) [#1]
Hi!
I have a large number of "Global" tImage variables.
for example
...
...
...
Global IMG_TitleBG:TImage = LoadImage("Style\" + Style + "\Title.png") 
Global IMG_FormBG:TImage = LoadImage("Style\" + Style + "\shade1.png") 
Global IMG_FormBG1:TImage = LoadImage("Style\" + Style + "\shade2.png") 
...
...
...

and draw it simply..
DrawImage IMG_TitleBG,0,0 
..etc


now, I need to reload all these global image, with a new "Style" path component, in runtime:
there's a way to do it not manually for each variable?

something like that
Global IMG_TitleBG:TImage = LoadImage("Style\" + Style + "\Title.png") 
img[0]:tImage = IMG_titleBG
.....
......
'replace image
img[0]=  LoadImage("Style\" + *NEW*Style + "\Title.png")
 


obviously it don't works: changing "img" doesn't affect IMG_TitleBG.

And i can't add a
"IMG_titleBG = img[0]"
else I must do it for each global images, coming back at the start point.




I thought to use an auxiliar tMap (or tList) populated in an alternative "loadImage_2()" function that load and return a tImage var, and also add the ptr of this image in a the tMap.

But I'm stucked here: then how can I replace the pointed area with a new loaded image? I think that's not possible :(

I'm also looking at Reflection, but in docs I only saw it used on Type and Type's istances, not simply Global variables.


Dreamora(Posted 2008) [#2]
do NOT initialize the global in the same line as you declare it and it will work!

-> this
Global IMG_TitleBG:TImage = LoadImage("Style\" + Style + "\Title.png")

must become
Global IMG_TitleBG:TImage
IMG_TitleBG = LoadImage("Style\" + Style + "\Title.png")


tonyg(Posted 2008) [#3]
I would use a Media or Resource Manager to keep track of loaded objects and do a SetLoadPath with LoadAll and/or ReloadAll methods.


z4g0(Posted 2008) [#4]
-> this
Global IMG_TitleBG:TImage = LoadImage("Style\" + Style + "\Title.png")

must become
Global IMG_TitleBG:TImage

IMG_TitleBG = LoadImage("Style\" + Style + "\Title.png")



but in this case still the problem to do a "reload" function where I change all global image manually
like
function reloadStyle()
  IMG_TitleBG = LoadImage("Style\" + Style + "\Title.png") 
  IMG_FormBG = LoadImage("Style\" + Style + "\shade1.png") 
  IMG_FormBG1 = LoadImage("Style\" + Style + "\shade2.png") 
  ....
  ....
end function


and that is the thing I want, if possible, bypass.

I want turn it in something like
function reloadStyle()
  '''for each Global images As node of a TList / TMap '''
       node = loadImage(..."+newStyle+"...)
  '''next'''
end function

continuing using global images like now.

I would use a Media or Resource Manager to keep track of loaded objects and do a SetLoadPath with LoadAll and/or ReloadAll methods.

yes, using an auxiliar data structure was the idea... but cointainings what?
couse I want cointinue to draw these images using
drawImage IMG_FormBG...

and NOT, for example
drawImage tImage(StyleMngr.valueForKey("IMG_FormBG"))..

or
drawImage2("IMG_FormBG")
where drawImage2 is a function that return tImage from the data structure of style manager..

[EDIT]
mmm I can add images in tlist/tmap, and, not reload it with a loadImage (that create a new tImage, losing link at the gloabal variable), but "simply" replacing theirs PixMap!


tonyg(Posted 2008) [#5]
You have a Resource type with filepath, Filename, filesize whatever which extends into Image_Resource etc.
Your ResoureManager checks the extension of each file in your Media directory (and any sub-directories) set using a SetMediaPath command and loads the resource using LoadImage, LoadSound or whatever.
The returned TImage, TSound pointer is stored in a field of a TResource Instance. The TResource instance is saved in a TMap with the key being the Filename of the resource.
When using the resource you simply use the Map Key
(e.g. "Myimage") in your own Drawimage.
A Generic Handle-Based Resource Manager is quite good but I understood Can We Handle it? a bit better.

<edit> Sorry about the first link but it has a '~' in it which seems to naff up the link code.


Dreamora(Posted 2008) [#6]
You can not bypass that function. At least not just like that.

Main problem is that you want the "professional" solution for loading but the noob kiddie solution for using the data (this means you have no sprite class but want to use the regular draw command with a given variable name instead of lookup the name or use a sprite class which handles everything). The combination of that will not really work as you can not evaluate variable names at realtime.

My suggestion for your problem:
Create a Sprite Class or something the like with a draw method.
That sprite method holds the name of the element (similar to your current IMG_FormBG) and the TImage handle. Potentially you can as well put scale, position and rotation in if you ever intend to use them for more (like animation).
As well give the class the possibility to load an image to replace the current one. lets say ChangeImage(path:string)

Store these Sprites in a list, the same list you use for all other objects (I would suggest using the Sprites for them as well!). Don't forget to store the TLink within the sprite for fast remove - repositioning within the list.

For faster lookup on reload and "name based operations" place the sprite as well within a TMap using its name.

Now drawing is as simple as looping over the list and call the draw method.
Altering the image is as simple as lookup the image by name in the tmap and call ChangeImage(path). From the next loop over the list on the new image will be drawn.


z4g0(Posted 2008) [#7]
thanks :)
ATM I'm not using map/list for direct draw 'couse I have a lot of draw call: I thought that the access through tMap fields was too slower than using a global variable for a massive use of tImage...

if you tell me that's not too slow, I'll bring the global images into tMap nodes: At the moments in my program, except the Istances of the Managers (ie programManager, fileManager etc..), the images of skin are the only Global variables I'm using..


Dreamora(Posted 2008) [#8]
TMap is in the order of log2(n) lookup wise. so you would need to have a large amount of objects to make it "slow" ...
Its slower than local global, but not a real problem.

Though using TSprite or TUIElement (selfwritten classes) still might be (management wise) a better solution on the long run as they only need to do one lookup, when you change the image. afterwards they hold the image reference. This would be the best of both worlds ie a SpriteFactory that creates Sprites by name (lookup in TMap) but uses the images straight by type reference.


z4g0(Posted 2008) [#9]
cool, I think i'll bring it in tMap's node so...

tnx ;)