Tlist.remove() does not remove

BlitzMax Forums/BlitzMax Beginners Area/Tlist.remove() does not remove

deps(Posted 2006) [#1]
Hi,

I always use a TList to store the player, enemies and other stuff in my games. And I always remove them when needed by calling something like this:
the_list.remove(self) 

from within the Entity types. It has worked just fine up until now.

But it won't work for me now for some unknown reason.
I added some debug output to my Remove() function in my base Entity type:
	Method Remove()
		Print "Before remove: List contains "+ent_list.count()+" entities"
		If Not ListContains( ent_list,Self ) Then 
			Print " - List claims to not contain the entity..."
			Print " -- Requesting a remove: "+self.tostring()
			Print " -- In list:"
			For Local e:Entity = EachIn ent_list
				If e.ToString() = self.ToString()
					Print " --- "+e.ToString()+" <-"
				Else
					Print " --- "+e.ToString()	
				EndIf
			Next

		EndIf
		
		ent_list.remove( Self ) ' Remove the entity
		
		Print "After remove: List contains "+ent_list.count()+" entities"
	EndMethod


Sample output:
Before remove: List contains 3 entities
 - List claims to not contain the entity...
 -- Requesting a remove: 00CF1640
 -- In list:
 --- 00CF1E60
 --- 00CEBD30
 --- 00CF1640 <-
After remove: List contains 3 entities


And the funny thing is that the Entity is not removed. It is still drawn to screen and other entities can still interact with it.
And why can't remove() and contains() find the entity, when it shows up in the debug output?


tonyg(Posted 2006) [#2]
This works so, I guess, it's not list.remove that's failing...
SuperStrict
Type ttest
	Global list:tlist = CreateList()
	Function create()
		Local my:ttest = New ttest
		ListAddLast list , my
	End Function
	Method remove()
		Print "Before remove: List contains "+list.count()+" entities"
		If Not ListContains( list,Self ) Then 
			Print " - List claims to not contain the entity..."
			Print " -- Requesting a remove: "+ self.tostring()
			Print " -- In list:"
			For Local e:ttest = EachIn list
				If e.ToString() = self.ToString()
					Print " --- "+e.ToString()+" <-"
				Else
					Print " --- "+e.ToString()	
				EndIf
			Next
		EndIf
		list.remove(Self)
		Print CountList(list)
	End Method
End Type
For Local x:Int = 1 To 5
	ttest.create()
Next
For Local all:ttest = EachIn ttest.list
	all.remove()
Next


Is it at all possible to post a simple, self-contained example of code which causes the problem?
<edited> to include your code.


deps(Posted 2006) [#3]
I tried to create a smaller example, but it turns out everything is removed. Just like in your example. And it has always worked just fine before.
I could post all code, but it's 8 files and not a lot of comments. But I will if requested.

I did a syncmod and a full recompile of all modules, but as I expected it did not help.

But why is ListContains failing? The address to the entity is there, but still not removed. Is there a way to get the reference count from the garbage collector? Maybe something somewhere is keeping the entity alive somehow, but why it would affect the TList.remove() I don't know.


tonyg(Posted 2006) [#4]
The only hint I can see is that the entity being removed *SHOULD* be at the top of the list as you're running a for/eachin loop.
For some reason it is at the bottom.
If you ignore the first entity remove does the second work or flag 00CEBD30 (or the middle one)?
What else might you do with the list in your program? Sort it? Invert it? If so, how do you do it?


Dreamora(Posted 2006) [#5]
Potential reason that remove does not work: you overwrote the compare method and it does never return 0. In that case, the "is equal" case never happens and thus never is anything removed.


deps(Posted 2006) [#6]
I read a tip somewhere to always add things at the front of the list. That would explain why the entity to be removed is at the bottom.

When the game starts it adds three things to the list:
1) A tree (The one that I have problem removing)
2) A house
3) A woodcutter
In that order.

Since I add things at the front, the tree will end up at the bottom.

Now, in my little game, the woodcutter, powered by one of those fancy AI Goal-Driven-AGent-Behaviour thingys, walks up to the tree and starts to swing the axe on it. At the 5th strike, the tree gets a message that it should remove itself. It calls the Remove() method it inherited fron the base Entity type.
But it refuses to work. :P

Now, while writing this, I got an idea. What happens if I try to remove all entities upon exit? I wasn't doing that until now.
Here is the output:
Before remove: List contains 3 entities
 - List claims to not contain the entity...
 -- Requesting a remove: 00CF1E00
 -- In list:
 --- 00CF1E00 <-
 --- 00CEBCD0
 --- 00CF15E0
After remove: List contains 3 entities
Before remove: List contains 3 entities
 - List claims to not contain the entity...
 -- Requesting a remove: 00CEBCD0
 -- In list:
 --- 00CF1E00
 --- 00CEBCD0 <-
 --- 00CF15E0
After remove: List contains 3 entities
Before remove: List contains 3 entities
 - List claims to not contain the entity...
 -- Requesting a remove: 00CF15E0
 -- In list:
 --- 00CF1E00
 --- 00CEBCD0
 --- 00CF15E0 <-
After remove: List contains 3 entities

Nothing is removed. :P

Here is the code I'm calling when the game quits:
For Local e:Entity = EachIn Entity.ent_list
	e.Remove()
Next


So, even outside the main loop, things is acting strange.

I'm not sorting the list, or inverting it. It just contains the entities used in the game. All i do with it is to go through it and drawing/updating when needed.


deps(Posted 2006) [#7]
Dreamora, I might consider having your babies in a distant future.

Case closed. Thanks a lot for the help! :D


Edit: I'm not currently sorting the list. the overwritten compare method was a left over. Thanks a lot to both of you for taking the time to help me solve this!