Noob Object Help Please

BlitzMax Forums/BlitzMax Beginners Area/Noob Object Help Please

MGE(Posted 2007) [#1]
Basically, I want to have a field inside an object, that optionally points to another object. If the object that is being pointed to is null, I need to be able to respond to that in code. In this example code, I set up 2 objects, they have the same fields. ObjectB points to ObjectA via one of the fields, however when ObjectA becomes nullified, I can't find a way to verify that in code? Thanks for any insight you can offer. ;)

Type testobj
 Field x:Int
 Field obj:testobj
End Type
'
Global mylist:TList = New TList
'
Global objA:testobj = New testobj
objA.x=Rand(100,800)
ListAddLast(mylist,obja)
'
Global objB:testobj = New testobj
objB.x=Rand(100,800)
objB.obj = objA   ' add a reference to obja 
ListAddLast(mylist,objb)
'
Print "Items in list:" + CountList(mylist) 
'
ListRemove(mylist,objA)  ' remove item from list
'
Print "Items in list:" + CountList(mylist) 
'
Print "After removing object A from the list..."
'
If objA = Null          
 Print "object A is null"
Else
 Print "object A is still alive"
EndIf
'
objA = Null
'
Print "After setting object A to null..."
'
If objA = Null          
 Print "object A is null"
Else
 Print "object A is still alive"
EndIf
'
' I need to find out if objB.obj is pointing to a null object!
'
' Try 1....?
If objB.obj = Null
 Print "object B reference to A is null"
Else
 Print "object B reference to A is NOT null"
EndIf
' Try 2....?
If testobj(objB.obj) = Null
 Print "obeject B reference to A is null"
Else
 Print "object B reference to A is NOT null"
EndIf



Brucey(Posted 2007) [#2]
That's because :

objA points to a reference of a testobj object
You set objB.obj to point to the same reference as objA.

Nulling objA just has it not pointing to a reference of anything. objB.obj still points to the original reference. Therefore, objA is null, objB.obj is not null.


You will have to change your design in order to work the way you want :-)


tonyg(Posted 2007) [#3]
Type testobj
 Field x:Int
 Field obj:testobj=Null
End Type
'
Local test1:testobj = New testobj
If Not test1.obj Print "It's null"
Local test2:testobj = New testobj
test1.obj = test2
If test1.obj Print "It's NOT null"
test1.obj=null
if not test1.obj print "Its null again"

?


Who was John Galt?(Posted 2007) [#4]
Objects themselves cannot be null. A pointer is either Null, or points to an object. Deleting objects when there are still pointers to them is bad news. In Blitz, an object stays alive until there are no pointers to it, so as long as you haven't set 'objB.obj=NULL', objA will no be disposed of. I hope that makes sense... I know what I'm trying to say.


MGE(Posted 2007) [#5]
@TonyG - Your example doesn't nullify test2, that's the point of interest. Having test1 recognize test2 is null. ;)

@Luni - Thanks for the explanation. I think I've got a solution. ;)

@ Brucey - Agreed. It's my implementation that is at fault.

Since I now fully understand that objects removed from a list are still alive until no references are made to them, I simply added another field to my objects that tells me if they are removed from the list.

The problem surfaced when I was adding code for homing missiles. If the baddie the missile was homing in on, was removed, I didn't know how to recognize this in code, because I had assumed the baddie was gone, but since there is a reference to the baddie via the missile, the baddie was still there just not in the update or render loops because it was removed from the list.

The solution was to simply add a field to the objects which tells me if they're removed from the list. So when a missile is homing in on a baddie that is removed, I can recognize this (and act on it) and also set the reference to null, which in turn will allow the garbage collection object to eventually remove the object. So I'm sure what was happening was, even though they were removed from the list and not being updated or rendered, they were still in memory taking up resources, etc. So now by setting the reference to null, it should allow everything to clean up correctly. ;)

Thanks for all the help!


MGE(Posted 2007) [#6]
As a general rule, is "object = Null" the best way to remove (free?) an object that is no longer needed? And would this also apply to a TList I no longer need? Thanks.


Czar Flavius(Posted 2007) [#7]
What about this? Have an alive field for your objects, and whenever something is referencing an object that you want to remove, make it check that its alive field is true. Otherwise, reset its reference to null


tonyg(Posted 2007) [#8]
The best way is for the object to go out of scope. If you're using 'main program' globals (rather than globals within a type) you'll have to null yourself though. Once the last pointer is removed GC will remove them.


dmaz(Posted 2007) [#9]
what I usually do for these types of things is the test that you thought of...

I test to see if it's still in the list by using the variable I keep for it's TLink (I (almost)always keep the pointer to it's TLink) which is nulled when I call it's "remove" method

SuperStrict

Type TThing
	Global list:TList = New TList
	
	Field x:Float
	Field y:Float
	Field link:TLink
	
	
	Function Create:TThing( x:Float, y:Float )
		Local t:TThing = New TThing
		t.x = x
		t.y = y
		t.Link = list.AddLast(t)
		Return t
	End Function
	
	Method Remove()
		link.Remove
		link = Null
	End Method
	
End Type

Local test:TThing = TThing.Create(10,10)
test.Remove
If test.link = Null Then Print "removed"