Looping trough a type?

BlitzMax Forums/BlitzMax Programming/Looping trough a type?

bytecode77(Posted 2008) [#1]
hi!

is there a way to loop trough a type without using a TList?

i mean like this
for blah:somelist = eachin somelist
    ....
next



Dreamora(Posted 2008) [#2]
If you store the types in a list, then yes, then thats the correct way actually :)

It is done by using the Iterator implemented for tlist.


bytecode77(Posted 2008) [#3]
the what?
can you please show me a lil example :) ?

you know, i'm beginning to learn bmax and i dont know nothing about it...


Sledge(Posted 2008) [#4]
is there a way to loop trough a type without using a TList?


You could store instances in a different sort of data structure (ie array or TMap) but to iterate through a collection of instances you have to have collected them somewhere... and typically they will be in a list! (This is much like Blitz3D, the difference being that B3D only supports a single global list per custom type which is automatically-populated, so the list type itself is somewhat transparent.)


bytecode77(Posted 2008) [#5]
hm ok. are there any useful references specificaly to this problem - maybee with an example?


degac(Posted 2008) [#6]
Type mytype
	Field value:Int
End Type

Type mytype2
	Field value:Int
End Type



Global list:TList=New TList
Global map:tmap=CreateMap()

'add 10 new object to a list
For k=1 To 10
	locty:mytype=New mytype
	list.addLast locty
Next

'same list, different object-type
For k=1 To 10
	locty2:mytype2=New mytype2
	locty2.value=K*1000
	list.addlast locty2
	MapInsert(map,"KEY "+String(k),locty2)
	'save the object with the 'label-tag-key' KEY #
Next

'as i don't know what object is I need to use the 'generic' Object type
For obj:Object=EachIn list

	If mytype(obj)
		Print "Mytype..."+mytype(obj).value
	End If
	
	If mytype2(obj)
		Print "Mytype2..."+mytype2(obj).value
	End If
Next

Local who:Object=MapValueForKey(map,"KEY 7")

If who
	
	If mytype(who)
		Print "who for 'key 7' is Mytype..."+mytype(who).value
	End If
	
	If mytype2(who)
		Print "who for 'key 7' is Mytype2..."+mytype2(who).value
	End If
	
End If


Probably not the best example of the world, but it explains the fact that a list can 'contain' different object-type.
And a Map is a sort-of array with 'label' of each elements (=object-type) you store in.


grable(Posted 2008) [#7]
Heres a small example showing how to implement EachIn iteration for your own classes.



bytecode77(Posted 2008) [#8]
this is really something :)
thanks guys!


tonyg(Posted 2008) [#9]
You might be interested in Beginner's Guide to Bmax
and Learning 2D Game Programming With BlitzMax . It should cover a lot of your starter questions and both are excellent. You might also want to check Absolute Newbie's Tutorial for Object Oriented Design if you're new to OO and, specifically, Bmax implementation of it.


bytecode77(Posted 2008) [#10]
i'm not new to OOP, but i'm new to the bmax version of oop!
i'll check out these three links. thx!


Dreamora(Posted 2008) [#11]
well enumerators / iterators are quite common in any OO language on set / collection classes


slenkar(Posted 2008) [#12]
the above explanations are a little complex maybe, i certainly dont understand them after a quick look

hmm, here is an explanation that makes sense to me.....

when you create a type you can put the list into the type:



blitzmax knows which global you are refering to because they are inside the different types (even though they are both called list)

then when you create a new one you can add it to that list

local s:ship
s:ship=new ship
listaddlast(ship.list,s)


then to loop through:
local s:ship
for s:ship=eachin ship.list

next



Dreamora(Posted 2008) [#13]
move that "listaddlast(...)" into
type TShip
  global list:tlist=new tlist

  field _link:TLink

  method new()
    self._list.addlast(self)
  end method

  method remove()
    ' Will remove the object from the list realtime efficiently instead of "list.remove blabla"
    _link.remove()
    _link = null
  end method
end type


I would suggest using the standard naming conventions for BM as well in your code:

Type names begin with T
Private meant fields start with a _


bytecode77(Posted 2008) [#14]
that is better! i managed to implement this to my program.
also i wonder why this is so complicated at all...


tonyg(Posted 2008) [#15]
also i wonder why this is so complicated at all...


Are you saying it IS complicated or it is NOT?
I struggled for a few months with BlitzMax but found using those tutorials made it all clear. It is now so intuitive, compared to B3D, that I have a lot of problems going back.


verfum(Posted 2008) [#16]
Going back to B3D <shudder>

Also I have noticed some examples on here demonstrating globals, this is really bad practiced and a bad example for someone learning oop, the whole point of oop is that *nothing* is global, and in a way there should be private and protected features in blitzmax to make variables and functions private to the class but there isn't, here is some code demonstrating private member variables and functions, this 'I think' being a c++ programmer, is good practiced in Bmax:
Type CEnemy
	
	Function Create:CEnemy(x:Double, y:Double, file:String)
		local enemy:CEnemy = new CEnemy;
		enemy.m_x = x;
		enemy.m_y = y;
		enemy.m_image = LoadImage(image);
		enemy.m_enemy_list.AddLast(enemy);
		return enemy;	
	
	End Function
	
	Method Draw()
		
		DrawImage(m_image, m_x, m_y);
	
	End Method
	
	Field m_x:Double, m_y:double;
	Field m_image:TImage;
	Field m_enemy_list:TList = CreateList();
	
End Type

Graphics(800, 600);

local meany:CEnemy = CEnemy.Create(10, 50, "enemy.jpg");

while not keyhit(KEY_ESCAPE)
	Cls;
	
	for local enemy:CEnemy = eachin enemy.m_enemy_list
		enemy.Draw();
	Next
	
	Flip;
Wend



Dreamora(Posted 2008) [#17]
What is the idea of that sample? Show how not do to it?

Its neither clean code nor is it OOP because in OOP you would not iterate over a list (either static or private) from outside the class. That totally breaks the idea of encapsulation which is the main purpose of OO Design.

But in any way, your code is bad design there.
Either CEnemy is the Enemy class. In that case, make the list global (Static in C++ / Java) to the type. It won't be global outside, it will just be global to all instances of that type. Currently each enemy has an own list of enemies .. good luck iterating over anything at all

The other would be that you implement a factory and add the list there as field, that would be OOP as well.


Who was John Galt?(Posted 2008) [#18]
Just stick with Paxman's example - everyone else seems to have over complicated their examples with irrelevant stuff.


verfum(Posted 2008) [#19]
Okay, change that code to do that and keep it nice and simple for a beginner to understand, that was a very basic example that you shouldn't make global objects, and far from NOT clean, it's just not clean in a sense that it's not true oop. Here is an extended version which I've just done, here we have what you have suggested, but it's more complex for a beginner to understand.
SuperStrict

Type CGod Final
	' This is kind of a singleton pattern, this makes sure there is
	' only ever one sole instance of the god class, but blitz does not support
	' private constructors.
	Function getInstance:CGod()
		if instance = null then
            instance = new CGod;
        EndIf
  
        return instance;
	
	End Function
	
	' public interface
	Method addEnemy:CEnemy(entity:CEnemy)
		m_entities.AddLast(entity);
		return entity;
		
	End Method
	
	Method Draw()
	
		For local iter:CEntity = eachin m_entities
			local pos_x:double = iter.getPositionX();
			local pos_y:Double = iter.getPositionY();
			local ent:CEntity = iter.getEntity();
			
			iter.Draw(pos_x, pos_y);	
		Next
		
	End Method
	
	Global instance:CGod;					' This should be private!
	Field m_entities:TList = CreateList();	' The god stores all entities
	
End Type

Type CEntity
	
	Method getEntity:CEntity()
		return self;	
	End Method
	
	Method getPositionX:Double()  ' This should be a const method
		return m_x;	
	End Method
	
	Method getPositionY:Double()  ' This should be a const method
		return m_y;	
	End Method
	
	Method Draw(x:Double, y:Double) abstract;

	
	Field m_x:Double, m_y:Double;

End Type

Type CEnemy Extends CEntity
	
	Function Create:CEnemy(x:Double, y:Double, file:String)
		local enemy:CEnemy = new CEnemy;
		enemy.m_x = x;
		enemy.m_y = y;
		enemy.m_image = LoadImage(file);
		return enemy;	
	
	End Function
	
	Method Draw(x:Double, y:double)
		DrawImage(m_image, x, y);
	End Method

	Field m_image:TImage;
		
End Type

Local god:CGod = CGod.getInstance();

local enemy:CEnemy = god.addEnemy(new CEnemy.Create(10, 50, "media/enemy.bmp"));

Graphics(800, 600);

while not keyhit(KEY_ESCAPE)
	Cls;

	god.Draw();
	
	Flip;
Wend



verfum(Posted 2008) [#20]
As you can see the god class creates and draws all entities created, as far as I'm aware of this is probably the best way of doing it, with variations of course. The god class would also create all the items in the game, levels and players etc.


slenkar(Posted 2008) [#21]
I didnt know you could use the Object command like that, pretty good,
anything else an ex-Blitz3D user should know about like that?


tonyg(Posted 2008) [#22]
anything else an ex-Blitz3D user should know about like that?

Orientation guide for existing Blitz users


Czar Flavius(Posted 2008) [#23]
I'm more comfortable with Paxman's way of doing things. Suprisingly my code hasn't exploded or taken over the world.


slenkar(Posted 2008) [#24]
thanks


verfum(Posted 2008) [#25]

I didnt know you could use the Object command like that, pretty good,
anything else an ex-Blitz3D user should know about like that?



Which part didn't you know? The Singleton?


Dreamora(Posted 2008) [#26]
To save yourself time, I would suggest doing all basic tutorials of Assari

they are a great place to start.

And forget what you know about blitz, it has quite little in common with BM even when the syntax looks similar.


verfum(Posted 2008) [#27]
Good advice, the above code has been converted from my c++ game framework, cut down, and it's a bit hectic, but once understood it works pretty well and makes a lot of logical sense, even better in c :)


slenkar(Posted 2008) [#28]
Which part didn't you know? The Singleton?

the fact that you dont have to know what kind of type it is


verfum(Posted 2008) [#29]
Which part are you refering too? Sorry for being a bit dim here :( I'm just not following you.


tonyg(Posted 2008) [#30]
@verfum, I don't believe Mr Paxman is referring to anything in your code rather the use of 'Object' cast from a user-defined type.


slenkar(Posted 2008) [#31]
yeah its useful


Beaker(Posted 2008) [#32]
Blitz2D/3D/+ like type access...