Noob Object Help Please
BlitzMax Forums/BlitzMax Beginners Area/Noob Object Help Please
| ||
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 |
| ||
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 :-) |
| ||
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" ? |
| ||
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. |
| ||
@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! |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
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" |