hello again!
Today (tonight here) I am fighting with this problem. I can’t empty a list of objects.
For a simpler understanding
class Army; which contains the unitList which is the list of all unit/structures on scen. Contains function delete all units which i posted above. Unit is my personal class and it’s similar to this.
class Unit(DirectObject.DirectObject):
def __init__(self, model, x=0, y=0, z=0):
self.node = loader.loadModel("models/" + model + ".egg")
self.node.setPos(x,y,z)
self.node.reparentTo(render)
#function that i use to remove all my RTS's units from the main units list.
def removeAll(self):
#create a copy of my unitList (member of my class) in order to prevent main list to be broken - am I right?
tmpList = self.unitList
# than loop over all the tmpList (which is equal to unitList)
for unit in tmpList:
#remove the object (unit is type of my Unit class containing a member called node which is nodepath)
unit.node.remove()
#the i try to remove all the units because this actually doesn't work... it leave one object on the scene.
#confirmed by render.ls() too
self.unitList.remove(unit)
#delete temporary list
del tmpList
#end of function
it’s well documented explaining my stupidity i think it’s more a python problem than panda.
Anyway, thank you a lot in advance!
And if you have any suggestion I’d really appreciate since I’ve just written code for 2 weeks with panda and I’m still a big newbie here
This is useless because self.initList is the actual list, when you say newVar = self.initList It’s just assigning a pointer to that list… You can look up pointers for more information on this subject.
Instead you can just loop over the real list, and as long as you never remove an item from that list (list.remove(item)) then you are never tampering with the list, just scanning the items in it.
unit.node.remove()
This should work fine, assuming that unit.node is a nodePath… are you sure it is? perhaps if this is just a model loaded via loader.loadModel or something similar, try:
self.unitList.remove(unit)
I’m unable to understand why you would want to remove the item from the original list, perhaps I’ve misunderstood due to lack of knowledge on your code (perhaps this is a list of classes holding units?)
In any case, the following should work:
def removeAll(self):
for unit in self.initList:
unit.node.remove()
#self.unitList.remove(unit) # Why?
#del tmpList #No need for this anymore
If you want to loop over a list while removing items here are a few ways to do it.
Make a copy of the list:
for item in list[:]:
do_something(item)
list.remove(item)
Go in reverse order:
for i in reversed(range(0, len(list))):
item = list[i]
do_something(item)
list.remove(item)
Use while loop instead of for:
while list:
item = list.pop(0)
do_something(item)
As for why you have one item left over, it could be because of the loop, or maybe your class has some code outside of a function that is executing when the class is defined. Do you mean one item left in your list or one 3d model not removed from the scene?