I’m trying to build an object-based graphics development environment using Panda3D. A critical aspect of this is running code in a thread, while the main loop continues updating frames. However I have struck a snag doing this. I can get a test program working with the standard Python threading module, but according to the Panda3D documentation this will lead to highly unstable code. If I use the Panda3D threading module then the thread runs but the main thread stops rendering frames. This behaviour is the same whether I use my own threads, or use an Async Task Chain. Examples below.
My question is, is it safe for me to continue using the standard Python threading module? If not, is there any way to get Panda3D threads to run while frames continue to be rendered?
Here is the sample code for threading (Panda3D SDK 1.6.2):
from direct.directbase import DirectStart from direct.showbase.DirectObject import DirectObject from direct.interval.IntervalGlobal import * from direct.actor.Actor import Actor from pandac.PandaModules import Point3 #from direct.stdpy import threading import threading class myThread(threading.Thread): def run(self): print 'thread starting.' mydata = threading.local() mydata.i =panda.hprInterval(1, Point3(panda.getH(),panda.getP(),panda.getR()+360)) mydata.i.start() # With a simple "import threading" this code runs in a separate thread and the main loop keeps on # running, hence the interval plays until it stops. But with "from direct.stdpy import threading" # this code stops the interval from playing and the program freezes. while mydata.i.isPlaying(): pass print 'thread ending.' base.disableMouse() base.camera.setPos(0,-1000,0) base.camera.lookAt(0,0,0) panda = Actor("models/panda-model") panda.setScale(0.1, 0.1, 0.1) panda.setPos(0,0,0) panda.reparentTo(render) t = myThread() t.start() run()
here is the sample code for Async Tasks (Panda3D SDK 1.6.2):
from direct.directbase import DirectStart from direct.showbase.DirectObject import DirectObject from direct.interval.IntervalGlobal import * from direct.actor.Actor import Actor from pandac.PandaModules import Point3 def exampleTask(task): # I expect that since this task is running in a separate thread from the main loop it should # allow the interval to play, but it doesn't - it blocks the main loop, the interval stops playing, # and the program freezes. while i.isPlaying(): pass print 'threaded task ending.' return task.done base.disableMouse() base.camera.setPos(0,-1000,0) base.camera.lookAt(0,0,0) panda1 = Actor("models/panda-model") panda1.setScale(0.1, 0.1, 0.1) panda1.setPos(0,0,0) panda1.reparentTo(render) i = panda1.hprInterval(4, Point3(panda1.getH(),panda1.getP(),panda1.getR()+360)) i.start() taskMgr.setupTaskChain('threadedChain1', numThreads = 1) taskMgr.doMethodLater(2, exampleTask, 'someTaskName', taskChain = 'threadedChain1') print taskMgr run()
Any help appreciated.