[SOLVED] Garbage collection problem

Hi Panda Forum! :slight_smile:

I’ve been doing some test with the garbage collection thing, trying to remove a class, and the thing is, I can’t delete the class. :frowning:

Here’s my code (based on the “panda hello world” from the manual):

from math import pi, sin, cos
 
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import Sequence
from panda3d.core import Point3

import gc
import sys


class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.baseNode = render.attachNewNode('baseNode')


        # Disable the camera trackball controls.
        self.disableMouse()
 
        # Load the environment model.
        self.environ = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        self.environ.reparentTo(self.baseNode)
        # Apply scale and position transforms on the model.
        self.environ.setScale(0.25, 0.25, 0.25)
        self.environ.setPos(-8, 42, 0)
 


        # Add the spinCameraTask procedure to the task manager.
        self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")



        # Load and transform the panda actor.
        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.005, 0.005, 0.005)
        self.pandaActor.reparentTo(self.baseNode)

	self.pandaControl = self.pandaActor.getAnimControl("walk")

        # Loop its animation.
        self.pandaActor.loop("walk")
	self.pandaActor.setPos(0, 0, 0)
	
 
        # Create the four lerp intervals needed for the panda to
        # walk back and forth.
        pandaPosInterval1 = self.pandaActor.posInterval(13,
                                                        Point3(0, -10, 0),
                                                        startPos=Point3(0, 10, 0))
        pandaPosInterval2 = self.pandaActor.posInterval(13,
                                                        Point3(0, 10, 0),
                                                        startPos=Point3(0, -10, 0))
        pandaHprInterval1 = self.pandaActor.hprInterval(3,
                                                        Point3(180, 0, 0),
                                                        startHpr=Point3(0, 0, 0))
        pandaHprInterval2 = self.pandaActor.hprInterval(3,
                                                        Point3(0, 0, 0),
                                                        startHpr=Point3(180, 0, 0))
 
        # Create and play the sequence that coordinates the intervals.
        self.pandaPace = Sequence(pandaPosInterval1,
                                  pandaHprInterval1,
                                  pandaPosInterval2,
                                  pandaHprInterval2,
                                  name="pandaPace")
        self.pandaPace.loop()

    def __del__(self):
        print "deleted"


    # Define a procedure to move the camera.
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        self.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont



class main(ShowBase):

    def __init__(self):

        self.app = MyApp()

        self.accept("escape", sys.exit)
        self.accept("q", self.delete)


    def delete(self):

        self.app.taskMgr.remove('spinCameraTask')
        print self.app.taskMgr.remove('spinCameraTask')

        self.app.pandaPace = None
        self.app.pandaPosInterval1 = None
        self.app.pandaPosInterval2 = None
        self.app.pandaHprInterval1 = None
        self.app.pandaHprInterval2 = None

        self.app.pandaActor.delete()
        self.app.pandaActor.removeNode()
        self.app.environ.removeNode()
        self.app.baseNode.removeNode()
        self.app.ignoreAll()
        del self.app

        gc.collect()
        print gc.garbage
        

main = main()
run()

Based on the manual, I should have a “delete” output in the terminal, but instead, the output is simply:

0
[]

Meaning that there’s no garbage and (possibly the problem here), the task “spinCameraTask” is not removed.

What is wrong with my code?? :question: :question: :question:

Thanks in advance!! :slight_smile: :slight_smile:

Don’t you have to call cleanup on Actors first? I thought I read that in the Manaul…

panda3d.org/reference/1.7.2/ … c75e376a0d

Thanks for the reply!! :slight_smile:

According to the manual, the method to delete actors is delete(): Removing Custom Class Instances

Anyway, I’ve tried adding cleanup() on actors but this doesn’t work. :frowning: :frowning:

You should stop/pause the pace interval.

Hi ynjh_jo! :slight_smile: :slight_smile:

I’ve tried that, but even if I remove the whole interval/sequence thing from the program, I still can’t delete the class.

I think that the problem is with the task, but I can’t figure out what I’m doing wrong. :frowning: :frowning:

Of course there are active tasks keep running, because your MyApp instance is a Showbase instance, which has some tasks running in a loop every frame : input, collision, rendering, etc.
So far, you haven’t stopped any of them.

Are you sure it’s what you really want, stopping panda3d altogether ?
Why don’t you make your Main to be the Showbase instance instead ?

Ohhhhhhhhhhhhhhh, of course :blush: :blush:

so I’ll make my main class the showbase instance. But, MyApp class shouldn’t inherit from Showbase?? I’m a little confused with this, but I’ll try this approach.

Thanks for the replies!! :smiley: :smiley:


EDIT:

I’ve make my main class the ShowBase instance; here’s my code so far:

from math import pi, sin, cos
 
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import Sequence
from panda3d.core import Point3

import gc
import sys


class MyApp():
    def __init__(self):

        self.baseNode = render.attachNewNode('baseNode')

 
        # Load the environment model.
        self.environ = loader.loadModel("models/environment")
        # Reparent the model to render.
        self.environ.reparentTo(self.baseNode)
        # Apply scale and position transforms on the model.
        self.environ.setScale(0.25, 0.25, 0.25)
        self.environ.setPos(-8, 42, 0)
 


        # Add the spinCameraTask procedure to the task manager.
        taskMgr.add(self.spinCameraTask, "SpinCameraTask")



        # Load and transform the panda actor.
        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.005, 0.005, 0.005)
        self.pandaActor.reparentTo(self.baseNode)

	self.pandaControl = self.pandaActor.getAnimControl("walk")

        # Loop its animation.
        self.pandaActor.loop("walk")
	self.pandaActor.setPos(0, 0, 0)
	

    def __del__(self):
        print "deleted"

    
    # Define a procedure to move the camera.
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3)
        camera.setHpr(angleDegrees, 0, 0)
        return Task.cont
    


class main(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        # Disable the camera trackball controls.
        self.disableMouse()

        self.app = MyApp()

        self.accept("escape", sys.exit)
        self.accept("q", self.delete)


    def delete(self):

        self.taskMgr.remove('spinCameraTask')
        print self.taskMgr.remove('spinCameraTask')

        self.app.pandaActor.delete()
        self.app.pandaActor.cleanup()
        self.app.pandaActor.removeNode()
        self.app.environ.removeNode()
        self.app.baseNode.removeNode()
        #self.app.ignoreAll()
        del self.app

        gc.collect()
        print gc.garbage
        

main = main()
run()

But still, I can’t get “deleted” in the terminal after running the delete function, so there’s something more. :frowning: :frowning:

Sorry for being so annoying :blush: :blush: .

SUCCESS!!!

after some testing, I’ve found that in the line:

        self.taskMgr.remove('SpinCameraTask')

the ‘task name’ must be the name you put in the

        taskMgr.add(self.spinCameraTask, "SpinCameraTask")

That’s all, I think.

Anyway, if I wouldn’t changed the “instance od the ShowBase” thing, I wouldn’t find the answer. :slight_smile:

Thanks for your help! :smiley: :smiley:
Wish this could be useful to somebody besides me. :smiley: