TList : AddLast etc...

BlitzMax Forums/BlitzMax Programming/TList : AddLast etc...

Hi

I'm a little bit lost whith the bmax tlink commands
(like addlast addfirst from blitz3D) Anybody can help
me ?

Original code (blitz3D) :

Graphics 500,500,0,2
	SetBuffer BackBuffer()
	SeedRnd MilliSecs()
	
	Type thingyT
		Field x%, y%
		Field width%, height%
		Field r%, g%, b%
	End Type
	
	; create some random 'thingies'.
	For n = 1 To 50
		this.thingyT = New thingyT
		this\width = Rand(30,100)
		this\height = Rand(30,100)
		this\x = Rand(0,500-this\width)
		this\y = Rand(0,500-this\height)
		this\r = Rand(20,255)
		this\g = Rand(20,255)
		this\b = Rand(20,255)
	Next
	
	While Not KeyHit(1)
		Cls
		If MouseHit(1) Then update_thingies()
		draw_thingies()
		Flip
	Wend
	
	End	

Function update_thingies()

	mx = MouseX()
	my = MouseY()
	
	this.thingyT = Last thingyT

	; We need to check through the thingy list backwards so that
	; a thingy overlapping another one is checked first.
	While this <> Null
		If (mx >= this\x) And (mx <= (this\x+this\width-1))	
			If (my >= this\y) And (my <= (this\y+this\height-1))	
				; This thingy has been clicked on so make it top thingy.
				Insert this After Last thingyT
				Return
			EndIf
		EndIf
		
		this = Before this
	Wend	

End Function

Function draw_thingies()

	For this.thingyT = Each thingyT
		Color this\r,this\g,this\b
		Rect this\x,this\y,this\width,this\height,True
		Color 255,255,255
		Rect this\x,this\y,this\width,this\height,False
	Next
	
End Function


My blitzmax code :

Graphics 640,480,0

Global thingyTList:TList=New TList
Global ThisLink:TLink=thingyTList.FirstLink()

Type thingyT
	Field x%, y%
	Field width%, height%
	Field r%, g%, b%
	
	Method New ()
		thingyTList.AddLast Self
  	End Method	

	Function Create:thingyT()
		Local B:thingyT = New thingyT
		Return B
	End Function
	
	Function Draw()
		For Local this:thingyT = EachIn thingyTList
			SetColor this.r,this.g,this.b
			DrawRect this.x,this.y,this.width,this.height
		Next
	End Function
	
	'Look the function update_thingies() in blitz3D code
	Function Refresh()
		Local Mx:Int=MouseX()
		Local My:Int=MouseY()
		
		ThisLink=thingyTList.LastLink()
		Local this:thingyT=thingyT(ThisLink.Value())
		
		While this <> Null
			If (mx >= this.x) And (mx <= (this.x+this.width-1))	
				If (my >= this.y) And (my <= (this.y+this.height-1))
				
				
				EndIf
			EndIf	
		Wend
	End Function
End Type


For n = 1 To 50
	Local this:thingyT=thingyT.Create()

	this.width = Rand(30,100)
	this.height = Rand(30,100)
	this.x = Rand(0,500-this.width)
	this.y = Rand(0,500-this.height)
	this.r = Rand(20,255)
	this.g = Rand(20,255)
	this.b = Rand(20,255)
Next
	
	
Repeat
	thingyT.Draw()
	
	If MouseHit(1) Then
	thingyT.Refresh()
	EndIf
	
	Flip
	Cls
Until KeyDown(key_escape)

End


why do you not just use for local t:thingyT = eachin thingyTList ...

Try changing AddLast to AddFirst and doing something like this for you update code:
Local Mx:Int=MouseX()
Local My:Int=MouseY()

Local newlist:TList = thingyTList.Copy()

For Local this:thingyT = EachIn thingyTList
    If (mx >= this.x) And (mx <= (this.x+this.width-1)) And ..
        (my >= this.y) And (my <= (this.y+this.height-1))

        newlist.Remove( this )
        newlist.AddFirst( this )

    EndIf
Next

thingyTList.Clear()
thingyTList = newlist
newlist = Null ' precaution


I have to admit though, I'm somewhat confused. You wrote a GUI for BMax, and you're not sure how linked lists work? O_o

Might explain why users of the library opted it to tripple the speed ^^

Pure Cane Soda : You are right it's strange :) Maybe an alien
instead me, wrote the library? :) i understand the method
EachIn without problem but the approach via while / Wend
and tlink is maybe usefull too? Thanks for your help :)

Edit :
But as you can see the list in the blitz code is browsed
from the last to the first. the method eachin browse the
list from start to end. This is why I am asking the
question about the tlink :)

Dreamora : What? :/

Filax, I think you are looking for TLink.PrevLink:TLink() and TList.InsertAfterLink:TLink(value:Object, pred:TLink)

You are right David! but the doc do not really help me :/

Does this help?

Pseudocode:

Local link:TLink = List.LastLink()

While link

	If TListItemType(link.Value()) = ItemWeAreSearchingFor
		List.InsertAfterLink(NewListItem,link)
		Exit
	EndIf

	link = PrevLink()

Wend


the approach you use there makes only partially sense.

what makes more sense is to store the TLink you get from addFirst / AddLast when adding an element to the object that you added.
That allows you to get the previous / next element of each element in the list as well as removing it instantanous from the list if needed.
moving it around the list is as well no problem

I'll try others methods, thanks for help :)

here is an extended list I did where you can go from any link forwards or backwards
http://www.blitzbasic.com/codearcs/codearcs.php?code=1807

Thanks Dmaz i'll take a look ;)

Did you know, that eachin is that intelligent to only return values of a certain type? I didn't until now...

 Type TA
 end type
 
 type TB
 end type
 
 
 local lst:TList=new TList
 
 lst.AddLast(new TA)
 lst.AddLast(new TB)
 
 for local obj:TA=eachin lst
 	print ("I'm only of Type TA")
 Next


Until now I thought that obj will be Null for TB-objects.

Blitzmax is such a lovely language!