Managing resources

BlitzMax Forums/BlitzMax Beginners Area/Managing resources

degac(Posted 2006) [#1]
Hi to all.
After a long break I'm writing a little library for my projects: its goal is to manage every resource I load.
But I'm thinking on its working way. Here it's a little extract
Type tresource
	Field tipo:Int
	Field file:Object
	Field handle:Object
	
	Global tresource_list:TList=New TList
			
	Function ResLoadImage:timage(url:Object,parameter=-1)
			DebugLog "GCMemAlloced "+GCMemAlloced()
			Local temp_image:timage=LoadImage(url,parameter)
			If temp_image=Null DebugLog "NO image! "+String(url);Return
			Addresource(url,temp_image)
			Print "Load image"
			Return temp_image
	End Function
	
	Function AddResource(url:Object,handle:Object)
			If url=Null Or handle=Null Return
			Local tres:tresource=New tresource
				tres.file=url
				tres.handle=handle
				tresource_list.addlast(tres)
			DebugLog "ADD RESOURCE:["+GCMemAlloced()+"]"
	End Function
	
	
	Function ClearAll(fine:Int=0)
		GCCollect
		DebugLog "Clear resource"+GCMemAlloced()
		For Local i:tresource=EachIn tresource_list
			i.handle=Null
		Next
		ClearList tresource_list
		If fine=1 tresource_list=Null
		GCCollect
		DebugLog "FREED: ["+GCMemAlloced()+"]"
	End Function 
End Type

Graphics 640,480

Global myimage:timage=tresource.ResLoadImage("gfx/back3.png")


DrawImage myimage,0,0
Global myimage:timage=tresource.ResLoadImage("gfx/back3.png")


DrawImage myimage,0,0
Flip
WaitKey
tresource.ClearAll()
'myimage=Null <--- with this I'm OK
Cls
DrawImage myimage,0,0
Flip
WaitKey
End


The program itself is very stupid: in this case I want to load an Image and I use the .ResLoadImage() function I created. The reference is returned to main program and stored in the tresource_list.
My problem is: when I call tresource.ClearAll() it DOESN'T DESTROY the resource because there is myimage still live...
How do you resolve this, if possibile? Yes I know I'm lazy, and that the best solution is to keep track 'by hand' of all the resources used...

This is the second way (not very easy to manage). It's the same thing, but I return to main program a TResource reference, that I need to cast manually as I need.

Type tresource
	Field tipo:Int
	Field file:Object
	Field handle:Object
	
	Global tresource_list:TList=New TList
			
	Function ResLoadImage:tresource(url:Object,parameter=-1)
			DebugLog "GCMemAlloced "+GCMemAlloced()
			Local temp_image:timage=LoadImage(url,parameter)
			If temp_image=Null DebugLog "NO image! "+String(url);Return
			Local han:tresource=Addresource(url,temp_image)
			Print "Load image"
			Return han
	End Function
	
	Function AddResource:tresource(url:Object,handle:Object)
			If url=Null Or handle=Null Return
			Local tres:tresource=New tresource
				tres.file=url
				tres.handle=handle
				tresource_list.addlast(tres)
			DebugLog "ADD RESOURCE:["+GCMemAlloced()+"]"
			Return tres
	End Function
	
	
	Function ClearAll(fine:Int=0)
		GCCollect
		DebugLog "Clear resource"+GCMemAlloced()
		For Local i:tresource=EachIn tresource_list
			i.handle=Null
		Next
		ClearList tresource_list
		If fine=1 tresource_list=Null
		GCCollect
		DebugLog "FREED: ["+GCMemAlloced()+"]"
	End Function 
End Type

Graphics 640,480

Global myimage:tresource=tresource.ResLoadImage("gfx/back3.png")

DrawImage timage(myimage.handle),0,0' I need to cast it manually...
Flip
WaitKey
Print GCMemAlloced()
tresource.ClearAll()
'myimage=Null
Cls
DrawImage timage(myimage.handle),0,0
Flip
WaitKey
End


This works like I want, but the price is to 'cast' to the right object the reference passed...

PS: I wrote different module for my projects (particle, sprite, animated background and so on) so there are many resources involved, and a system like this I think is useful...


bregors(Posted 2006) [#2]
.


Grisu(Posted 2006) [#3]
Why use GCCollect() when bmx has a built in garbage collector?

Isn't this sort of handling your data slowing the whole app down a lot?


degac(Posted 2006) [#4]
In fact it is just an idea to see if it is worth or not.
The basic solution is to manage all the resources by hand (global image:timage=LoadImage() and then image=NULL), but if you have many resources (images, anim_images, sounds...) and you need to load/unload them at some point this is very costly (well I think so): logo image,title image, menu music, player image (this could be loaded once), particle image, level music, gfx level and so on...(these could change every level).
Moreover in the full code I added a log function to check if & when any resource is missing and so on...
GCCollect is only to force BMax to release resource (the OS behind I think...)
OK...back to the old system so.
Thanks again.