Most of this code is just copied from the wxreactor that is included with the twisted networking module.
This works for me on linux and mac os 10.4.10
The only issue i am having is getting reactor.stop() to call when the main window is destroyed. I’ve seen a few topics on this but assigning base.exitfunc or base.exitFunc doesn’t appear to be working. Comments, advice, etc would be most appreciated.
"""
This module provides panda3d event loop support for Twisted.
In order to use this support, simply do the following::
| import pandaReactor
| pandaReactor.install()
Then, when your root pandaApp has been created::
| from twisted.internet import reactor
| reactor.registerPandaApp(Your DirectObject.DirectObject instance)
| reactor.run()
Finally when you want to exit the application::
| reactor.stop()
"""
import Queue as sysQueue
from twisted.python import log, runtime
from twisted.internet import _threadedselect
import direct.directbase.DirectStart
from direct.showbase.PythonUtil import *
from direct.task.Task import Task
import sys
class pandaReactor(_threadedselect.ThreadedSelectReactor):
_stopping = False
def registerPandaApp(self, pandaApp):
self.pandaApp = pandaApp
def _installSignalHandlersAgain(self):
try:
import signal
signal.signal(signal.SIGINT, signal.default_int_handler)
except ImportError:
return
self._handleSignals()
def stop(self):
if self._stopping :
return
self._stopping = True
_threadedselect.ThreadedSelectReactor.stop(self)
def _runInMainThread(self, f):
if hasattr(self, "pandaApp") and self.pandaApp != None:
self.f = f
taskMgr.add(self.taskWrapper, 'taskWrapper', -52)
else:
self._postQueue.put(f)
def taskWrapper(self, task):
self.f()
return None
def _stopPanda(self):
if hasattr(self, "pandaApp"):
self.pandaApp.stopGame()
def run(self, installSignalHandlers=True):
self._postQueue = sysQueue.Queue()
if not hasattr(self, "pandaApp"):
log.msg("registerPandaApp() was not called on reactor.. bye. ")
return
self.interleave(self._runInMainThread, installSignalHandlers=installSignalHandlers)
if installSignalHandlers:
self.callLater(0, self._installSignalHandlersAgain)
self.addSystemEventTrigger("after", "shutdown", self._stopPanda)
self.addSystemEventTrigger("after", "shutdown",
lambda: self._postQueue.put(None))
run()
pandaApp = self.pandaApp
del self.pandaApp
if not self._stopping:
self.stop()
while 1:
try:
f = self._postQueue.get(timeout=0.01)
except Queue.Empty:
continue
else:
if f is None:
break
try:
f()
except:
log.err()
def install():
reactor = pandaReactor()
from twisted.internet.main import installReactor
installReactor(reactor)
return reactor
__all__ = ['install']