mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
Deprecate DirectStart and run(), allow clean ShowBase teardown, docstrings for ShowBase members
This commit is contained in:
parent
78c3593d2c
commit
753b1c623d
@ -1,4 +1,5 @@
|
||||
print 'DirectStart: Starting the game.'
|
||||
__all__ = []
|
||||
print('Using deprecated DirectStart interface.')
|
||||
|
||||
from direct.showbase import ShowBase
|
||||
base = ShowBase.ShowBase()
|
||||
|
@ -1,5 +1,7 @@
|
||||
"""instantiate global DirectNotify used in Direct"""
|
||||
|
||||
__all__ = ['directNotify', 'giveNotify']
|
||||
|
||||
import DirectNotify
|
||||
|
||||
directNotify = DirectNotify.DirectNotify()
|
||||
|
@ -187,3 +187,8 @@ class EventManager:
|
||||
|
||||
def shutdown(self):
|
||||
taskMgr.remove('eventManager')
|
||||
|
||||
# Flush the event queue. We do this after removing the task
|
||||
# since the task removal itself might also fire off an event.
|
||||
if self.eventQueue is not None:
|
||||
self.eventQueue.clear()
|
||||
|
@ -14,12 +14,12 @@ from panda3d.direct import get_config_showbase, throw_new_frame, init_app_for_gu
|
||||
import __builtin__
|
||||
__builtin__.config = get_config_showbase()
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import *
|
||||
from MessengerGlobal import *
|
||||
from BulletinBoardGlobal import *
|
||||
from direct.task.TaskManagerGlobal import *
|
||||
from JobManagerGlobal import *
|
||||
from EventManagerGlobal import *
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
|
||||
from MessengerGlobal import messenger
|
||||
from BulletinBoardGlobal import bulletinBoard
|
||||
from direct.task.TaskManagerGlobal import taskMgr
|
||||
from JobManagerGlobal import jobMgr
|
||||
from EventManagerGlobal import eventMgr
|
||||
from PythonUtil import *
|
||||
from direct.showbase import PythonUtil
|
||||
#from direct.interval.IntervalManager import ivalMgr
|
||||
@ -29,11 +29,11 @@ from direct.showbase.BufferViewer import BufferViewer
|
||||
from direct.task import Task
|
||||
from direct.directutil import Verify
|
||||
from direct.showbase import GarbageReport
|
||||
import EventManager
|
||||
import math,sys,os
|
||||
import Loader
|
||||
import time
|
||||
import gc
|
||||
import atexit
|
||||
from direct.fsm import ClassicFSM
|
||||
from direct.fsm import State
|
||||
from direct.showbase import ExceptionVarDump
|
||||
@ -47,6 +47,14 @@ import AppRunnerGlobal
|
||||
__builtin__.FADE_SORT_INDEX = 1000
|
||||
__builtin__.NO_FADE_SORT_INDEX = 2000
|
||||
|
||||
def legacyRun():
|
||||
__builtin__.base.notify.warning("run() is deprecated, use base.run() instead")
|
||||
__builtin__.base.run()
|
||||
|
||||
@atexit.register
|
||||
def exitfunc():
|
||||
if getattr(__builtin__, 'base', None) is not None:
|
||||
__builtin__.base.destroy()
|
||||
|
||||
# Now ShowBase is a DirectObject. We need this so ShowBase can hang
|
||||
# hooks on messages, particularly on window-event. This doesn't
|
||||
@ -65,11 +73,12 @@ class ShowBase(DirectObject.DirectObject):
|
||||
if logStackDump or uploadStackDump:
|
||||
ExceptionVarDump.install(logStackDump, uploadStackDump)
|
||||
|
||||
# Locate the directory containing the main program
|
||||
## The directory containing the main Python file of this application.
|
||||
self.mainDir = ExecutionEnvironment.getEnvironmentVariable("MAIN_DIR")
|
||||
|
||||
# The appRunner should have been created by the time ShowBase
|
||||
# has been.
|
||||
## This contains the global appRunner instance, as imported from
|
||||
## AppRunnerGlobal. This will be None if we are not running in the
|
||||
## runtime environment (ie. from a .p3d file).
|
||||
self.appRunner = AppRunnerGlobal.appRunner
|
||||
|
||||
#debug running multiplier
|
||||
@ -108,13 +117,13 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.wantTk = False
|
||||
self.wantWx = False
|
||||
|
||||
# Fill this in with a function to invoke when the user "exits"
|
||||
# the program by closing the main window.
|
||||
## Fill this in with a function to invoke when the user "exits"
|
||||
## the program by closing the main window.
|
||||
self.exitFunc = None
|
||||
|
||||
# Add final-exit callbacks to this list. These will be called
|
||||
# when sys.exit() is called, after Panda has unloaded, and
|
||||
# just before Python is about to shut down.
|
||||
## Add final-exit callbacks to this list. These will be called
|
||||
## when sys.exit() is called, after Panda has unloaded, and
|
||||
## just before Python is about to shut down.
|
||||
self.finalExitCallbacks = []
|
||||
|
||||
Task.TaskManager.taskTimerVerbose = self.config.GetBool('task-timer-verbose', 0)
|
||||
@ -139,13 +148,15 @@ class ShowBase(DirectObject.DirectObject):
|
||||
# we get a window-event.
|
||||
self.__oldAspectRatio = None
|
||||
|
||||
## This is set to the value of the window-type config variable, but may
|
||||
## optionally be overridden in the Showbase constructor. Should either be
|
||||
## 'onscreen' (the default), 'offscreen' or 'none'.
|
||||
self.windowType = windowType
|
||||
if self.windowType is None:
|
||||
self.windowType = self.config.GetString('window-type', 'onscreen')
|
||||
self.requireWindow = self.config.GetBool('require-window', 1)
|
||||
|
||||
# base.win is the main, or only window; base.winList is a list of
|
||||
# *all* windows. Similarly with base.camList.
|
||||
## This is the main, or only window; see winList for a list of *all* windows.
|
||||
self.win = None
|
||||
self.frameRateMeter = None
|
||||
self.sceneGraphAnalyzerMeter = None
|
||||
@ -165,17 +176,29 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.trackball = None
|
||||
self.texmem = None
|
||||
self.showVertices = None
|
||||
|
||||
## This is a NodePath pointing to the Camera object set up for the 3D scene.
|
||||
## This is usually a child of self.camera.
|
||||
self.cam = None
|
||||
self.cam2d = None
|
||||
self.cam2dp = None
|
||||
|
||||
## This is the NodePath that should be used to manipulate the camera. This
|
||||
## is the node to which the default camera is attached.
|
||||
self.camera = None
|
||||
self.camera2d = None
|
||||
self.camera2dp = None
|
||||
|
||||
## This is a list of all cameras created with makeCamera, including base.cam.
|
||||
self.camList = []
|
||||
## Convenience accessor for base.cam.node()
|
||||
self.camNode = None
|
||||
## Convenience accessor for base.camNode.get_lens()
|
||||
self.camLens = None
|
||||
self.camFrustumVis = None
|
||||
self.direct = None
|
||||
## This is used to store the wx.Application object used when want-wx is
|
||||
## set or base.startWx() is called.
|
||||
self.wxApp = None
|
||||
self.tkRoot = None
|
||||
|
||||
@ -189,6 +212,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
|
||||
self.hidden = NodePath('hidden')
|
||||
|
||||
## The global graphics engine, ie. GraphicsEngine.getGlobalPtr()
|
||||
self.graphicsEngine = GraphicsEngine.getGlobalPtr()
|
||||
self.setupRender()
|
||||
self.setupRender2d()
|
||||
@ -198,11 +222,11 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.setupRender2dp()
|
||||
|
||||
|
||||
# This is a placeholder for a CollisionTraverser. If someone
|
||||
# stores a CollisionTraverser pointer here, we'll traverse it
|
||||
# in the collisionLoop task.
|
||||
self.shadowTrav = 0
|
||||
## This is a placeholder for a CollisionTraverser. If someone
|
||||
## stores a CollisionTraverser pointer here, we'll traverse it
|
||||
## in the collisionLoop task.
|
||||
self.cTrav = 0
|
||||
self.shadowTrav = 0
|
||||
self.cTravStack = Stack()
|
||||
# Ditto for an AppTraverser.
|
||||
self.appTrav = 0
|
||||
@ -233,10 +257,6 @@ class ShowBase(DirectObject.DirectObject):
|
||||
random.seed(seed)
|
||||
#whrandom.seed(seed & 0xff, (seed >> 8) & 0xff, (seed >> 16) & 0xff)
|
||||
|
||||
# Now that we've set up the window structures, assign an exitfunc.
|
||||
self.oldexitfunc = getattr(sys, 'exitfunc', None)
|
||||
sys.exitfunc = self.exitfunc
|
||||
|
||||
# Open the default rendering window.
|
||||
if self.windowType != 'none':
|
||||
props = WindowProperties.getDefault()
|
||||
@ -254,17 +274,22 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.loader = Loader.Loader(self)
|
||||
self.graphicsEngine.setDefaultLoader(self.loader.loader)
|
||||
|
||||
## The global event manager, as imported from EventManagerGlobal.
|
||||
self.eventMgr = eventMgr
|
||||
## The global messenger, as imported from MessengerGlobal.
|
||||
self.messenger = messenger
|
||||
## The global bulletin board, as imported from BulletinBoardGlobal.
|
||||
self.bboard = bulletinBoard
|
||||
## The global task manager, as imported from TaskManagerGlobal.
|
||||
self.taskMgr = taskMgr
|
||||
## The global job manager, as imported from JobManagerGlobal.
|
||||
self.jobMgr = jobMgr
|
||||
|
||||
# Particle manager
|
||||
## Particle manager
|
||||
self.particleMgr = None
|
||||
self.particleMgrEnabled = 0
|
||||
|
||||
# Physics manager
|
||||
## Physics manager
|
||||
self.physicsMgr = None
|
||||
self.physicsMgrEnabled = 0
|
||||
self.physicsMgrAngular = 0
|
||||
@ -316,6 +341,8 @@ class ShowBase(DirectObject.DirectObject):
|
||||
if 'base' in __builtin__.__dict__:
|
||||
raise StandardError, "Attempt to spawn multiple ShowBase instances!"
|
||||
|
||||
# DO NOT ADD TO THIS LIST. We're trying to phase out the use of
|
||||
# built-in variables by ShowBase. Use a Global module if necessary.
|
||||
__builtin__.base = self
|
||||
__builtin__.render2d = self.render2d
|
||||
__builtin__.aspect2d = self.aspect2d
|
||||
@ -331,7 +358,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
__builtin__.bboard = self.bboard
|
||||
# Config needs to be defined before ShowBase is constructed
|
||||
#__builtin__.config = self.config
|
||||
__builtin__.run = self.run
|
||||
__builtin__.run = legacyRun
|
||||
__builtin__.ostream = Notify.out()
|
||||
__builtin__.directNotify = directNotify
|
||||
__builtin__.giveNotify = giveNotify
|
||||
@ -426,7 +453,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.cTrav = self.cTravStack.pop()
|
||||
|
||||
def __setupProfile(self):
|
||||
""" Sets up the Python profiler, if avaialable, according to
|
||||
""" Sets up the Python profiler, if available, according to
|
||||
some Panda config settings. """
|
||||
|
||||
try:
|
||||
@ -445,8 +472,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
return 0
|
||||
|
||||
def printEnvDebugInfo(self):
|
||||
"""
|
||||
Print some information about the environment that we are running
|
||||
"""Print some information about the environment that we are running
|
||||
in. Stuff like the model paths and other paths. Feel free to
|
||||
add stuff to this.
|
||||
"""
|
||||
@ -470,11 +496,18 @@ class ShowBase(DirectObject.DirectObject):
|
||||
for cb in self.finalExitCallbacks[:]:
|
||||
cb()
|
||||
|
||||
# Remove the built-in base reference
|
||||
if getattr(__builtin__, 'base', None) is self:
|
||||
del __builtin__.base
|
||||
del __builtin__.loader
|
||||
del __builtin__.taskMgr
|
||||
|
||||
# [gjeon] restore sticky key settings
|
||||
if self.config.GetBool('disable-sticky-keys', 0):
|
||||
allowAccessibilityShortcutKeys(True)
|
||||
|
||||
taskMgr.destroy()
|
||||
self.ignoreAll()
|
||||
self.shutdown()
|
||||
|
||||
if getattr(self, 'musicManager', None):
|
||||
self.musicManager.shutdown()
|
||||
@ -501,19 +534,6 @@ class ShowBase(DirectObject.DirectObject):
|
||||
vfs = VirtualFileSystem.getGlobalPtr()
|
||||
vfs.unmountAll()
|
||||
|
||||
|
||||
def exitfunc(self):
|
||||
"""
|
||||
This should be assigned to sys.exitfunc to be called just
|
||||
before Python shutdown. It guarantees that the Panda window
|
||||
is closed cleanly, so that we free system resources, restore
|
||||
the desktop and keyboard functionality, etc.
|
||||
"""
|
||||
self.destroy()
|
||||
|
||||
if self.oldexitfunc:
|
||||
self.oldexitfunc()
|
||||
|
||||
def makeDefaultPipe(self, printPipeTypes = True):
|
||||
"""
|
||||
Creates the default GraphicsPipe, which will be used to make
|
||||
@ -1022,6 +1042,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
Creates the render scene graph, the primary scene graph for
|
||||
rendering 3-d geometry.
|
||||
"""
|
||||
## This is the root of the 3-D scene graph.
|
||||
self.render = NodePath('render')
|
||||
self.render.setAttrib(RescaleNormalAttrib.makeDefault())
|
||||
|
||||
@ -1037,6 +1058,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
2-d objects and gui elements that are superimposed over the
|
||||
3-d geometry in the window.
|
||||
"""
|
||||
## This is the root of the 2-D scene graph.
|
||||
self.render2d = NodePath('render2d')
|
||||
|
||||
# Set up some overrides to turn off certain properties which
|
||||
@ -1057,22 +1079,26 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.render2d.setMaterialOff(1)
|
||||
self.render2d.setTwoSided(1)
|
||||
|
||||
# The normal 2-d DisplayRegion has an aspect ratio that
|
||||
# matches the window, but its coordinate system is square.
|
||||
# This means anything we parent to render2d gets stretched.
|
||||
# For things where that makes a difference, we set up
|
||||
# aspect2d, which scales things back to the right aspect
|
||||
# ratio.
|
||||
aspectRatio = self.getAspectRatio()
|
||||
## The normal 2-d DisplayRegion has an aspect ratio that
|
||||
## matches the window, but its coordinate system is square.
|
||||
## This means anything we parent to render2d gets stretched.
|
||||
## For things where that makes a difference, we set up
|
||||
## aspect2d, which scales things back to the right aspect
|
||||
## ratio along the X axis (Z is still from -1 to 1)
|
||||
self.aspect2d = self.render2d.attachNewNode(PGTop("aspect2d"))
|
||||
|
||||
aspectRatio = self.getAspectRatio()
|
||||
self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0)
|
||||
|
||||
self.a2dBackground = self.aspect2d.attachNewNode("a2dBackground")
|
||||
|
||||
# It's important to know the bounds of the aspect2d screen.
|
||||
## The Z position of the top border of the aspect2d screen.
|
||||
self.a2dTop = 1.0
|
||||
## The Z position of the bottom border of the aspect2d screen.
|
||||
self.a2dBottom = -1.0
|
||||
## The X position of the left border of the aspect2d screen.
|
||||
self.a2dLeft = -aspectRatio
|
||||
## The X position of the right border of the aspect2d screen.
|
||||
self.a2dRight = aspectRatio
|
||||
|
||||
self.a2dTopCenter = self.aspect2d.attachNewNode("a2dTopCenter")
|
||||
@ -1112,12 +1138,12 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.a2dBottomRight.setPos(self.a2dRight, 0, self.a2dBottom)
|
||||
self.a2dBottomRightNs.setPos(self.a2dRight, 0, self.a2dBottom)
|
||||
|
||||
# This special root, pixel2d, uses units in pixels that are relative
|
||||
# to the window. The upperleft corner of the window is (0, 0),
|
||||
# the lowerleft corner is (xsize, -ysize), in this coordinate system.
|
||||
xsize, ysize = self.getSize()
|
||||
## This special root, pixel2d, uses units in pixels that are relative
|
||||
## to the window. The upperleft corner of the window is (0, 0),
|
||||
## the lowerleft corner is (xsize, -ysize), in this coordinate system.
|
||||
self.pixel2d = self.render2d.attachNewNode(PGTop("pixel2d"))
|
||||
self.pixel2d.setPos(-1, 0, 1)
|
||||
xsize, ysize = self.getSize()
|
||||
if xsize > 0 and ysize > 0:
|
||||
self.pixel2d.setScale(2.0 / xsize, 1.0, 2.0 / ysize)
|
||||
|
||||
@ -1144,25 +1170,27 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.render2dp.setMaterialOff(1)
|
||||
self.render2dp.setTwoSided(1)
|
||||
|
||||
# The normal 2-d DisplayRegion has an aspect ratio that
|
||||
# matches the window, but its coordinate system is square.
|
||||
# This means anything we parent to render2d gets stretched.
|
||||
# For things where that makes a difference, we set up
|
||||
# aspect2d, which scales things back to the right aspect
|
||||
# ratio.
|
||||
|
||||
aspectRatio = self.getAspectRatio()
|
||||
## The normal 2-d DisplayRegion has an aspect ratio that
|
||||
## matches the window, but its coordinate system is square.
|
||||
## This means anything we parent to render2dp gets stretched.
|
||||
## For things where that makes a difference, we set up
|
||||
## aspect2dp, which scales things back to the right aspect
|
||||
## ratio along the X axis (Z is still from -1 to 1)
|
||||
self.aspect2dp = self.render2dp.attachNewNode(PGTop("aspect2dp"))
|
||||
self.aspect2dp.node().setStartSort(16384)
|
||||
|
||||
aspectRatio = self.getAspectRatio()
|
||||
self.aspect2dp.setScale(1.0 / aspectRatio, 1.0, 1.0)
|
||||
|
||||
# It's important to know the bounds of the aspect2d screen.
|
||||
## The Z position of the top border of the aspect2dp screen.
|
||||
self.a2dpTop = 1.0
|
||||
## The Z position of the bottom border of the aspect2dp screen.
|
||||
self.a2dpBottom = -1.0
|
||||
## The X position of the left border of the aspect2dp screen.
|
||||
self.a2dpLeft = -aspectRatio
|
||||
## The X position of the right border of the aspect2dp screen.
|
||||
self.a2dpRight = aspectRatio
|
||||
|
||||
|
||||
self.a2dpTopCenter = self.aspect2dp.attachNewNode("a2dpTopCenter")
|
||||
self.a2dpBottomCenter = self.aspect2dp.attachNewNode("a2dpBottomCenter")
|
||||
self.a2dpLeftCenter = self.aspect2dp.attachNewNode("a2dpLeftCenter")
|
||||
@ -1184,13 +1212,13 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.a2dpBottomLeft.setPos(self.a2dpLeft, 0, self.a2dpBottom)
|
||||
self.a2dpBottomRight.setPos(self.a2dpRight, 0, self.a2dpBottom)
|
||||
|
||||
# This special root, pixel2d, uses units in pixels that are relative
|
||||
# to the window. The upperleft corner of the window is (0, 0),
|
||||
# the lowerleft corner is (xsize, -ysize), in this coordinate system.
|
||||
xsize, ysize = self.getSize()
|
||||
## This special root, pixel2d, uses units in pixels that are relative
|
||||
## to the window. The upperleft corner of the window is (0, 0),
|
||||
## the lowerleft corner is (xsize, -ysize), in this coordinate system.
|
||||
self.pixel2dp = self.render2dp.attachNewNode(PGTop("pixel2dp"))
|
||||
self.pixel2dp.node().setStartSort(16384)
|
||||
self.pixel2dp.setPos(-1, 0, 1)
|
||||
xsize, ysize = self.getSize()
|
||||
if xsize > 0 and ysize > 0:
|
||||
self.pixel2dp.setScale(2.0 / xsize, 1.0, 2.0 / ysize)
|
||||
|
||||
@ -1502,12 +1530,14 @@ class ShowBase(DirectObject.DirectObject):
|
||||
np = mw.getParent().attachNewNode(mouseRecorder)
|
||||
mw.reparentTo(np)
|
||||
|
||||
# A special ButtonThrower to generate keyboard events and
|
||||
# include the time from the OS. This is separate only to
|
||||
# support legacy code that did not expect a time parameter; it
|
||||
# will eventually be folded into the normal ButtonThrower,
|
||||
# above.
|
||||
|
||||
mw = self.buttonThrowers[0].getParent()
|
||||
|
||||
## A special ButtonThrower to generate keyboard events and
|
||||
## include the time from the OS. This is separate only to
|
||||
## support legacy code that did not expect a time parameter; it
|
||||
## will eventually be folded into the normal ButtonThrower,
|
||||
## above.
|
||||
self.timeButtonThrower = mw.attachNewNode(ButtonThrower('timeButtons'))
|
||||
self.timeButtonThrower.node().setPrefix('time-')
|
||||
self.timeButtonThrower.node().setTimeFlag(1)
|
||||
@ -1970,7 +2000,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.taskMgr.remove('dataLoop')
|
||||
self.taskMgr.remove('resetPrevTransform')
|
||||
self.taskMgr.remove('ivalLoop')
|
||||
self.taskMgr.remove('garbage_collect')
|
||||
self.taskMgr.remove('garbageCollectStates')
|
||||
self.eventMgr.shutdown()
|
||||
|
||||
def getBackgroundColor(self, win = None):
|
||||
@ -2931,11 +2961,12 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.startDirect(fWantDirect = fDirect, fWantTk = fTk, fWantWx = fWx)
|
||||
|
||||
def run(self):
|
||||
# This method runs the TaskManager when self.appRunner is
|
||||
# None, which is to say, when we are not running from within a
|
||||
# p3d file. When we *are* within a p3d file, the Panda
|
||||
# runtime has to be responsible for running the main loop, so
|
||||
# we can't allow the application to do it.
|
||||
""" This method runs the TaskManager when self.appRunner is
|
||||
None, which is to say, when we are not running from within a
|
||||
p3d file. When we *are* within a p3d file, the Panda
|
||||
runtime has to be responsible for running the main loop, so
|
||||
we can't allow the application to do it. """
|
||||
|
||||
if self.appRunner is None or self.appRunner.dummy or \
|
||||
(self.appRunner.interactiveConsole and not self.appRunner.initialAppImport):
|
||||
self.taskMgr.run()
|
||||
|
Loading…
x
Reference in New Issue
Block a user