Noob: TList Question

BlitzMax Forums/BlitzMax Beginners Area/Noob: TList Question

MGE(Posted 2008) [#1]
I don't even want to touch the IDE again until I see the answer....if the answer to this question is "yes"...then I'm going to feel very foolish because I've been doing things the hard(er) way for about a year now....

Can a Tlist contain a list of different object types? If the answer is "yes" then I ASSume I could just go through the list of objects and call each object's update and render method.


Perturbatio(Posted 2008) [#2]
The answer is yes, now get back to work. :)

You would have to test which object type it is and cast it as such before calling the render method, unless you extend them all from a base class that implements these methods, in which case you should be able to cast them all as that class and invoke.


MGE(Posted 2008) [#3]
Thank you.

Now if you don't mind, I'm going to log off my computer, go have a few beers and marvel at the fact how stupid I have handled things in my code the past year.

Then....when I sober up I will realize just how much more efficent and logical I can code things now.

fkin eh.... !@#$%^&^%$#*@#!


Perturbatio(Posted 2008) [#4]



MGE(Posted 2008) [#5]
Perturbatio - Thanks for the Matrix like awakening. :)

I'm still drinking though...........


Otus(Posted 2008) [#6]
One of the most useful things IMHO is that you can target only objects of one type in the list using the EachIn loop like this:

For o:TMyType = EachIn list
  'Do something
Next


Whereas using o:Object would loop through the whole list. This is also a good way to ensure every object in the loop is of your base type:

For bc:TBaseClass = EachIn list
  bc.Render
Next



slenkar(Posted 2008) [#7]
didnt know you could do that Otus, quite useful!


dmaz(Posted 2008) [#8]
Whereas using o:Object would loop through the whole list.

well, the For loop does actually loop through the whole list... but the body will only be performed on a successful assignment.


Grey Alien(Posted 2008) [#9]
YES! haha, doh ;-) You shoulda looked at my framework more closely, I have ParticleLists, ImageLists, SoundLists, String Array lists, etc. oh and AOTMG has Alien and Bullet lists ;-p

Using a list for Strings only is totally underusing it's power. But now of course we know about TMaps!


MGE(Posted 2008) [#10]
Well.. I'm still stumped! I want to create a tlist of different objects and just iterate through a list and call each objects update and render. Sumpin like this:

'
Type TObjects
 '
 Field TObjectsList:TList
 '
 Method Update()
  For Local o:Object = EachIn TObjectsList
   o.Update()
  Next
 End Method
 '
 Method Render()
  For Local o:Object = EachIn TObjectsList
   o.Render()
  Next
 End Method
 '
End Type
'
Type TBaseObject
 '
 Field x:Float,y:Float
 '
 Method Render()
  ' draw here
 End Method
 '
End Type
'
Type TObject1 Extends TBaseObject
 Method Update()
  x = x +1 
 End Method
End Type
'
Type TObject2 Extends TBaseObject
 Method Update()
  x = x +1 
 End Method
End Type


But this little bit of code won't even compile. Says it can't find "Update". Any help is appreciated, thanks.


GfK(Posted 2008) [#11]
You need to cast the returned object. Eg.

 Method Update()
  For Local o:Object = EachIn TObjectsList
   TObject1(o).Update()
  Next
 End Method


Might need to have an ID:Int field in each type, since the above code will likely throw an error if the object was originally a TObject2.


Grey Alien(Posted 2008) [#12]
Better still stick a blank Update() method in TBaseObject and typecast o as TBaseObject, then I think it should polymorphically call the correct Update method...

e.g.

Strict

Type base
	Method do()
	End Method
End Type

Type a Extends base
	Method do()
		Print "a"
	End Method
End Type

Type b Extends base
	Method do()
		Print "b"
	End Method
End Type

Local aa:a= New a
Local bb:b= New b

base(aa).do()
base(bb).do()


Yeah dude, I know I ROCK! ;-p


MGE(Posted 2008) [#13]
wow...I owe for this one, I'm working on a basic gui system and I wanted to make a list that holds all of the objects, and now...thanks to you I can proceed! You truly rock. wow..

'
SuperStrict
'
Type TObjects
 '
 Field TObjectsList:TList
 '
 Method Update()
  For Local o:TBaseObject = EachIn TObjectsList
   o.Update()
  Next
 End Method
 '
 Method Render()
  For Local o:TBaseObject = EachIn TObjectsList
   o.Render()
  Next
 End Method
 '
 Method Init()
  TObjectsList = New TList
 End Method
 '
 Method AddNewTObject1()
  Local ob:TObject1 = New TObject1 
  ob.y=10
  ListAddLast(TObjectsList,ob)
 End Method
 '
 Method AddNewTObject2()
  Local ob:TObject2 = New TObject2 
  ob.y=100
  ListAddLast(TObjectsList,ob)
 End Method
 '
End Type
'
Type TBaseObject
 '
 Field x:Float,y:Float
 '
 Method Render()
  DrawText "Object",x,y
 End Method
 '
 Method Update()
 End Method
 '
End Type
'
Type TObject1 Extends TBaseObject
 Method Update()
  x = x + 1
 End Method
End Type
'
Type TObject2 Extends TBaseObject
 Method Update()
  x = x + 2
 End Method
End Type
'
Global MyObjects:TObjects = New TObjects
'
MyObjects.Init()
MyObjects.AddNewTObject1()
MyObjects.AddNewTObject2()
'
Graphics 800,600,0,60
'
Repeat
 Cls
 MyObjects.Update()
 MyObjects.Render()
 Flip(1)
Until KeyHit(KEY_ESCAPE)
'
EndGraphics()
End



Philip7(Posted 2008) [#14]
Actually, the 'correct' way to declare sub-methods in your base-type is:

Method Update() Abstract

*no End Method needed

In your way you have an actual method in your base type which is overriden by the existence of the method in the subclass.
With the abstract declaration you create a pointer to the method of the subtype.

Ofcource, when you have multiple subtypes which have exactly the same method then you want that method only once in your basetype and then you use your way.

Wow, some old java knowledge just popped up there in my head :)


Gabriel(Posted 2008) [#15]
Yep, Abstract methods are the "correct" way here, in the same way that SuperStrict is "correct". Having a blank method in the base type works, but only if you remember to override the methods in every type which inherits from the base type. When you declare the method abstract, you ensure that you can never forget, because you will not be permitted to instantiate that type unless you write the method.


MGE(Posted 2008) [#16]
Awesome, thanks. Abstract works like a charm. :)


Grey Alien(Posted 2008) [#17]
Yeah I forgot to say about abstract, I use it for my TScreen Type for example.


MGE(Posted 2008) [#18]
I just wanted to say thanks again to GA and everyone who helped me to understand this. I can't believe how much easier and more importantly "easier" the code is to grasp and work with. I've had a very productive weekend!!! :)


Grey Alien(Posted 2008) [#19]
Cool. OOP and Polymorphism is pretty neat when you figure out what it can do.