problem with lists

BlitzMax Forums/BlitzMax Programming/problem with lists

gellyware(Posted 2005) [#1]
I am trying to seperate the p1 and the p2 lists... I want p1 to contain values 0-10 and p2 to contain values 11-20. Running this code prints the following:

------------- p1 list -------------
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
------------- p2 list -------------
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


Here is the code:


Strict

Global p1:TParent
Global p2:TParent 

Type TParent
	Global list:TList
	Global child:TChild 
	
	Method New()
		If list = Null Then list = New TList 
		list.addlast Self
	EndMethod 
	
	Method destroy()
		list.remove Self 
	EndMethod 
EndType 

Type TChild
	Global list:TList
	
	Field val:Int 
	
	Method New()
		If list = Null Then list = New TList 
	EndMethod 
	
	Method destroy()
		list.remove Self 
	EndMethod 
EndType 	

For Local i = 0 To 10
	p1:TParent = New TParent
	p1.child   = New TChild
	p1.child.val = i
	p1.child.list.addlast p1.child 
Next

For Local i = 11 To 20
	p2:TParent = New TParent
	p2.child   = New TChild
	p2.child.val = i
	p2.child.list.addlast p2.child
Next 

Print "------------- p1 list -------------" 

For p1.child = EachIn p1.child.list  
	Print p1.child.val
Next 

Print "------------- p2 list -------------"

For p2.child = EachIn p2.child.list  
	Print p2.child.val
Next 



PGF(Posted 2005) [#2]
The Global list:TList exists only to put each created object into a single list for that type. Global applies to the type as a whole.

What you probably want to do is to create a parent type that contains a list of children which will be a Field. Then create instances p1 and p2 and add ten children to each list.

Strict

Global p1:TParent
Global p2:TParent 

Type TParent
	Global list:TList
	Field children:TList 
	
	Method New()
		If list = Null Then list = New TList 
		list.addlast Self
	EndMethod 
	
	Method destroy()
		list.remove Self 
	EndMethod
	
	Method AddChild(child:TChild)
		If children = Null Then children = New TList
		children.AddLast child
	EndMethod
EndType 

Type TChild
	Global list:TList
	
	Field val:Int
	
	Method New()
		If list = Null Then list = New TList 
	EndMethod 
	
	Method destroy()
		list.remove Self 
	EndMethod 
EndType 	

Local child:TChild

p1 = New TParent
For Local i = 0 To 10
	child = New TChild
	child.val = i
	p1.AddChild(child)
Next

p2 = New TParent
For Local i = 11 To 20
	child = New TChild
	child.val = i
	p2.AddChild(child)
Next 

Print "------------- p1 list -------------" 

For child = EachIn p1.children  
	Print child.val
Next 

Print "------------- p2 list -------------"

For child = EachIn p2.children  
	Print child.val
Next

You could directly access the list of children and do say 'p1.children.AddLast(child)' rather than 'p1.AddChild(child)' but I'd prefer not to directly access (to update) the fields of TParent. There may be other work to be added later to maintain the fields and direct access makes that more work and more error prone.

This is a slightly different version:
Strict

Global p1:TParent
Global p2:TParent 

Type TParent

	Global TypeList:TList
	
	Field Name:String
	Field Children:TList 
	
	Method New()
		If TypeList = Null Then TypeList = New TList
		TypeList.AddLast(Self)
		children = New TList
	EndMethod
	
	Function CreateParent:TParent(name:String)
		Local this:TParent = New TParent
		this.Name = name
		Return this
	EndFunction
	
	Method AddChild(child:TChild)
		children.AddLast child
	EndMethod
	
	Method AddChildValue(val:Int)
		Local child:TChild = TChild.CreateChild(val)
		children.AddLast(child)
	EndMethod
	
	Method PrintChildren()
		Print "------------- Children of " + Name + " -------------" 

		Local child:TChild
		For child = EachIn children
			Print child.Val
		Next
	EndMethod
	
EndType 

Type TChild

	Field Val:Int

	Function CreateChild:TChild(val:Int)
		Local child:TChild = New TChild
		child.Val = val
		Return child
	EndFunction	
	
EndType 	

' Initialisation

Local child:TChild

p1 = TParent.CreateParent("P1")
For Local i = 0 To 10
	p1.AddChildValue(i)
Next

p2 = TParent.CreateParent("P2")
For Local i = 11 To 20
	p2.AddChildValue(i)
Next 

Local parent:TParent
For parent = EachIn TParent.TypeList
	parent.PrintChildren()
Next

Note that I have removed the list maintenance from within TChild as it is not required. The parent instances maintain lists of their children. Generally I do implement the type list maintenance but for illustration you can see that it is optional.


gellyware(Posted 2005) [#3]
PGF, thank you for taking the time to provide such a thorough example! This has clarified a lot.


PGF(Posted 2005) [#4]
If you haven't already done so, I suggest that you go back and look at your original code. Explain to yourself why it did what it did. Then you'll really 'get it'.

For example:

- How many TParent objects did you create ?
- Where did the others go to ?
- Why did both lists print out the same contents ?
- Are they in fact different lists ?

Cheers.