Help on 'types' please.

BlitzMax Forums/BlitzMax Beginners Area/Help on 'types' please.

Tobo(Posted 2008) [#1]
Hello. Can some one help, please?

I've searched the forums, searched the web and searched Sloan's book; but I still can't find an effective example of how BlitzMax handles types as opposed to Blitz3D. I'm okay with defining them, but accessing them through a loop has me stumped. I know B3D used a kind of FOR F=EACH TYPE sort of thing!

Would some one be so kind as to write a short bit of code that defines a type with a couple of fields, and then goes through them using a loop, please?

Eg.

TYPE BULLET
FIELD x,y
END TYPE

FOR F=0 TO 10
Local b:bullet
b=New bullet
b.x=RAND(1,200)
b.y=RAND(1,200)
NEXT

.........what next, how do I loop through them?


Many thanks in advance - please keep it simple.

Tobo.


grable(Posted 2008) [#2]
Blitz3D has an internal list for each type, this is quite different in BlitzMax where you have to keep track of the types yourself.
Also since BlitzMax has garbage collection, Delete wont work, the object has to go out of scope or all references to it must be removed.

Here is an example:
SuperStrict

Type TBullet
    Field x:Int,y:Int
EndType

' the bullet list
Global list:TList = New TList

' fill the list
For Local i:Int = 1 To 10
    Local b:TBullet = New TBullet
    b.x = Rand(1,200)
    b.y = Rand(1,200)
    list.AddLast(b)
Next

' loop through the list
For Local b:TBullet = EachIn list
    Print b.x + "," + b.y
Next

' clear the list AND "delete" all types in the list (although there is no guarantee that they will be deleted as this is up the the GC)
list.Clear()



CS_TBL(Posted 2008) [#3]
why not simply use an array?


Tobo(Posted 2008) [#4]
Grable, can you put that into thicko Layman's terms please?

What is TList - the helpfile isn't very helpful on it. Also, what is the List.addlast(b) bit?

Many thanks.

T.


CS_TBL(Posted 2008) [#5]
type tbullet
  field x,y
  method new()
    x=rnd(1,20)
    y=rnd(1,20)
  end method
end type

local b:tbullet[100]
for local x:int=0 to 99
  b[x]=new tbullet
next


It may not be that you always need 100 bullets at the same time. Point is: this is hardly RAM overkill anyway, and with a reserved 100 slots for bullets you have a more stable cpu load.


Jesse(Posted 2008) [#6]
I will try to explain what list does.
when you create an object such as:
local b:bullet
b  = new bullet

it creates an instance of bullet and assigns the address to b
but if you do the same thing again on the next line
such as:
local b:bullet
b = new bullet
b = new bullet

you will loose the address of the first bullet, the garbage collector will clear that memory area, and assign the second address to b. If you keep doing that it will keep on replacing b with the newest address.
to avoid from loosing the first address or any consecutive address, you need to save the addresses on a "TList". Tlist is A type on its own. it is designed to store and extract addresses of objects. To create a Tlist you do it like this:
local TheList:TList
TheList  = new TList

the type TList has several options. On the bmaxIDE, if you type TList put the cursor over it and press f1 twice you will see all of the options for Tlist. lets concentrate on the obvious only. the first is to add an object to the list. To add it you do it like this:
TheList.addlast(b)

this line of code adds the address stored in b to "TheList"
now "TheList" has the address of the instance of the object assigned to b.
So now b and TheList both possesed the address stored in b
if you assign a new object to b the old address won't be completeley lost because it will still be stored in TheList.
If you want, the new Address can also be added to the TheList by doing the same thing:
TheList.addlast(b)

at this point the code would look like this:
Type Bullet
field x:int,y:int
End Type
local TheList:TList
TheList  = new TList
local b:bullet
b = new bullet
b.x = 3
b.y = 4
TheList.addlast(b)
b = new bullet
b.x = 7
b.y = 1
TheList.addlast(b)

now TheList has two object addresses. To access each of the objects you do it like this:
For local b2:Bullet = eachin TheList
    print b2.x
    print b2.y
Next

this code goes through the list and displays
3
4
7
1
the value of x and y for each of the objects stored in The TheList.

I hope this has helped you as I had the same problem when I started.


Rimmsy(Posted 2008) [#7]
A list is just that. You don't have to bother yourself with the internal workings of it, just remember it has some simple methods associated with it.
Global BulletList:TList = createlist()

ListAddLast(<your list>, <object to add>)
ListRemove(<your list>, <object to remove>)

<your list>.clear()
<your list>.ValueAtIndex(index)


Like Grable says, to delete an object you mustn't have any references to it. This simply means that nothing points to it. Imagine telling your friends a secret. Now say you forget the secret and then all your friends forget it too. Nobody knows the secret so it disappears. This is the same as removing it from the list and making sure nobody else points to it.

global i:Bullet = new Bullet
ListRemove(BulletList, i)

Here the bullet still exists because it's held in i. Simply removing it from the List doesn't do the job. You'll need to also do:
i = null


Lists are a lot easier but not as quick as arrays.


Rimmsy(Posted 2008) [#8]
Doh, beaten to it.


Jesse(Posted 2008) [#9]
no, that was the icing on the cake.


Czar Flavius(Posted 2008) [#10]
In a sentence: a list is like an array, but you can add or remove things from it whenever you want, whereas an array is fixed to a certain size and cannot be resized easily.

In Blitz3D you were using a list 'behind the scences', but what happened if you wanted to have two seperate lists of bullets or some other type? Blitzmax lets you make your own lists.

Garble's example is quite nice, study and run it and you'll soon get the idea.


Tobo(Posted 2008) [#11]
Guys / Gals,

Thank you ever so much. It's gonna take me a few read throughs to actually digest what you're all saying but I get the gist.

Seems a lot more complicated than B3D, which I only just grasped, but hey ho.

Thanks again, folks.

Tobo


CS_TBL(Posted 2008) [#12]
whereas an array is fixed to a certain size and cannot be resized easily

local a:int[10]
a=a[..20]


Tobo(Posted 2008) [#13]
Woohoo - I think I have it.

Graphics 640,480,0

Type bullet
	Field y
	Field x
End Type

bulletlist:TList = New TList

x=300

While Not KeyHit(key_escape)
	Cls
	
	DrawRect(x,400,20,10)
	If KeyDown(key_right) x:+2
	If KeyDown(key_left) x:-2

	If KeyHit(key_space)
		Local b:bullet
		b=New bullet
		b.y=400
		b.x=x
		bulletlist.addlast(b)
	End If
		
	For Local b2:bullet = EachIn bulletlist
		b2.y:-4
		DrawRect b2.x,b2.y,2,8
	Next

	Flip
Wend


....do I need to kill/delete the bullets when they go off of the screen?


CS_TBL(Posted 2008) [#14]
yes, otherwise your list would grow forever.

Of course, if you have a fixed-size array, then you just round-robin bullets in that array and you don't need to worry about a thing, old bullets will be overwritten by new ones. If you have too few array slots you'd see bullets disappear, hence, your array should be large enough to let the oldest bullets go off-screen in a worst-case-scenario.


Czar Flavius(Posted 2008) [#15]
CS_TBL, that method of resizing an array is slow, and not particularly elagant, if single items need to be added regularly.


Tobo(Posted 2008) [#16]
Do I have to remove it from both the List and the Type?

If so, how?

Again, the helpfile isn't very helpful on this.

(I do appreciate your help, guys)


Tobo


CS_TBL(Posted 2008) [#17]
What's the big deal with lists for objects that are maybe 16 bytes in size and of which the quantity probably varies between 0 and 50 (meaning 800 bytes memory!)? Linked lists aren't completely free of CPU load, afaik arrays are faster here.


tonyg(Posted 2008) [#18]

Do I have to remove it from both the List and the Type?


Listremove (or list.remove if you're using the method) to remove from the list and then let the type instance variable go out of scope at which point it will become available to the automatic Garbage Collector. If you have declared the variable as global to the whole program then you may need to set the instance variable to null


Yan(Posted 2008) [#19]
If you're coming to BMax form BB, be sure to read through this...

http://blitzbasic.com/Community/posts.php?topic=41179