How to check if a type object is dead?
BlitzMax Forums/BlitzMax Programming/How to check if a type object is dead?
| ||
Hiya, here's a little OO challenge for you:Field preyType Field x,y:Int End Type Type hunterType Field x,y:Int Field prey:preyType End Type The hunter stores a reference to the prey with self.pray = p (if looping through preys and choosing one). It does this so the hunter can access the prey objects data with a pointer to it (or is this a reference to it?) Within the hunterType update code, I go: If self.prey = Null Then find new prey. However even when I remove the prey object, it is never null when the hunter checks his prey field? How do I detect when it no longer exists? |
| ||
Create a list and remove objects from it in the delete method. Type Pray Method Delete() AliveEntities.Remove( Self ) end method end type |
| ||
When you say "remove the prey object". How are you doing that? By setting it to null and calling GCCollect (seeing as Delete is a reserved work)? Any other method isn't removing it and thus the prey field in unter won't be null. Maybe anyway, it doesn't go null after Garbage Collection anyway, shame. Another naff way is to have a pointer to Hunter in Prey and when you "remove" prey, set the Prey Field in Hunter to Null manually. |
| ||
Type preyType Field x,y:Int Field Dead:int = False End Type Type hunterType Field x,y:Int Field prey:preyType End Type Local Squirrel:preyType = new preyType Local Hawk:hunterType = new hunterType Hawk.prey = Squirrel Squirrel.Dead = True Squirrel = Null If Hawk.prey.Dead = True then Hawk.prey = Null Seems to work ok. |
| ||
For safety I would change the last line to:If Hawk.prey <> Null then If Hawk.prey.Dead = True then Hawk.prey = Null EndIf because if Garbage Collection does null the pointer at some future point, Hawk.Prey.Dead will crash as it references a field of a null object. If BlitzMax had "incomplete boolean evaluation" like Delphi you could put it all on one line: If Hawk.prey <> Null and Hawk.prey.Dead = True then Hawk.prey = Null Because the code wouldn't bother to evaluate the second part (Hawk.Prey.Dead) if the first part returned True. This is neat and fast and I Wish BMax supported it, but it doesn't, I've tested it. Wait a minute I tested in BPlus not Max. Perhaps Max DOES support it. |
| ||
Grey: GC will not set the pointer to Null because after you set Squirrel to Null, there's still a reference to it in Hawk. If the GC deletes Squirrel while Hawk is still referencing it, then that would be a bug in BMax. However, you're added code is still a good idea just in case Hawk.prey hasn't yet been set to point at anything. Also, BlitzMax does have incomplete boolean evaluation. Try this and you'll see. :) |
| ||
OK Thanks TomToad, of course I should have realised that. Generally I like to test for null to avoid problems if I suspect something may have been a)not created yet or b)been destroyed already. Oh and thanks for the code example that shows that BMax DOES indeed have incomplete bool eval! |
| ||
Just to clarify this: until my hunter's prey field is cleared, then the prey object will not be garbage collected? So it'll never be null until all other things in memory looking at it's address are also null? |
| ||
yes, that's my understanding of it (since about yesterday :-)) Because the garbage collector keeps track of how many variables point at the type. So you've got 2: the actual prey object and the variable in the hunter object. You free up the prey object (null it, whatever), but you still have 1 variable in hunter pointing at it so the GC won't get rid of it yet, even though the original object variable is null. |
| ||
Thats really clever really I suppose. I recall having a nightmare time with C++ GC. |
| ||
Create a list for your hunters. A field in the hunter type Global HunterList:TList. When you create a hunter, add it to this list. Have a method in the prey type you call for the prey when it is killed. In that method, loop through all hunters in the hunter list with eachin, and check to see if Hunter.Prey = Self. If so set Hunter.Prey to Null. Now assuming that you have no other pointers in your program pointing to the prey, the prey will be removed as soon as the method ends. If you have a list of prey, then you will need to remove the prey from that list in that method. Also, now that the hunters are in a list you will need to remove them from the list when you want them to be deleted. |