Types and 'the penny dropping'

BlitzMax Forums/BlitzMax Beginners Area/Types and 'the penny dropping'

EOF(Posted 2004) [#1]
Things are at last becoming clearer with how blitzmax handles types compared to b3d and bplus.
I've been having a play:
Type testtype
	Field x:Byte
End type

Local a:testtype=New testtype

FlushMem

Print "mem allocated at start = "+MemAlloced()

For Local d=1 To 5000
 a=New testtype
 a.x=d
 FlushMem
next

Print "after 5000 NEW testtypes = "+MemAlloced()

FlushMem

Print "flushed mem = "+MemAlloced()
Although the loop here seems to suggest there are 5000 NEW types being made, only one exists. The a:testtype is being overwritten time and time again. This took a while to sink in.
Under b3d and bplus there would in fact be 5000 new types being handled internally.

Now I understand why we need to throw these types into a linked-list. This is blitzmax's way of keeping hold of the types .. a bit like pegging em all up on a washing line.


Steve Elliott(Posted 2004) [#2]
Aren't you just creating one because of the Flushmem in the loop?


flying willy(Posted 2004) [#3]
I don't like the new way because I am an artist. I like to keep shit simple.

Of course I'll have to learn all this new stuff, but to tell us, the users, that blitzmax is in any way simpler, is a joke.


Gabriel(Posted 2004) [#4]
Aren't you just creating one because of the Flushmem in the loop?


Yup. Add in a=null before the final flushmem and print and you'll have got rid of that one too.



I don't like the new way because I am an artist. I like to keep shit simple.


I'd have liked an option to turn off garbage collection, but I guess that's not possible because Blitz depends on it deep in the modules.

Like you, I don't really see why it had to be changed. If I didn't need any helping creating a resource and allocating memory for it, I don't see why it's particularly hard work to clean up after myself. I assume there's more to it, and again, perhaps it's because of the way BMax works internally.


ImaginaryHuman(Posted 2004) [#5]
Umm ... doesn't Flushmem only get rid of `unused` variables, so since you are using the `a` variable it wouldn't flush it anyway?

Also, it does make sense that if you make a= something, any further instances of a= is going to overwrite the contents of a with something new, so if you use a to create a type there is only one intance of a tied to the type. Doing `New` would just overwrite it.

Although, I can see your point, you might think that it creates a bunch of new types that you just don't keep track of. But I guess it's better to keep track by tying it to the variable.


dmoc(Posted 2004) [#6]
Think "reference count": assigning a new instance to "a" decrements the ref count on the prev instance to zero. It's in a "ready-to-delete" state waiting for a flush mem. So in practical terms it doesn't exist and you only ever have one, ie, the one assign to "a" which will have a ref count = 1.


Tom(Posted 2004) [#7]
erm...

If x in the Type is declared as a Byte, then I don't see how it can be assigned d, which in that code would default to an Int

?

Tom


Bot Builder(Posted 2004) [#8]
Hey, good point thats odd 0_o according to the bmax docs you shouldn't be able to imply that conversion due to possible data loss.


BlitzSupport(Posted 2004) [#9]
When a is assigned to a new object, it is no longer pointing to the last one. Since nothing's now pointing to the last one, it gets freed.


Paul "Taiphoz"(Posted 2004) [#10]
Hmm that could be a pain in the arse tbh.

Like in b3d you might have a list of type a like a\life a\image and so on.

and just by calling a.mytype = new mytype it would auto add it to the LIST a ?

so is this not the case with max ? if not does that mean that to do the above b3d code you will have to actually code and manage traverse our own linked lists ?

if so im not so keen on that at all.


EOF(Posted 2004) [#11]
and just by calling a.mytype = new mytype it would auto add it to the LIST a ?
so is this not the case with max ?

No but it's easy to get Max to behave like classic Blitz ..
Global list:TList=CreateList()

Type nametype
	Field name$
	Method New()
		ListAddLast list,Self
	End Method
End Type

Local n:nametype

n=New nametype
n.name="Tom"
n=New nametype
n.name="Amanda"
n=New nametype
n.name="Mary"
n=New nametype
n.name="Peter"

For n=EachIn list
	Print "   -> "+n.name
Next

Input "Done. Return to end ..."
In the above code when I do

n=New nametype

the 'Method New() .. End Method' bit is executed automatically.
Since I have 'ListAddLast list,Self' in there the type gets placed in the list without hassle.


Gabriel(Posted 2004) [#12]
Is there any reason not to include the list in the type definition?


EOF(Posted 2004) [#13]
From the above example, placing the list definition inside the type would prevent this part from working:
For n=EachIn list 
 ...
Next
Because the 'list' would only be global to the type itself.

I could do it this way though ..
Type nametype
	Global list:TList
	Field name$
	Method New()	
		If list=Null list=CreateList()
		ListAddLast list,Self
	End Method
	Method ShowList()
		For Local n:nametype=EachIn list
			Print "   -> "+n.name
		Next
	End method
End Type

Local n:nametype

n=New nametype
n.name="Tom"
n=New nametype
n.name="Amanda"

n.showlist

Input "Done. Return to end ..."



Bot Builder(Posted 2004) [#14]
No, List is a variable:
Global list:TList=CreateList()
TList is the class name.


EOF(Posted 2004) [#15]
Once advantage of keeping the list global is the fact that you can throw different types in there.

Look .. cats and dogs living in harmony:
Global list:TList=CreateList()

Type cattype
	Field name$
	Method New()
		ListAddLast list,Self
	End Method
End Type

Type dogtype
	Field name$
	Method New()
		ListAddLast list,Self
	End Method
End Type

Local c:cattype
Local d:dogtype

c=New cattype
c.name="Felix"
c=New cattype
c.name="Garfield"
d=New dogtype
d.name="Rover"
d=New dogtype
d.name="Tyson"

Print "Cats:"
For c=EachIn list
	Print "  > "+c.name
next

Print "Dogs:"
For d=EachIn list
	Print "  > "+d.name
next

Input "Done. Return to end ..."



ashmantle(Posted 2004) [#16]
neat!


Paul "Taiphoz"(Posted 2005) [#17]
Ahh in the cats&Dogs one, your actually creating two lists inside one list variable ??

if so thats cool as FK, would mean you can have say for example a List for all spaceships, then inside that list you can actually have lists of all alien.shaship or lists of all player.spaceships

Thats minted.

I was just buggin out cos I thought I was going to have to do all my own linked list and binary tree managment code. but seems like its all there just changed the way its used.

sweet.


Paul "Taiphoz"(Posted 2005) [#18]
I'm getting a listaddlist error it dont know what listaddlist is.

'

Strict

Global GFX_Width		:	Int		=	800
Global GFX_Height		:	Int		=	600
Global GFX_Depth		:	Int		=	16

'Graphics GFX_Width,GFX_Height,GFX_Depth




Global SpaceObjectList:Tlist = CreateList()

Type SpaceObject
	Field pos_x		:	Int
	Field pos_y		:	Int
	Field Velocity	        :	Int
	Field name 		:	int
	
	
	Method New ()
		listaddlist SpaceObjectList,Self
	End Method
	
	Function Display_New()
		Print "A New Space Object was Created."
		cls
	End function
	
End Type

Type Planet Extends SpaceObject
	Field Image:Timage
End Type

Type Moon	Extends SpaceObject
	Field Image:Timage
End Type

Type Star	Extends SpaceObject
	Field Image:Timage
End Type


While Not KeyHit(KEY_ESCAPE)
	Cls
	
	
	
	FlushMem;Flip
wend



the error I get is something like unkown listaddlist

What am I doing wrong here..


Gabriel(Posted 2005) [#19]
From the above example, placing the list definition inside the type would prevent this part from working:

For n=EachIn list 
 ...
Next 




Well yeah, but you'd only have to reference the list correctly with NameType.List instead of just list, surely?

I realise there are situations where you might not want to put the list in the type definition, I just wondered if there was a general reason not to, because that's the way I've been doing it so far.


Yavin : It's ListAddLast


Paul "Taiphoz"(Posted 2005) [#20]
OH FFS - /me walks off ina huff and kicks himself a few times.

Now thats a good case against dislexic people being programmers.

I must have read over that code about 10 times and my brain just kept on reading it out as listaddlist ..

I actually just noticed it and came through to the laptop to post a DOH , but you beat me to it lol..

Must admit though I am likin max.


Damien Sturdy(Posted 2005) [#21]
I hate when that happens. :)


Phish(Posted 2005) [#22]
In the cats and dogs example, the list contains both cats and dogs, the magic is in the " for d = eachin list ". A list contains Objects, and cats and dogs are implicitly subtypes of Objects.

Since d is typed to be a dog, then it cannot be assigned to be a cat, so the for...eachin loop can only operate on dog instances in the list. In fact, if you wanted to make blitzmax even more like the original blitz, I suppose you could replace all of these:

for m.myType = each myType


with:

for m:myType = eachin list


(Just as long as you make sure to include the type information)

But it might be quite slow, since list would contain every single instance of your types!


dmoc(Posted 2005) [#23]
An extended version of the cats&dogs+owners. I don't think the debugger can handle nested structures (try expanding the "_value" field).

Type pettype
	Global pets:TList

	Field name$
	Field ptype$

	Method New()
		If Not pets pets=CreateList()
		ListAddLast pets,Self
	End Method
End Type

Type cattype Extends pettype
	Method New()
		ptype="Cat"
	End Method
End Type

Type dogtype Extends pettype
	Method New()
		ptype="Dog"
	End Method
End Type

Type owner
	Global owners:TList
	
	Field pets:TList
	Field name$
	
	Function AddOwner:owner(n$)
		Local o:owner = New owner
		o.name = n
		Return o
	End Function
		
	Method New()
		If Not owners owners=CreateList()
		ListAddLast owners,Self
		pets=CreateList()
	End Method
	
	Method AddDog:dogtype(n$)
		Local p:dogtype = New dogtype
		p.name=n
		ListAddLast pets,p
		Return p
	End Method

	Method AddCat:cattype(n$)
		Local p:cattype = New cattype
		p.name=n
		ListAddLast pets,p
		Return p
	End Method
End Type

Local o:owner
Local c:cattype
Local d:dogtype
Local p:pettype

o = owner.AddOwner("Mickey")
o.AddDog("Rover")
o.AddCat("Felix")

o = owner.AddOwner("Minnie")
o.AddDog("Fido")
o.AddCat("Garfield")

Print "Owners:"
For o=EachIn owner.owners
	Print "Owner: "+o.name
	For c=EachIn o.pets
		Print "~tCat: "+c.name
	Next
	For d=EachIn o.pets
		Print "~tDog: "+d.name
	Next
	Print "~tAll:"
	For p=EachIn o.pets
		Print "~t~t"+p.ptype+": "+p.name
	Next
Next
Print ""

Print "Pets:"
For c=EachIn pettype.pets
	Print "~tCat: "+c.name
Next
For d=EachIn pettype.pets
	Print "~tDog: "+d.name
Next
Print "~tAll:"
For p=EachIn pettype.pets
	Print "~t~t"+p.ptype+": "+p.name
Next
Print ""

DebugStop