Pickling Problem

I have put this short code together. I demonstrates one way to pickle a class instance with one NodePath attribute. ‘X’ will pickle/save, and ‘Y’ will unpickle/load.

Please notice that I didn’t store the NodePath’s position, orientation or parent. Also pickling the object deletes the NodePath instance.

I wonder if this is the best way to make Panda3D objects persistent. If anybody knows other/better way, please tell.

enn0x

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
import sys
import cPickle as pickle
import time

class Foo:

    def __init__( self ):
        self.x = 999
        self.z = 'abc'
        self.np = loader.loadModel( 'models/box' )
        self.np.reparentTo( render )
        self.np.setPos( 0, 10, 0 )

    def __getstate__( self ):
        filename = '%i.bam' % id( self.np )
        self.np.writeBamFile( filename )
        self.np.removeNode( )

        dict = self.__dict__
        del dict[ 'np' ]
        dict[ 'filename' ] = filename

        return dict

    def __setstate__( self, dict ):
        filename = dict[ 'filename' ]
        del dict[ 'filename' ]

        self.__dict__ = dict

        self.np = loader.loadModel( filename )
        self.np.reparentTo( render )
        self.np.setPos( 0, 10, 0 )

class World( DirectObject ):

    def __init__( self ):
        self.accept( 'escape', self.exit )
        self.accept( 'x', self.save )
        self.accept( 'y', self.load )

        self.foo = Foo( )

    def save( self ):
        print 'SAVE'
        pickle.dump( self.foo, file( 'foo.p', 'wb' ) )

    def load( self ):
        print 'LOAD'
        self.foo = pickle.load( file( 'foo.p', 'rb' ) )

    def exit( self ):
        sys.exit( 1 )

world = World( )
run( )