layered TList

BlitzMax Forums/BlitzMax Programming/layered TList

I'm not sure if I re-invented someones wheel here... I'm not sure how helpful this will be but I thought I would share anyway.

Normally I use separate renderLists for different types of objects in my code... like a list of hud objs, enemy sprite, bullets, particles... This time I was playing around where all sprites where in the same list but I still wanted basic z-ordering. well, not really z-ordering, more like layers. so I extended TList to incorporate layers that are pre-sorted so you don't have to ever do the a Sort() (too slow for many objects) on them.

When I create sprite renderLists I always keep track of the TLink from the list so I can remove the sprite (among other things) without having to search the list with ListRemove (very bad). I would imagine that many of us do this.

Type TSprite Extends TObject
	Global renderList:TList		= New TList
	
	Field renderListLink:TLink	= Null

...
	
	Method New()
		renderListLink = renderList.AddFirst(Self)
		count :+ 1
	End Method
	
	Method Remove()
		renderListLink.Remove	'remove self from renderList
		count :- 1
	End Method
...
so the idea was to just put some fake objects in the list first and keep track of the links so I could then call InsertBeforeLink(). All I do is keep track of the TLinks of a few fake objects in the list using the array layers. then when adding an object I insert it before the layers TLink... I do it before to perserve the sorting of that layer (first in first to draw)
Type TLayerMeta
	Field nothing:Int
End Type

Type TLayerList Extends TList
	Field totalLayers:Int = 0
	Field layers:TLink[]
	Field userObjectLink:TLink 'TLink to users inserted object
	
	' funtions -------------------------------------
	Function Create:TLayerList( totalLayers:Int=4 )
		Local list:TLayerList = New TLayerList
		list.totalLayers = totalLayers
		list.layers = New TLink[totalLayers]
		
		For Local i:Int = 0 To totalLayers-1
			list.layers[i] = list.AddLast(New TLayerMeta)
		Next
		
		Return list
	End Function

	' methods --------------------------------------	
	Method AddToLayer:TLink( value:Object,layer:Int )
		userObjectLink = InsertBeforeLink( value,layers[layer] )
		Return userObjectLink
	End Method
	
	Method RemoveFromLayer()
		userObjectLink.Remove
	End Method
	
End Type
It worked great, but I have one question. can anybody tell me why when I do this
For Local box:TBox = EachIn TBox.renderList
I only seem to be getting back actual TBox types... none of the TLayerMeta come back... this is good, makes it cleaner but does EachIn only return the ask for types or is something wrong here?

here is a full test program, any thoughts?
SuperStrict

Type TLayerMeta
	Field nothing:Int
End Type

Type TLayerList Extends TList
	Field totalLayers:Int = 0
	Field layers:TLink[]
	Field userObjectLink:TLink
	
	' funtions -------------------------------------
	Function Create:TLayerList( totalLayers:Int=4 )
		Local list:TLayerList = New TLayerList
		list.totalLayers = totalLayers
		list.layers = New TLink[totalLayers]
		
		For Local i:Int = 0 To totalLayers-1
			list.layers[i] = list.AddLast(New TLayerMeta)
		Next
		
		Return list
	End Function

	' methods --------------------------------------	
	Method AddToLayer:TLink( value:Object,layer:Int )
		userObjectLink = InsertBeforeLink( value,layers[layer] )
		Return userObjectLink
	End Method
	
	Method RemoveFromLayer()
		userObjectLink.Remove
	End Method
	
End Type

Type TBox
	Global renderList:TLayerList = TLayerList.Create(5)
	
	Field x:Float
	Field y:Float
	Field width:Float
	Field height:Float
	Field layer:Int
	
	' funtions -------------------------------------
	Function Create:TBox( x:Int,y:Int,width:Int,height:Int,layer:Int=0 )
		Local box:TBox = New TBox
		box.x = x
		box.y = y
		box.width = width
		box.height = height
		box.layer = layer
		renderList.AddToLayer(box,layer)
		Return box
	End Function
	
	Function DrawAll()
		For Local box:TBox = EachIn TBox.renderList
			box.Draw()
		Next	
	End Function
	
	' methods --------------------------------------	
	Method Remove()
		renderList.RemoveFromLayer()
	End Method
	
	Method Draw()
		SetColor 50+layer*40,50+layer*40,50+layer*40
		DrawRect(x,y,width,height)
		SetColor 0,0,0
		DrawText(layer,x,y)
	End Method
	
End Type

Graphics 800,600

TBox.Create(50,20,50,50,2)
TBox.Create(10,10,50,50,1)
TBox.Create(0,0,150,150,0) ' even though this is insert in the middle it will actually be at the beginning of the list.
Local b:TBox = TBox.Create(30,50,50,50,1)


While Not KeyHit(KEY_ESCAPE)
	Cls
	TBox.DrawAll()
	If KeyDown(KEY_SPACE) And b<>Null
		b.Remove
		b = Null
	End If
	
	Flip 1
Wend


Sorry for my bad english.

I have certain code that is useful for you.
The code is a prioritary queue. Is posible whit this traverse the que in certain order and modify the order of any object. This is very eficient for typical zorder draws.

if you need this code mail to me in comun@...

bye,
Paposo